Shadow map issue

This commit is contained in:
Daniel Chappuis 2015-08-11 18:32:45 +02:00
parent a4e28ddcf1
commit ce80426a2c
20 changed files with 268 additions and 61 deletions

View File

@ -43,8 +43,6 @@ SET(TESTBED_SOURCES
src/SceneDemo.cpp src/SceneDemo.cpp
src/Timer.h src/Timer.h
src/Timer.cpp src/Timer.cpp
src/PhysicsEventListener.h
src/PhysicsEventListener.cpp
) )
# IMGUI source files # IMGUI source files

View File

@ -33,7 +33,6 @@ openglframework::VertexBufferObject VisualContactPoint::mVBOIndices(GL_ELEMENT_A
openglframework::VertexArrayObject VisualContactPoint::mVAO; openglframework::VertexArrayObject VisualContactPoint::mVAO;
int VisualContactPoint::mNbTotalPoints = 0; int VisualContactPoint::mNbTotalPoints = 0;
openglframework::Mesh VisualContactPoint::mMesh; openglframework::Mesh VisualContactPoint::mMesh;
int VisualContactPoint::totalNbBoxes = 0;
// Constructor // Constructor
VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position,
@ -42,31 +41,11 @@ VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position,
// Initialize the position where the mesh will be rendered // Initialize the position where the mesh will be rendered
translateWorld(position); translateWorld(position);
// Create the VBOs and VAO
if (totalNbBoxes == 0) {
createStaticData(meshFolderPath);
createVBOAndVAO();
}
totalNbBoxes++;
} }
// Destructor // Destructor
VisualContactPoint::~VisualContactPoint() { VisualContactPoint::~VisualContactPoint() {
if (totalNbBoxes == 1) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVAO.destroy();
destroyStaticData();
}
totalNbBoxes--;
} }
// Load and initialize the mesh for all the contact points // Load and initialize the mesh for all the contact points
@ -79,11 +58,19 @@ void VisualContactPoint::createStaticData(const std::string& meshFolderPath) {
mMesh.calculateNormals(); mMesh.calculateNormals();
mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS); mMesh.scaleVertices(VISUAL_CONTACT_POINT_RADIUS);
createVBOAndVAO();
} }
// Destroy the mesh for the contact points // Destroy the mesh for the contact points
void VisualContactPoint::destroyStaticData() { void VisualContactPoint::destroyStaticData() {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVAO.destroy();
mMesh.destroy(); mMesh.destroy();
} }

View File

@ -29,7 +29,7 @@
// Libraries // Libraries
#include "openglframework.h" #include "openglframework.h"
const float VISUAL_CONTACT_POINT_RADIUS = 0.1f; const float VISUAL_CONTACT_POINT_RADIUS = 0.2f;
// Class VisualContactPoint // Class VisualContactPoint
class VisualContactPoint : public openglframework::Object3D { class VisualContactPoint : public openglframework::Object3D {
@ -56,9 +56,6 @@ class VisualContactPoint : public openglframework::Object3D {
/// Vertex Array Object for the vertex data /// Vertex Array Object for the vertex data
static openglframework::VertexArrayObject mVAO; static openglframework::VertexArrayObject mVAO;
/// Total number of points created
static int totalNbBoxes;
/// Color /// Color
openglframework::Color mColor; openglframework::Color mColor;

View File

@ -233,7 +233,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Set the box color // Set the box color
mFloor->setColor(mGreyColorDemo); mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mRedColorDemo); mFloor->setSleepingColor(mGreyColorDemo);
// The floor must be a static rigid body // The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC); mFloor->getRigidBody()->setType(rp3d::STATIC);
@ -361,6 +361,8 @@ void CollisionShapesScene::updatePhysics() {
// Take a step for the simulation // Take a step for the simulation
void CollisionShapesScene::update() { void CollisionShapesScene::update() {
SceneDemo::update();
// Update the position and orientation of the boxes // Update the position and orientation of the boxes
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {

View File

@ -45,13 +45,13 @@ namespace collisionshapesscene {
// Constants // Constants
const float SCENE_RADIUS = 30.0f; const float SCENE_RADIUS = 30.0f;
const int NB_BOXES = 5; const int NB_BOXES = 4;
const int NB_CUBES = 4; const int NB_CUBES = 6;
const int NB_CONES = 4; const int NB_CONES = 6;
const int NB_CYLINDERS = 6; const int NB_CYLINDERS = 5;
const int NB_CAPSULES = 5; const int NB_CAPSULES = 4;
const int NB_MESHES = 7; const int NB_MESHES = 5;
const int NB_COMPOUND_SHAPES = 3; const int NB_COMPOUND_SHAPES = 4;
const openglframework::Vector3 BOX_SIZE(2, 2, 2); const openglframework::Vector3 BOX_SIZE(2, 2, 2);
const float SPHERE_RADIUS = 1.5f; const float SPHERE_RADIUS = 1.5f;
const float CONE_RADIUS = 2.0f; const float CONE_RADIUS = 2.0f;
@ -122,8 +122,16 @@ class CollisionShapesScene : public SceneDemo {
/// Reset the scene /// Reset the scene
virtual void reset(); virtual void reset();
/// Return all the contact points of the scene
virtual std::vector<ContactPoint> getContactPoints() const;
}; };
// Return all the contact points of the scene
inline std::vector<ContactPoint> CollisionShapesScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld);
}
} }
#endif #endif

View File

@ -149,6 +149,8 @@ void CubesScene::updatePhysics() {
// Update the scene // Update the scene
void CubesScene::update() { void CubesScene::update() {
SceneDemo::update();
// Update the position and orientation of the boxes // Update the position and orientation of the boxes
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
@ -198,11 +200,3 @@ void CubesScene::reset() {
mBoxes[i]->resetTransform(transform); mBoxes[i]->resetTransform(transform);
} }
} }
// Return all the contact points of the scene
std::vector<ContactPoint> CubesScene::getContactPoints() const {
std::vector<ContactPoint> contactPoints;
return contactPoints;
}

View File

@ -83,9 +83,14 @@ class CubesScene : public SceneDemo {
virtual void reset(); virtual void reset();
/// Return all the contact points of the scene /// Return all the contact points of the scene
std::vector<ContactPoint> virtual getContactPoints() const; virtual std::vector<ContactPoint> getContactPoints() const;
}; };
// Return all the contact points of the scene
inline std::vector<ContactPoint> CubesScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld);
}
} }
#endif #endif

View File

@ -145,6 +145,8 @@ void JointsScene::updatePhysics() {
// Take a step for the simulation // Take a step for the simulation
void JointsScene::update() { void JointsScene::update() {
SceneDemo::update();
// Update the position and orientation of the boxes // Update the position and orientation of the boxes
mSliderJointBottomBox->updateTransform(mInterpolationFactor); mSliderJointBottomBox->updateTransform(mInterpolationFactor);
mSliderJointTopBox->updateTransform(mInterpolationFactor); mSliderJointTopBox->updateTransform(mInterpolationFactor);
@ -474,7 +476,7 @@ void JointsScene::createFloor() {
// Set the box color // Set the box color
mFloor->setColor(mGreyColorDemo); mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mRedColorDemo); mFloor->setSleepingColor(mGreyColorDemo);
// The floor must be a static rigid body // The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC); mFloor->getRigidBody()->setType(rp3d::STATIC);

View File

@ -135,8 +135,16 @@ class JointsScene : public SceneDemo {
/// Reset the scene /// Reset the scene
virtual void reset(); virtual void reset();
/// Return all the contact points of the scene
virtual std::vector<ContactPoint> getContactPoints() const;
}; };
// Return all the contact points of the scene
inline std::vector<ContactPoint> JointsScene::getContactPoints() const {
return computeContactPointsOfWorld(mDynamicsWorld);
}
} }
#endif #endif

View File

@ -36,6 +36,8 @@ RaycastScene::RaycastScene(const std::string& name)
mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath),
mVBOVertices(GL_ARRAY_BUFFER) { mVBOVertices(GL_ARRAY_BUFFER) {
mIsContactPointsDisplayed = true;
// Compute the radius and the center of the scene // Compute the radius and the center of the scene
openglframework::Vector3 center(0, 0, 0); openglframework::Vector3 center(0, 0, 0);
@ -286,6 +288,8 @@ void RaycastScene::update() {
// callback class in argument. // callback class in argument.
mCollisionWorld->raycast(ray, &mRaycastManager); mCollisionWorld->raycast(ray, &mRaycastManager);
} }
SceneDemo::update();
} }
// Render the scene // Render the scene

View File

@ -66,7 +66,7 @@ class RaycastManager : public rp3d::RaycastCallback {
private: private:
/// All the visual contact points /// All the visual contact points
std::vector<VisualContactPoint*> mHitPoints; std::vector<ContactPoint> mHitPoints;
/// All the normals at hit points /// All the normals at hit points
std::vector<Line*> mNormals; std::vector<Line*> mNormals;
@ -88,8 +88,7 @@ class RaycastManager : public rp3d::RaycastCallback {
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) { virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) {
rp3d::Vector3 hitPos = raycastInfo.worldPoint; rp3d::Vector3 hitPos = raycastInfo.worldPoint;
openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z);
VisualContactPoint* point = new VisualContactPoint(position, mMeshFolderPath); mHitPoints.push_back(ContactPoint(position));
mHitPoints.push_back(point);
// Create a line to display the normal at hit point // Create a line to display the normal at hit point
rp3d::Vector3 n = raycastInfo.worldNormal; rp3d::Vector3 n = raycastInfo.worldNormal;
@ -103,11 +102,13 @@ class RaycastManager : public rp3d::RaycastCallback {
void render(const openglframework::Matrix4& worldToCameraMatrix, void render(const openglframework::Matrix4& worldToCameraMatrix,
bool showNormals) { bool showNormals) {
/*
// Render all the raycast hit points // Render all the raycast hit points
for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin(); for (std::vector<ContactPoint>::iterator it = mHitPoints.begin();
it != mHitPoints.end(); ++it) { it != mHitPoints.end(); ++it) {
(*it)->render(mShader, worldToCameraMatrix); (*it)->render(mShader, worldToCameraMatrix);
} }
*/
if (showNormals) { if (showNormals) {
@ -121,11 +122,13 @@ class RaycastManager : public rp3d::RaycastCallback {
void resetPoints() { void resetPoints() {
/*
// Destroy all the visual contact points // Destroy all the visual contact points
for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin(); for (std::vector<VisualContactPoint*>::iterator it = mHitPoints.begin();
it != mHitPoints.end(); ++it) { it != mHitPoints.end(); ++it) {
delete (*it); delete (*it);
} }
*/
mHitPoints.clear(); mHitPoints.clear();
// Destroy all the normals // Destroy all the normals
@ -135,6 +138,10 @@ class RaycastManager : public rp3d::RaycastCallback {
} }
mNormals.clear(); mNormals.clear();
} }
std::vector<ContactPoint> getHitPoints() const {
return mHitPoints;
}
}; };
// Class RaycastScene // Class RaycastScene
@ -224,6 +231,12 @@ class RaycastScene : public SceneDemo {
/// Enabled/Disable the shadow mapping /// Enabled/Disable the shadow mapping
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
/// Display/Hide the contact points
void virtual setIsContactPointsDisplayed(bool display);
/// Return all the contact points of the scene
virtual std::vector<ContactPoint> getContactPoints() const;
}; };
// Display or not the surface normals at hit points // Display or not the surface normals at hit points
@ -233,10 +246,19 @@ inline void RaycastScene::showHideNormals() {
// Enabled/Disable the shadow mapping // Enabled/Disable the shadow mapping
inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
SceneDemo::setIsShadowMappingEnabled(false); SceneDemo::setIsShadowMappingEnabled(false);
} }
// Display/Hide the contact points
inline void RaycastScene::setIsContactPointsDisplayed(bool display) {
SceneDemo::setIsContactPointsDisplayed(true);
}
// Return all the contact points of the scene
inline std::vector<ContactPoint> RaycastScene::getContactPoints() const {
return mRaycastManager.getHitPoints();
}
} }
#endif #endif

View File

@ -34,6 +34,7 @@ uniform sampler2D shadowMapSampler; // Shadow map texture sampler
uniform bool isTexture; // True if we need to use the texture uniform bool isTexture; // True if we need to use the texture
uniform vec4 vertexColor; // Vertex color uniform vec4 vertexColor; // Vertex color
uniform bool isShadowEnabled; // True if shadow mapping is enabled uniform bool isShadowEnabled; // True if shadow mapping is enabled
uniform vec2 shadowMapDimension; // Shadow map dimension
// In variables // In variables
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
@ -44,6 +45,13 @@ in vec4 shadowMapCoords; // Shadow map texture coords
// Out variable // Out variable
out vec4 color; // Output color out vec4 color; // Output color
// Texture for PCF Shadow mapping
float textureLookupPCF(sampler2D map, vec2 texCoords, vec2 offset)
{
vec2 shadowMapScale = vec2(1.0, 1.0) / shadowMapDimension;
return texture(map, texCoords.xy + offset * shadowMapScale).r;
}
void main() { void main() {
// Compute the ambient term // Compute the ambient term
@ -61,18 +69,36 @@ void main() {
float diffuseFactor = max(dot(N, L0), 0.0); float diffuseFactor = max(dot(N, L0), 0.0);
vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor; vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor;
// Compute shadow factor // Compute shadow factor
float shadow = 1.0; float shadow = 1.0;
if (isShadowEnabled) { if (isShadowEnabled) {
shadow = 0.0;
float bias = 0.0003; float bias = 0.0003;
float shadowBias = -0.000; float shadowBias = -0.000;
vec4 shadowMapUV = shadowMapCoords; vec4 shadowMapUV = shadowMapCoords;
shadowMapUV.z -= shadowBias; shadowMapUV.z -= shadowBias;
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
/*
// PCF Shadow Mapping
for (float i=-1; i<=1; i++) {
for (float j=-1; j<=1; j++) {
float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
if (shadowMapCoords.w > 0) {
shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
}
}
shadow /= 9.0;
*/
float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias;
if (shadowMapCoords.w > 0) { if (shadowMapCoords.w > 0) {
shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
} }
} }
// Compute the final color // Compute the final color

View File

@ -299,6 +299,13 @@ void Gui::displayRenderingPane() {
imguiVerticalSpace(15); imguiVerticalSpace(15);
// Display/Hide contact points
bool toggleContactPoints = imguiCheck("Contacts", app.mIsContactPointsDisplayed);
if (toggleContactPoints) {
app.displayContactPoints(!app.mIsContactPointsDisplayed);
}
// Enabled/Disable VSync // Enabled/Disable VSync
bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled); bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled);
if (toggleVSync) { if (toggleVSync) {

View File

@ -37,7 +37,7 @@
const float GUI_SCALING = 2.0f; const float GUI_SCALING = 2.0f;
const int LEFT_PANE_WIDTH = 300; const int LEFT_PANE_WIDTH = 300;
const int LEFT_PANE_HEADER_HEIGHT = 90; const int LEFT_PANE_HEADER_HEIGHT = 90;
const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.2; const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 0.3;
using namespace openglframework; using namespace openglframework;

View File

@ -32,7 +32,8 @@ using namespace openglframework;
// Constructor // Constructor
Scene::Scene(const std::string& name, bool isShadowMappingEnabled) Scene::Scene(const std::string& name, bool isShadowMappingEnabled)
: mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0), : mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0),
mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled) { mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled),
mIsContactPointsDisplayed(true) {
} }

View File

@ -28,7 +28,18 @@
// Libraries // Libraries
#include "openglframework.h" #include "openglframework.h"
#include "PhysicsEventListener.h"
// Structure ContactPoint
struct ContactPoint {
public:
openglframework::Vector3 point;
/// Constructor
ContactPoint(const openglframework::Vector3& pointWorld) : point(pointWorld) {
}
};
/// Structure EngineSettings /// Structure EngineSettings
/// This structure contains several physics engine parameters /// This structure contains several physics engine parameters
@ -94,6 +105,9 @@ class Scene {
/// True if the shadow mapping is enabled /// True if the shadow mapping is enabled
bool mIsShadowMappingEnabled; bool mIsShadowMappingEnabled;
/// True if contact points are displayed
bool mIsContactPointsDisplayed;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Set the scene position (where the camera needs to look at) /// Set the scene position (where the camera needs to look at)
@ -106,7 +120,6 @@ class Scene {
bool mapMouseCoordinatesToSphere(double xMouse, double yMouse, bool mapMouseCoordinatesToSphere(double xMouse, double yMouse,
openglframework::Vector3& spherePoint) const; openglframework::Vector3& spherePoint) const;
/// Zoom the camera /// Zoom the camera
void zoom(float zoomDiff); void zoom(float zoomDiff);
@ -183,6 +196,9 @@ class Scene {
/// Enabled/Disable the shadow mapping /// Enabled/Disable the shadow mapping
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
/// Display/Hide the contact points
void virtual setIsContactPointsDisplayed(bool display);
/// Return all the contact points of the scene /// Return all the contact points of the scene
std::vector<ContactPoint> virtual getContactPoints() const; std::vector<ContactPoint> virtual getContactPoints() const;
}; };
@ -246,6 +262,11 @@ inline void Scene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
mIsShadowMappingEnabled = isShadowMappingEnabled; mIsShadowMappingEnabled = isShadowMappingEnabled;
} }
// Display/Hide the contact points
inline void Scene::setIsContactPointsDisplayed(bool display) {
mIsContactPointsDisplayed = display;
}
// Return all the contact points of the scene // Return all the contact points of the scene
inline std::vector<ContactPoint> Scene::getContactPoints() const { inline std::vector<ContactPoint> Scene::getContactPoints() const {

View File

@ -47,7 +47,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa
mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
mQuadShader("shaders/quad.vert", "shaders/quad.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"),
mVBOQuad(GL_ARRAY_BUFFER) { mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") {
shadowMapTextureLevel++; shadowMapTextureLevel++;
@ -74,6 +74,8 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa
} }
createQuadVBO(); createQuadVBO();
VisualContactPoint::createStaticData(mMeshFolderPath);
} }
// Destructor // Destructor
@ -83,13 +85,23 @@ SceneDemo::~SceneDemo() {
mFBOShadowMap.destroy(); mFBOShadowMap.destroy();
mVBOQuad.destroy(); mVBOQuad.destroy();
// Destroy the contact points
removeAllContactPoints();
VisualContactPoint::destroyStaticData();
}
// Update the scene
void SceneDemo::update() {
// Update the contact points
updateContactPoints();
} }
// Render the scene (in multiple passes for shadow mapping) // Render the scene (in multiple passes for shadow mapping)
void SceneDemo::render() { void SceneDemo::render() {
const Color& diffCol = mLight0.getDiffuseColor(); const Color& diffCol = mLight0.getDiffuseColor();
const Color& specCol = mLight0.getSpecularColor();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@ -154,6 +166,7 @@ void SceneDemo::render() {
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("shadowMapSampler", textureUnit);
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
//mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT));
// Set the viewport to render the scene // Set the viewport to render the scene
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
@ -167,10 +180,15 @@ void SceneDemo::render() {
// Render the objects of the scene // Render the objects of the scene
renderSinglePass(mPhongShader, worldToCameraMatrix); renderSinglePass(mPhongShader, worldToCameraMatrix);
// Render the contact points
if (mIsContactPointsDisplayed) {
renderContactPoints(mPhongShader, worldToCameraMatrix);
}
if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); if (mIsShadowMappingEnabled) mShadowMapTexture.unbind();
mPhongShader.unbind(); mPhongShader.unbind();
//drawTextureQuad(); drawTextureQuad();
} }
// Create the Shadow map FBO and texture // Create the Shadow map FBO and texture
@ -194,6 +212,7 @@ void SceneDemo::createShadowMapFBOAndTexture() {
mIsShadowMappingInitialized = true; mIsShadowMappingInitialized = true;
} }
// Used for debugging shadow maps
void SceneDemo::createQuadVBO() { void SceneDemo::createQuadVBO() {
mVAOQuad.create(); mVAOQuad.create();
@ -254,3 +273,74 @@ void SceneDemo::drawTextureQuad() {
mQuadShader.unbind(); mQuadShader.unbind();
mVAOQuad.unbind(); mVAOQuad.unbind();
} }
// Gather and create contact points
void SceneDemo::updateContactPoints() {
// Remove the previous contact points
removeAllContactPoints();
if (mIsContactPointsDisplayed) {
// Get the current contact points of the scene
std::vector<ContactPoint> contactPoints = getContactPoints();
// For each contact point
std::vector<ContactPoint>::const_iterator it;
for (it = contactPoints.begin(); it != contactPoints.end(); ++it) {
// Create a visual contact point for rendering
VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath);
mContactPoints.push_back(point);
}
}
}
// Render the contact points
void SceneDemo::renderContactPoints(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix) {
// Render all the raycast hit points
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
it != mContactPoints.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix);
}
}
void SceneDemo::removeAllContactPoints() {
// Destroy all the visual contact points
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
it != mContactPoints.end(); ++it) {
delete (*it);
}
mContactPoints.clear();
}
// Return all the contact points of the scene
std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const {
std::vector<ContactPoint> contactPoints;
// Get the list of contact manifolds from the world
std::vector<const rp3d::ContactManifold*> manifolds = world->getContactsList();
// For each contact manifold
std::vector<const rp3d::ContactManifold*>::const_iterator it;
for (it = manifolds.begin(); it != manifolds.end(); ++it) {
const rp3d::ContactManifold* manifold = *it;
// For each contact point of the manifold
for (uint i=0; i<manifold->getNbContactPoints(); i++) {
rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i);
rp3d::Vector3 point = contactPoint->getWorldPointOnBody1();
ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z));
contactPoints.push_back(contact);
}
}
return contactPoints;
}

View File

@ -28,6 +28,8 @@
// Libraries // Libraries
#include "Scene.h" #include "Scene.h"
#include "VisualContactPoint.h"
#include "reactphysics3d.h"
// Constants // Constants
const int SHADOWMAP_WIDTH = 2048; const int SHADOWMAP_WIDTH = 2048;
@ -56,6 +58,9 @@ class SceneDemo : public Scene {
static int shadowMapTextureLevel; static int shadowMapTextureLevel;
/// All the visual contact points
std::vector<VisualContactPoint*> mContactPoints;
/// Shadow map bias matrix /// Shadow map bias matrix
openglframework::Matrix4 mShadowMapBiasMatrix; openglframework::Matrix4 mShadowMapBiasMatrix;
@ -85,17 +90,28 @@ class SceneDemo : public Scene {
static openglframework::Color mDemoColors[]; static openglframework::Color mDemoColors[];
static int mNbDemoColors; static int mNbDemoColors;
std::string mMeshFolderPath;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Shadow map FBO and texture // Create the Shadow map FBO and texture
void createShadowMapFBOAndTexture(); void createShadowMapFBOAndTexture();
// TODO : Delete this // Used for debugging shadow maps
void createQuadVBO(); void createQuadVBO();
// TODO : Delete this // TODO : Delete this
void drawTextureQuad(); void drawTextureQuad();
// Update the contact points
void updateContactPoints();
// Render the contact points
void renderContactPoints(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix);
void removeAllContactPoints();
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -106,6 +122,9 @@ class SceneDemo : public Scene {
/// Destructor /// Destructor
virtual ~SceneDemo(); virtual ~SceneDemo();
/// Update the scene
virtual void update();
/// Render the scene (possibly in multiple passes for shadow mapping) /// Render the scene (possibly in multiple passes for shadow mapping)
virtual void render(); virtual void render();
@ -115,6 +134,9 @@ class SceneDemo : public Scene {
/// Enabled/Disable the shadow mapping /// Enabled/Disable the shadow mapping
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled); void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
/// Return all the contact points of the scene
std::vector<ContactPoint> computeContactPointsOfWorld(const rp3d::DynamicsWorld* world) const;
}; };
// Enabled/Disable the shadow mapping // Enabled/Disable the shadow mapping

View File

@ -63,13 +63,12 @@ TestbedApplication::TestbedApplication()
mWindowToFramebufferRatio = Vector2(1, 1); mWindowToFramebufferRatio = Vector2(1, 1);
mIsShadowMappingEnabled = true; mIsShadowMappingEnabled = true;
mIsVSyncEnabled = true; mIsVSyncEnabled = true;
mIsContactPointsDisplayed = false;
} }
// Destructor // Destructor
TestbedApplication::~TestbedApplication() { TestbedApplication::~TestbedApplication() {
// TODO : Check that this method is called at the end
// Destroy all the scenes // Destroy all the scenes
destroyScenes(); destroyScenes();
@ -242,6 +241,9 @@ void TestbedApplication::update() {
// Enable/Disable shadow mapping // Enable/Disable shadow mapping
mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled); mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled);
// Display/Hide contact points
mCurrentScene->setIsContactPointsDisplayed(mIsContactPointsDisplayed);
// Update the scene // Update the scene
mCurrentScene->update(); mCurrentScene->update();
} }

View File

@ -98,6 +98,9 @@ class TestbedApplication {
/// True if shadow mapping is enabled /// True if shadow mapping is enabled
bool mIsShadowMappingEnabled; bool mIsShadowMappingEnabled;
/// True if contact points are displayed
bool mIsContactPointsDisplayed;
/// True if vsync is enabled /// True if vsync is enabled
bool mIsVSyncEnabled; bool mIsVSyncEnabled;
@ -175,6 +178,9 @@ class TestbedApplication {
/// Enable/Disable shadow mapping /// Enable/Disable shadow mapping
void enableShadows(bool enable); void enableShadows(bool enable);
/// Display/Hide contact points
void displayContactPoints(bool display);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -239,6 +245,11 @@ inline void TestbedApplication::enableShadows(bool enable) {
mIsShadowMappingEnabled = enable; mIsShadowMappingEnabled = enable;
} }
/// Display/Hide contact points
inline void TestbedApplication::displayContactPoints(bool display) {
mIsContactPointsDisplayed = display;
}
// Enable/Disable Vertical synchronization // Enable/Disable Vertical synchronization
inline void TestbedApplication::enableVSync(bool enable) { inline void TestbedApplication::enableVSync(bool enable) {
mIsVSyncEnabled = enable; mIsVSyncEnabled = enable;