diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 3a1659aa..cc97b04e 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -31,32 +31,85 @@ // Initialize static variables openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); -openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); +openglframework::VertexBufferObject Box::mVBONormals(GL_ARRAY_BUFFER); openglframework::VertexArrayObject Box::mVAO; int Box::totalNbBoxes = 0; -VertexData Box::mCubeVertices[8] = { - {openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(1,0,0,1)}, - {openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(1,0,0,1)} +GLfloat Box::mCubeVertices[108] = { + -1.0f,-1.0f,-1.0f, // triangle 1 : begin + -1.0f,-1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, // triangle 1 : end + 1.0f, 1.0f,-1.0f, // triangle 2 : begin + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, // triangle 2 : end + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f +}; +GLfloat Box::mCubeNormals[108] = { + -1.0f, 0.0f, 0.0f, // triangle 1 : begin + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, // triangle 1 : end + 0.0f, 0.0f,-1.0f, // triangle 2 : begin + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f, // triangle 2 : end + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f,// + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f, + 0.0f, 0.0f,-1.0f,// + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f,0.0f,// + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f, + 0.0f,-1.0f, 0.0f,// + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f,// + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f,// + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f,// + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f,// + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f,// + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f// }; -GLuint Box::mCubeIndices[36] = { 0, 1, 2, - 2, 3, 0, - 7, 4, 5, - 5, 6, 7, - 6, 5, 2, - 2, 1, 6, - 7, 0, 3, - 3, 4, 7, - 7, 6, 1, - 1, 0, 7, - 3, 2, 5, - 5, 4, 3}; - // Constructor Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, reactphysics3d::CollisionWorld* world) @@ -161,8 +214,8 @@ Box::~Box() { if (totalNbBoxes == 1) { // Destroy the VBOs and VAO - mVBOIndices.destroy(); mVBOVertices.destroy(); + mVBONormals.destroy(); mVAO.destroy(); } @@ -201,17 +254,20 @@ void Box::render(openglframework::Shader& shader, GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); glEnableVertexAttribArray(vertexPositionLoc); - if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position)); - if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal)); + mVBONormals.bind(); + + if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc); + if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL); // Draw the geometry of the box - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); + glDrawArrays(GL_TRIANGLES, 0, 36); glDisableVertexAttribArray(vertexPositionLoc); if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc); + mVBONormals.unbind(); mVBOVertices.unbind(); // Unbind the VAO @@ -256,11 +312,11 @@ void Box::createVBOAndVAO() { mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); mVBOVertices.unbind(); - // Create th VBO for the indices data - mVBOIndices.create(); - mVBOIndices.bind(); - mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); - mVBOIndices.unbind(); + // Create th VBO for the normals data + mVBONormals.create(); + mVBONormals.bind(); + mVBONormals.copyDataIntoVBO(sizeof(mCubeNormals), mCubeNormals, GL_STATIC_DRAW); + mVBONormals.unbind(); // Create the VAO for both VBOs mVAO.create(); @@ -270,7 +326,7 @@ void Box::createVBOAndVAO() { mVBOVertices.bind(); // Bind the VBO of indices - mVBOIndices.bind(); + mVBONormals.bind(); // Unbind the VAO mVAO.unbind(); diff --git a/testbed/common/Box.h b/testbed/common/Box.h index b322dc8b..d5759bb1 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -65,17 +65,17 @@ class Box : public openglframework::Object3D { /// Vertex Buffer Object for the vertices data used to render the box with OpenGL static openglframework::VertexBufferObject mVBOVertices; - /// Vertex Buffer Object for the indices used to render the box with OpenGL - static openglframework::VertexBufferObject mVBOIndices; + /// Vertex Buffer Object for the normales used to render the box with OpenGL + static openglframework::VertexBufferObject mVBONormals; /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; - /// Vertex data for each vertex of the cube (used to render the box) - static VertexData mCubeVertices[8]; + /// Vertices coordinates of the triangles of the box + static GLfloat mCubeVertices[108]; - /// Indices of the cube (used to render the box) - static GLuint mCubeIndices[36]; + /// Vertices normals of the triangles of the box + static GLfloat mCubeNormals[108]; /// Total number of boxes created static int totalNbBoxes; diff --git a/testbed/opengl-framework/src/Texture2D.cpp b/testbed/opengl-framework/src/Texture2D.cpp index 94d8905e..2bc8f0a5 100644 --- a/testbed/opengl-framework/src/Texture2D.cpp +++ b/testbed/opengl-framework/src/Texture2D.cpp @@ -33,13 +33,13 @@ using namespace openglframework; // Constructor -Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) { +Texture2D::Texture2D() : mID(0), mUnit(0), mWidth(0), mHeight(0) { } // Constructor Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type) - : mID(0), mLayer(0), mWidth(0), mHeight(0){ + : mID(0), mUnit(0), mWidth(0), mHeight(0) { // Create the texture create(width, height, internalFormat, format, type); @@ -52,7 +52,7 @@ Texture2D::~Texture2D() { // Create the texture void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type, - void* data) { + void* data) { // Destroy the current texture destroy(); @@ -99,7 +99,7 @@ void Texture2D::destroy() { if (mID != 0) { glDeleteTextures(1, &mID); mID = 0; - mLayer = 0; + mUnit = 0; mWidth = 0; mHeight = 0; } diff --git a/testbed/opengl-framework/src/Texture2D.h b/testbed/opengl-framework/src/Texture2D.h index f765e1ac..5f8ce3ae 100644 --- a/testbed/opengl-framework/src/Texture2D.h +++ b/testbed/opengl-framework/src/Texture2D.h @@ -45,8 +45,8 @@ class Texture2D { // OpenGL texture ID GLuint mID; - // Layer of the texture - GLuint mLayer; + // Current texture unit for this texture + GLuint mUnit; // Width uint mWidth; @@ -87,11 +87,11 @@ class Texture2D { // Get the OpenGL texture ID uint getID() const; - // Get the layer of the texture - uint getLayer() const; + // Get the unit of the texture + uint getUnit() const; - // Set the layer of the texture - void setLayer(uint layer); + // Set the unit of the texture + void setUnit(uint unit); // Get the width uint getWidth() const; @@ -103,14 +103,14 @@ class Texture2D { // Bind the texture inline void Texture2D::bind() const { assert(mID != 0); - glActiveTexture(GL_TEXTURE0 + mLayer); + glActiveTexture(GL_TEXTURE0 + mUnit); glBindTexture(GL_TEXTURE_2D, mID); } // Unbind the texture inline void Texture2D::unbind() const { assert(mID != 0); - glActiveTexture(GL_TEXTURE0 + mLayer); + glActiveTexture(GL_TEXTURE0 + mUnit); glBindTexture(GL_TEXTURE_2D, 0); } @@ -119,14 +119,14 @@ inline uint Texture2D::getID() const { return mID; } -// Get the layer of the texture -inline uint Texture2D::getLayer() const { - return mLayer; +// Get the unit of the texture +inline uint Texture2D::getUnit() const { + return mUnit; } -// Set the layer of the texture -inline void Texture2D::setLayer(uint layer) { - mLayer = layer; +// Set the unit of the texture +inline void Texture2D::setUnit(uint unit) { + mUnit = unit; } // Get the width diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 46c34f4a..1fc06b7e 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -225,9 +225,6 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name) // Destructor CollisionShapesScene::~CollisionShapesScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy all the boxes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.h b/testbed/scenes/collisionshapes/CollisionShapesScene.h index 92fd166b..a75528e7 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.h +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.h @@ -46,12 +46,12 @@ namespace collisionshapesscene { // Constants const float SCENE_RADIUS = 30.0f; const int NB_BOXES = 3; -const int NB_CUBES = 3; -const int NB_CONES = 3; -const int NB_CYLINDERS = 3; -const int NB_CAPSULES = 3; -const int NB_MESHES = 2; -const int NB_COMPOUND_SHAPES = 2; +const int NB_CUBES = 0; +const int NB_CONES = 0; +const int NB_CYLINDERS = 0; +const int NB_CAPSULES = 0; +const int NB_MESHES = 0; +const int NB_COMPOUND_SHAPES = 0; const openglframework::Vector3 BOX_SIZE(2, 2, 2); const float SPHERE_RADIUS = 1.5f; const float CONE_RADIUS = 2.0f; @@ -61,7 +61,7 @@ const float CYLINDER_HEIGHT = 5.0f; const float CAPSULE_RADIUS = 1.0f; const float CAPSULE_HEIGHT = 1.0f; const float DUMBBELL_HEIGHT = 1.0f; -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; const float CONE_MASS = 1.0f; const float CYLINDER_MASS = 1.0f; @@ -76,9 +76,6 @@ class CollisionShapesScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Phong shader - openglframework::Shader mPhongShader; - /// All the spheres of the scene std::vector mBoxes; diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 1defa9ce..0215e6d3 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -41,7 +41,7 @@ CubesScene::CubesScene(const std::string& name) setScenePosition(center, SCENE_RADIUS); // Gravity vector in the dynamics world - rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); + rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); // Time step for the physics simulation rp3d::decimal timeStep = 1.0f / 60.0f; @@ -100,9 +100,6 @@ CubesScene::CubesScene(const std::string& name) // Destructor CubesScene::~CubesScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy all the cubes of the scene for (std::vector::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 5a60023d..50d7deb1 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -33,11 +33,7 @@ using namespace jointsscene; // Constructor JointsScene::JointsScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS), mLight0(0), mPhongShader("shaders/phong.vert", - "shaders/phong.frag") { - - // Move the light 0 - mLight0.translateWorld(Vector3(7, 15, 15)); + : SceneDemo(name, SCENE_RADIUS) { // Compute the radius and the center of the scene openglframework::Vector3 center(0, 5, 0); @@ -87,9 +83,6 @@ JointsScene::JointsScene(const std::string& name) // Destructor JointsScene::~JointsScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy the joints mDynamicsWorld->destroyJoint(mSliderJoint); mDynamicsWorld->destroyJoint(mPropellerHingeJoint); diff --git a/testbed/scenes/joints/JointsScene.h b/testbed/scenes/joints/JointsScene.h index 2795a7fd..b2d22c07 100644 --- a/testbed/scenes/joints/JointsScene.h +++ b/testbed/scenes/joints/JointsScene.h @@ -37,7 +37,7 @@ namespace jointsscene { // Constants const float SCENE_RADIUS = 30.0f; const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters -const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const float BOX_MASS = 1.0f; // Box mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes @@ -50,12 +50,6 @@ class JointsScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - /// Boxes of Ball-And-Socket joint chain Box* mBallAndSocketJointChainBoxes[NB_BALLSOCKETJOINT_BOXES]; diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index d26c2e8a..4e82fb6a 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -32,14 +32,10 @@ using namespace raycastscene; // Constructor RaycastScene::RaycastScene(const std::string& name) - : SceneDemo(name, SCENE_RADIUS), mLight0(0), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), - mPhongShader("shaders/phong.vert", "shaders/phong.frag"), + : SceneDemo(name, SCENE_RADIUS), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false), mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath), mVBOVertices(GL_ARRAY_BUFFER) { - // Move the light 0 - mLight0.translateWorld(Vector3(50, 50, 50)); - // Compute the radius and the center of the scene openglframework::Vector3 center(0, 0, 0); diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index a58837fc..9110a5bb 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -144,12 +144,6 @@ class RaycastScene : public SceneDemo { // -------------------- Attributes -------------------- // - /// Light 0 - openglframework::Light mLight0; - - /// Phong shader - openglframework::Shader mPhongShader; - /// Contact point mesh folder path std::string mMeshFolderPath; diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 565df414..a4c044f0 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -35,6 +35,7 @@ uniform sampler2D textureSampler; // Texture uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color +uniform bool isShadowEnabled; // True if shadow mapping is enabled // In variables in vec3 vertexPosCameraSpace; // Camera-space position of the vertex @@ -70,20 +71,19 @@ void main() { vec3 specular = light0SpecularColor * specularFactor; // Compute shadow factor - float bias = 0.00001; - float shadowBias = -0.000; - vec4 shadowMapUV = shadowMapCoords; - shadowMapUV.z -= shadowBias; - vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; - float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; - float shadow = 0.0; - if (shadowMapCoords.w > 0) { - shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; - } - if (abs(dot(N, L0)) < 0.01) { - shadow = 0.5; + float shadow = 1.0; + if (isShadowEnabled) { + float bias = 0.0001; + float shadowBias = -0.000; + vec4 shadowMapUV = shadowMapCoords; + shadowMapUV.z -= shadowBias; + vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w ; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias; + if (shadowMapCoords.w > 0) { + shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0; + } } // Compute the final color - color = vec4(ambient + shadow * vertexColor.rgb, 1.0); + color = vec4(ambient + shadow * diffuse, 1.0); } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 5fc1a37f..6a5ddfbe 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -29,13 +29,18 @@ using namespace openglframework; +int SceneDemo::shadowMapTextureLevel = 0; + // Constructor -SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mLight0(0), +SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), + mLight0(0), mIsShadowMappingEnabled(true), mIsShadowMappingInitialized(false), mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), mVBOQuad(GL_ARRAY_BUFFER) { + shadowMapTextureLevel++; + // Move the light0 mLight0.translateWorld(Vector3(0, 40, 40)); @@ -47,14 +52,15 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mShadowMapLightCamera.setSceneRadius(100); //mShadowMapLightCamera.setZoom(1.0); - mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); // Create the Shadow map FBO and texture - createShadowMapFBOAndTexture(); + if (mIsShadowMappingEnabled) { + createShadowMapFBOAndTexture(); + } createQuadVBO(); } @@ -71,49 +77,50 @@ SceneDemo::~SceneDemo() { // Render the scene (in multiple passes for shadow mapping) void SceneDemo::render() { + const Color& diffCol = mLight0.getDiffuseColor(); + const Color& specCol = mLight0.getSpecularColor(); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // ---------- Render the scene to generate the shadow map (first pass) ----------- // - //glEnable(GL_POLYGON_OFFSET_FILL); - //glPolygonOffset(8.0, 4.0); - - // Culling switching, rendering only backface, this is done to avoid self-shadowing - glCullFace(GL_BACK); - - Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); - - // Get the world-space to camera-space matrix + const Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse(); - mFBOShadowMap.bind(); + // If Shadow Mapping is enabled + if (mIsShadowMappingEnabled) { - // Bind the shader - mDepthShader.bind(); + // Culling switching, rendering only backface, this is done to avoid self-shadowing + glCullFace(GL_BACK); - // Set the variables of the shader - mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); + mFBOShadowMap.bind(); - // Set the viewport to render into the shadow map texture - glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); + // Bind the shader + mDepthShader.bind(); - // Clear previous frame values - glClear( GL_DEPTH_BUFFER_BIT); + // Set the variables of the shader + mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); - // Disable color rendering, we only want to write to the Z-Buffer - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + // Set the viewport to render into the shadow map texture + glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); - // Render the objects of the scene - renderSinglePass(mDepthShader, worldToLightCameraMatrix); + // Clear previous frame values + glClear(GL_DEPTH_BUFFER_BIT); - // Unbind the shader - mDepthShader.unbind(); + // Disable color rendering, we only want to write to the Z-Buffer + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - mFBOShadowMap.unbind(); + // Render the objects of the scene + renderSinglePass(mDepthShader, worldToLightCameraMatrix); - glDisable(GL_POLYGON_OFFSET_FILL); + // Unbind the shader + mDepthShader.unbind(); + mFBOShadowMap.unbind(); + + glDisable(GL_POLYGON_OFFSET_FILL); + } // ---------- Render the scene for final rendering (second pass) ----------- // @@ -124,20 +131,20 @@ void SceneDemo::render() { mPhongShader.bind(); - mShadowMapTexture.bind(); + if (mIsShadowMappingEnabled) mShadowMapTexture.bind(); + const GLuint textureUnit = 0; // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); - mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); - const Color& diffCol = mLight0.getDiffuseColor(); - const Color& specCol = mLight0.getSpecularColor(); + mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f)); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); - mPhongShader.setIntUniform("shadowMapSampler", mShadowMapTexture.getID()); + mPhongShader.setIntUniform("shadowMapSampler", textureUnit); + mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -151,7 +158,7 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); - mShadowMapTexture.unbind(); + if (mIsShadowMappingEnabled) mShadowMapTexture.unbind(); mPhongShader.unbind(); //drawTextureQuad(); @@ -163,7 +170,6 @@ void SceneDemo::createShadowMapFBOAndTexture() { // Create the texture for the depth values mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); - mShadowMapTexture.setLayer(1); // Create the FBO for the shadow map mFBOShadowMap.create(0, 0, false); @@ -175,6 +181,8 @@ void SceneDemo::createShadowMapFBOAndTexture() { mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMapTexture.getID()); mFBOShadowMap.unbind(); + + mIsShadowMappingInitialized = true; } // TODO : Delete this @@ -200,7 +208,6 @@ void SceneDemo::createQuadVBO() { mVAOQuad.unbind(); } -// TODO : Delete this void SceneDemo::drawTextureQuad() { glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 83649abf..8893e26c 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -45,12 +45,20 @@ class SceneDemo : public Scene { /// Light 0 openglframework::Light mLight0; + /// True if the shadow mapping is enabled + bool mIsShadowMappingEnabled; + + /// True if the shadows FBO, textures have been created + bool mIsShadowMappingInitialized; + /// FBO for the shadow map openglframework::FrameBufferObject mFBOShadowMap; /// Shadow map texture openglframework::Texture2D mShadowMapTexture; + static int shadowMapTextureLevel; + /// Shadow map bias matrix openglframework::Matrix4 mShadowMapBiasMatrix; @@ -99,8 +107,28 @@ class SceneDemo : public Scene { /// Render the scene in a single pass virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix)=0; + + /// Return true if the shadow mapping is enabled + bool getIsShadowMappingEnabled() const; + + /// Enabled/Disable the shadow mapping + void setIsShadowMappingEnabled(bool isShadowMappingEnabled); }; +// Return true if the shadow mapping is enabled +inline bool SceneDemo::getIsShadowMappingEnabled() const { + return mIsShadowMappingEnabled; +} + +// Enabled/Disable the shadow mapping +inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) { + mIsShadowMappingEnabled = isShadowMappingEnabled; + + if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) { + createShadowMapFBOAndTexture(); + } +} + #endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index d81887f9..6cbeb41a 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -276,10 +276,6 @@ void TestbedApplication::reshape() { // Resize the camera viewport mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); - // Resize the OpenGL viewport - //glViewport(LEFT_PANE_WIDTH, HEADER_HEIGHT, - // width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT); - // Update the window size of the scene int windowWidth, windowHeight; glfwGetWindowSize(mWindow, &windowWidth, &windowHeight);