From 9d55255c56aa171654395c4a77b81efdaa88c086 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Wed, 17 May 2017 23:40:17 +0200 Subject: [PATCH] Add contact point normals and constant color shader in testbed application --- testbed/common/VisualContactPoint.cpp | 96 ++++++++++++++-- testbed/common/VisualContactPoint.h | 24 +++- .../CollisionDetectionScene.cpp | 103 +----------------- .../CollisionDetectionScene.h | 44 ++------ testbed/scenes/raycast/RaycastScene.cpp | 40 ++----- testbed/scenes/raycast/RaycastScene.h | 13 ++- testbed/shaders/color.frag | 38 +++++++ testbed/shaders/color.vert | 43 ++++++++ testbed/src/Scene.h | 5 +- testbed/src/SceneDemo.cpp | 25 ++++- testbed/src/SceneDemo.h | 3 + 11 files changed, 240 insertions(+), 194 deletions(-) mode change 100644 => 100755 testbed/scenes/collisiondetection/CollisionDetectionScene.cpp mode change 100644 => 100755 testbed/scenes/collisiondetection/CollisionDetectionScene.h create mode 100644 testbed/shaders/color.frag create mode 100644 testbed/shaders/color.vert diff --git a/testbed/common/VisualContactPoint.cpp b/testbed/common/VisualContactPoint.cpp index 7661587e..03ed864b 100644 --- a/testbed/common/VisualContactPoint.cpp +++ b/testbed/common/VisualContactPoint.cpp @@ -36,17 +36,24 @@ openglframework::Mesh VisualContactPoint::mMesh; bool VisualContactPoint::mStaticDataCreated = false; // Constructor -VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, - const std::string& meshFolderPath) - : mColor(1.0f, 0.0f, 0.0f, 1.0f) { +VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, const std::string& meshFolderPath, + const openglframework::Vector3& normalLineEndPointLocal, const openglframework::Color& color) + : mColor(color), mVBOVerticesNormalLine(GL_ARRAY_BUFFER) { + + mContactNormalLinePoints[0] = openglframework::Vector3(0, 0, 0); + mContactNormalLinePoints[1] = (normalLineEndPointLocal - position) * 0.5f; // Initialize the position where the mesh will be rendered translateWorld(position); + + // Create the VBO and VAO to render the contact normal line + createContactNormalLineVBOAndVAO(); } // Destructor VisualContactPoint::~VisualContactPoint() { - + mVAONormalLine.destroy(); + mVBOVerticesNormalLine.destroy(); } // Load and initialize the mesh for all the contact points @@ -84,8 +91,7 @@ void VisualContactPoint::destroyStaticData() { } // Render the sphere at the correct position and with the correct orientation -void VisualContactPoint::render(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { +void VisualContactPoint::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Bind the VAO mVAO.bind(); @@ -93,6 +99,10 @@ void VisualContactPoint::render(openglframework::Shader& shader, // Bind the shader shader.bind(); + // Set the vertex color + openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); + shader.setVector4Uniform("vertexColor", color, false); + mVBOVertices.bind(); // Set the model to camera matrix @@ -106,10 +116,6 @@ void VisualContactPoint::render(openglframework::Shader& shader, localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); - // Set the vertex color - openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); - shader.setVector4Uniform("vertexColor", color, false); - // Get the location of shader attribute variables GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); @@ -138,9 +144,56 @@ void VisualContactPoint::render(openglframework::Shader& shader, // Unbind the shader shader.unbind(); + + // Render the contact normal line + renderContactNormalLine(shader, worldToCameraMatrix); } -// Create the Vertex Buffer Objects used to render with OpenGL. +void VisualContactPoint::renderContactNormalLine(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { + + // Bind the VAO + mVAONormalLine.bind(); + + // Bind the shader + shader.bind(); + + mVBOVerticesNormalLine.bind(); + + // Set the model to camera matrix + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; + shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); + + // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the + // model-view matrix) + const openglframework::Matrix3 normalMatrix = + localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); + shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); + + // Set the vertex color + openglframework::Vector4 color(0, 1, 0, 1); + shader.setVector4Uniform("vertexColor", color, false); + + // Get the location of shader attribute variables + GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + + glEnableVertexAttribArray(vertexPositionLoc); + glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); + + // Draw the lines + glDrawArrays(GL_LINES, 0, 2); + + glDisableVertexAttribArray(vertexPositionLoc); + + mVBOVerticesNormalLine.unbind(); + + // Unbind the VAO + mVAONormalLine.unbind(); + + shader.unbind(); +} + +// Create the Vertex Buffer Objects used to render the contact point sphere with OpenGL. /// We create two VBOs (one for vertices and one for indices) void VisualContactPoint::createVBOAndVAO() { @@ -181,3 +234,24 @@ void VisualContactPoint::createVBOAndVAO() { // Unbind the VAO mVAO.unbind(); } + +// Create the Vertex Buffer Objects used to render the contact normal line +void VisualContactPoint::createContactNormalLineVBOAndVAO() { + + // Create the VBO for the vertices data + mVBOVerticesNormalLine.create(); + mVBOVerticesNormalLine.bind(); + size_t sizeNormalLineVertices = 2 * sizeof(openglframework::Vector3); + mVBOVerticesNormalLine.copyDataIntoVBO(sizeNormalLineVertices, &mContactNormalLinePoints[0], GL_STATIC_DRAW); + mVBOVerticesNormalLine.unbind(); + + // Create the VAO for both VBOs + mVAONormalLine.create(); + mVAONormalLine.bind(); + + // Bind the VBO of vertices + mVBOVerticesNormalLine.bind(); + + // Unbind the VAO + mVAONormalLine.unbind(); +} diff --git a/testbed/common/VisualContactPoint.h b/testbed/common/VisualContactPoint.h index 944caf21..b540e751 100644 --- a/testbed/common/VisualContactPoint.h +++ b/testbed/common/VisualContactPoint.h @@ -28,6 +28,7 @@ // Libraries #include "openglframework.h" +#include "Line.h" const float VISUAL_CONTACT_POINT_RADIUS = 0.2f; @@ -56,15 +57,30 @@ class VisualContactPoint : public openglframework::Object3D { /// Vertex Array Object for the vertex data static openglframework::VertexArrayObject mVAO; + /// Vertex Buffer Object for the vertices data + openglframework::VertexBufferObject mVBOVerticesNormalLine; + + /// Vertex Array Object for the vertex data + openglframework::VertexArrayObject mVAONormalLine; + /// True if static data (VBO, VAO) has been created already static bool mStaticDataCreated; + // Two end-points of the contact normal line + openglframework::Vector3 mContactNormalLinePoints[2]; + /// Color openglframework::Color mColor; - // Create the Vertex Buffer Objects used to render with OpenGL. + // Create the Vertex Buffer Objects used to render the contact point sphere with OpenGL. static void createVBOAndVAO(); + // Create the Vertex Buffer Objects used to render the contact normal line with OpenGL. + void createContactNormalLineVBOAndVAO(); + + /// Render the contact normal line + void renderContactNormalLine(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); + // -------------------- Methods -------------------- // public : @@ -72,8 +88,8 @@ class VisualContactPoint : public openglframework::Object3D { // -------------------- Methods -------------------- // /// Constructor - VisualContactPoint(const openglframework::Vector3& position, - const std::string &meshFolderPath); + VisualContactPoint(const openglframework::Vector3& position, const std::string &meshFolderPath, + const openglframework::Vector3& normalLineEndPointLocal, const openglframework::Color& color); /// Destructor ~VisualContactPoint(); @@ -84,7 +100,7 @@ class VisualContactPoint : public openglframework::Object3D { /// Destroy the mesh for the contact points static void destroyStaticData(); - /// Render the sphere at the correct position and with the correct orientation + /// Render the sphere contact point at the correct position and with the correct orientation void render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix); }; diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp old mode 100644 new mode 100755 index b96620b6..21a0b51a --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -34,7 +34,7 @@ using namespace collisiondetectionscene; CollisionDetectionScene::CollisionDetectionScene(const std::string& name) : SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), mContactManager(mPhongShader, mMeshFolderPath), - mAreNormalsDisplayed(false), mVBOVertices(GL_ARRAY_BUFFER) { + mAreNormalsDisplayed(false) { mSelectedShapeIndex = 0; mIsContactPointsDisplayed = true; @@ -60,7 +60,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) mSphere1->setColor(mGreyColorDemo); mSphere1->setSleepingColor(mRedColorDemo); - /* // ---------- Sphere 2 ---------- // openglframework::Vector3 position2(4, 0, 0); @@ -93,17 +92,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) // Set the color mCapsule2->setColor(mGreyColorDemo); mCapsule2->setSleepingColor(mRedColorDemo); -*/ - // ---------- Box 1 ---------- // - openglframework::Vector3 position5(4, 5, 0); - - // Create a box and a corresponding collision body in the dynamics world - mBox1 = new Box(BOX_SIZE, position5, mCollisionWorld, mMeshFolderPath); - mAllShapes.push_back(mBox1); - - // Set the color - mBox1->setColor(mGreyColorDemo); - mBox1->setSleepingColor(mRedColorDemo); // ---------- Cone ---------- // //openglframework::Vector3 position4(0, 0, 0); @@ -158,9 +146,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name) //mHeightField->setColor(mGreyColorDemo); //mHeightField->setSleepingColor(mRedColorDemo); - // Create the VBO and VAO to render the lines - //createVBOAndVAO(mPhongShader); - mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo); } @@ -172,9 +157,6 @@ void CollisionDetectionScene::reset() { // Destructor CollisionDetectionScene::~CollisionDetectionScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy the box rigid body from the dynamics world //mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); //delete mBox; @@ -183,7 +165,6 @@ CollisionDetectionScene::~CollisionDetectionScene() { mCollisionWorld->destroyCollisionBody(mSphere1->getCollisionBody()); delete mSphere1; - /* mCollisionWorld->destroyCollisionBody(mSphere2->getCollisionBody()); delete mSphere2; @@ -192,10 +173,6 @@ CollisionDetectionScene::~CollisionDetectionScene() { mCollisionWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); delete mCapsule2; - */ - - mCollisionWorld->destroyCollisionBody(mBox1->getCollisionBody()); - delete mBox1; /* // Destroy the corresponding rigid body from the dynamics world @@ -246,10 +223,6 @@ CollisionDetectionScene::~CollisionDetectionScene() { // Destroy the collision world delete mCollisionWorld; - - // Destroy the VBOs and VAO - mVBOVertices.destroy(); - mVAO.destroy(); } // Update the physics world (take a simulation step) @@ -272,57 +245,11 @@ void CollisionDetectionScene::update() { void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { - /* - // Bind the VAO - mVAO.bind(); - - // Bind the shader - shader.bind(); - - mVBOVertices.bind(); - - // Set the model to camera matrix - const Matrix4 localToCameraMatrix = Matrix4::identity(); - shader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); - shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); - - // Set the vertex color - openglframework::Vector4 color(1, 0, 0, 1); - shader.setVector4Uniform("vertexColor", color, false); - - // Get the location of shader attribute variables - GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); - - glEnableVertexAttribArray(vertexPositionLoc); - glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); - - // Draw the lines - glDrawArrays(GL_LINES, 0, NB_RAYS); - - glDisableVertexAttribArray(vertexPositionLoc); - - mVBOVertices.unbind(); - - // Unbind the VAO - mVAO.unbind(); - - shader.unbind(); - */ - // Render the shapes if (mSphere1->getCollisionBody()->isActive()) mSphere1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - /* if (mSphere2->getCollisionBody()->isActive()) mSphere2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mCapsule1->getCollisionBody()->isActive()) mCapsule1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mCapsule2->getCollisionBody()->isActive()) mCapsule2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - */ - if (mBox1->getCollisionBody()->isActive()) mBox1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); /* if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix); @@ -338,34 +265,6 @@ void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader, shader.unbind(); } -// Create the Vertex Buffer Objects used to render with OpenGL. -/// We create two VBOs (one for vertices and one for indices) -void CollisionDetectionScene::createVBOAndVAO(openglframework::Shader& shader) { - - // Bind the shader - shader.bind(); - - // Create the VBO for the vertices data - mVBOVertices.create(); - mVBOVertices.bind(); - size_t sizeVertices = mLinePoints.size() * sizeof(openglframework::Vector3); - mVBOVertices.copyDataIntoVBO(sizeVertices, &mLinePoints[0], GL_STATIC_DRAW); - mVBOVertices.unbind(); - - // Create the VAO for both VBOs - mVAO.create(); - mVAO.bind(); - - // Bind the VBO of vertices - mVBOVertices.bind(); - - // Unbind the VAO - mVAO.unbind(); - - // Unbind the shader - shader.unbind(); -} - void CollisionDetectionScene::selectNextShape() { int previousIndex = mSelectedShapeIndex; diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.h b/testbed/scenes/collisiondetection/CollisionDetectionScene.h old mode 100644 new mode 100755 index 01df3df8..6eeeb25b --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.h +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.h @@ -58,7 +58,7 @@ const int NB_RAYS = 100; const float RAY_LENGTH = 30.0f; const int NB_BODIES = 9; -// Raycast manager +// Contact manager class ContactManager : public rp3d::CollisionCallback { private: @@ -66,16 +66,12 @@ class ContactManager : public rp3d::CollisionCallback { /// All the visual contact points std::vector mContactPoints; - /// All the normals at contact points - std::vector mNormals; - /// Contact point mesh folder path std::string mMeshFolderPath; public: - ContactManager(openglframework::Shader& shader, - const std::string& meshFolderPath) + ContactManager(openglframework::Shader& shader, const std::string& meshFolderPath) : mMeshFolderPath(meshFolderPath) { } @@ -87,22 +83,20 @@ class ContactManager : public rp3d::CollisionCallback { rp3d::ContactPointInfo* contactPointInfo = collisionCallbackInfo.contactManifold.getFirstContactPointInfo(); while (contactPointInfo != nullptr) { + // Contact normal + rp3d::Vector3 normal = contactPointInfo->normal; + openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z); + rp3d::Vector3 point1 = contactPointInfo->localPoint1; point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1; + openglframework::Vector3 position1(point1.x, point1.y, point1.z); - mContactPoints.push_back(ContactPoint(position1)); - + mContactPoints.push_back(ContactPoint(position1, contactNormal, openglframework::Color::red())); rp3d::Vector3 point2 = contactPointInfo->localPoint2; point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2; openglframework::Vector3 position2(point2.x, point2.y, point2.z); - mContactPoints.push_back(ContactPoint(position2)); - - // Create a line to display the normal at hit point - rp3d::Vector3 n = contactPointInfo->normal; - openglframework::Vector3 normal(n.x, n.y, n.z); - Line* normalLine = new Line(position1, position1 + normal); - mNormals.push_back(normalLine); + mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue())); contactPointInfo = contactPointInfo->next; } @@ -111,13 +105,6 @@ class ContactManager : public rp3d::CollisionCallback { void resetPoints() { mContactPoints.clear(); - - // Destroy all the normals - for (std::vector::iterator it = mNormals.begin(); - it != mNormals.end(); ++it) { - delete (*it); - } - mNormals.clear(); } std::vector getContactPoints() const { @@ -146,7 +133,6 @@ class CollisionDetectionScene : public SceneDemo { Sphere* mSphere2; Capsule* mCapsule1; Capsule* mCapsule2; - Box* mBox1; //Cone* mCone; //Cylinder* mCylinder; //Capsule* mCapsule; @@ -162,18 +148,6 @@ class CollisionDetectionScene : public SceneDemo { /// Collision world used for the physics simulation rp3d::CollisionWorld* mCollisionWorld; - /// All the points to render the lines - std::vector mLinePoints; - - /// Vertex Buffer Object for the vertices data - openglframework::VertexBufferObject mVBOVertices; - - /// Vertex Array Object for the vertex data - openglframework::VertexArrayObject mVAO; - - /// Create the Vertex Buffer Objects used to render with OpenGL. - void createVBOAndVAO(openglframework::Shader& shader); - /// Select the next shape void selectNextShape(); diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index c403ebb2..d420073f 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -124,7 +124,7 @@ RaycastScene::RaycastScene(const std::string& name) createLines(); // Create the VBO and VAO to render the lines - createVBOAndVAO(mPhongShader); + createVBOAndVAO(); changeBody(); } @@ -199,9 +199,6 @@ void RaycastScene::reset() { // Destructor RaycastScene::~RaycastScene() { - // Destroy the shader - mPhongShader.destroy(); - // Destroy the box rigid body from the dynamics world mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); delete mBox; @@ -293,40 +290,33 @@ void RaycastScene::update() { } // Render the scene -void RaycastScene::renderSinglePass(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { +void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Bind the VAO mVAO.bind(); // Bind the shader - shader.bind(); + mColorShader.bind(); mVBOVertices.bind(); // Set the model to camera matrix const Matrix4 localToCameraMatrix = Matrix4::identity(); - shader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); - shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); - - // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the - // model-view matrix) - const openglframework::Matrix3 normalMatrix = - localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); - shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); + mColorShader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); + mColorShader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the vertex color - openglframework::Vector4 color(1, 0, 0, 1); - shader.setVector4Uniform("vertexColor", color, false); + openglframework::Vector4 color(1, 0.55, 0, 1); + mColorShader.setVector4Uniform("vertexColor", color, false); // Get the location of shader attribute variables - GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); + GLint vertexPositionLoc = mColorShader.getAttribLocation("vertexPosition"); glEnableVertexAttribArray(vertexPositionLoc); glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); // Draw the lines - glDrawArrays(GL_LINES, 0, NB_RAYS); + glDrawArrays(GL_LINES, 0, mLinePoints.size() * 2); glDisableVertexAttribArray(vertexPositionLoc); @@ -335,7 +325,7 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, // Unbind the VAO mVAO.unbind(); - shader.unbind(); + mColorShader.unbind(); // Render the shapes if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); @@ -345,16 +335,11 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader, if (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mConcaveMesh->getCollisionBody()->isActive()) mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mHeightField->getCollisionBody()->isActive()) mHeightField->render(shader, worldToCameraMatrix, mIsWireframeEnabled); - - shader.unbind(); } // Create the Vertex Buffer Objects used to render with OpenGL. /// We create two VBOs (one for vertices and one for indices) -void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { - - // Bind the shader - shader.bind(); +void RaycastScene::createVBOAndVAO() { // Create the VBO for the vertices data mVBOVertices.create(); @@ -372,9 +357,6 @@ void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { // Unbind the VAO mVAO.unbind(); - - // Unbind the shader - shader.unbind(); } // Called when a keyboard event occurs diff --git a/testbed/scenes/raycast/RaycastScene.h b/testbed/scenes/raycast/RaycastScene.h index be698e53..39b73799 100644 --- a/testbed/scenes/raycast/RaycastScene.h +++ b/testbed/scenes/raycast/RaycastScene.h @@ -82,13 +82,16 @@ class RaycastManager : public rp3d::RaycastCallback { } virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) override { + + rp3d::Vector3 n = raycastInfo.worldNormal; + openglframework::Vector3 normal(n.x, n.y, n.z); + rp3d::Vector3 hitPos = raycastInfo.worldPoint; openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); - mHitPoints.push_back(ContactPoint(position)); + mHitPoints.push_back(ContactPoint(position, normal, openglframework::Color::red())); // Create a line to display the normal at hit point - rp3d::Vector3 n = raycastInfo.worldNormal; - openglframework::Vector3 normal(n.x, n.y, n.z); + // TODO : Remove the mNormals because the VisualContactPoint is now able to display the contact normal on its own Line* normalLine = new Line(position, position + normal); mNormals.push_back(normalLine); @@ -134,8 +137,6 @@ class RaycastScene : public SceneDemo { /// True if the hit points normals are displayed bool mAreNormalsDisplayed; - /// Raycast manager - /// All objects on the scene Box* mBox; Sphere* mSphere; @@ -161,7 +162,7 @@ class RaycastScene : public SceneDemo { void createLines(); // Create the Vertex Buffer Objects used to render with OpenGL. - void createVBOAndVAO(openglframework::Shader& shader); + void createVBOAndVAO(); public: diff --git a/testbed/shaders/color.frag b/testbed/shaders/color.frag new file mode 100644 index 00000000..7ba710f0 --- /dev/null +++ b/testbed/shaders/color.frag @@ -0,0 +1,38 @@ +#version 330 + +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform vec4 vertexColor; // Vertex color + +// Out variable +out vec4 color; // Output color + +void main() { + + // Compute the final color + color = vertexColor; +} diff --git a/testbed/shaders/color.vert b/testbed/shaders/color.vert new file mode 100644 index 00000000..72083abc --- /dev/null +++ b/testbed/shaders/color.vert @@ -0,0 +1,43 @@ +#version 330 + +/******************************************************************************** +* OpenGL-Framework * +* Copyright (c) 2015 Daniel Chappuis * +********************************************************************************* +* * +* This software is provided 'as-is', without any express or implied warranty. * +* In no event will the authors be held liable for any damages arising from the * +* use of this software. * +* * +* Permission is granted to anyone to use this software for any purpose, * +* including commercial applications, and to alter it and redistribute it * +* freely, subject to the following restrictions: * +* * +* 1. The origin of this software must not be misrepresented; you must not claim * +* that you wrote the original software. If you use this software in a * +* product, an acknowledgment in the product documentation would be * +* appreciated but is not required. * +* * +* 2. Altered source versions must be plainly marked as such, and must not be * +* misrepresented as being the original software. * +* * +* 3. This notice may not be removed or altered from any source distribution. * +* * +********************************************************************************/ + +// Uniform variables +uniform mat4 localToWorldMatrix; // Local-space to world-space matrix +uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix +uniform mat4 projectionMatrix; // Projection matrix + +// In variables +in vec4 vertexPosition; + +void main() { + + // Compute the vertex position + vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition; + + // Compute the clip-space vertex coordinates + gl_Position = projectionMatrix * positionCameraSpace; +} diff --git a/testbed/src/Scene.h b/testbed/src/Scene.h index d51ffec1..aa29b9e5 100644 --- a/testbed/src/Scene.h +++ b/testbed/src/Scene.h @@ -34,9 +34,12 @@ struct ContactPoint { public: openglframework::Vector3 point; + openglframework::Vector3 normal; + openglframework::Color color; /// Constructor - ContactPoint(const openglframework::Vector3& pointWorld) : point(pointWorld) { + ContactPoint(const openglframework::Vector3& pointWorld, const openglframework::Vector3& normalWorld, const openglframework::Color colorPoint) + : point(pointWorld), normal(normalWorld), color(colorPoint) { } }; diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 1906d9f4..2cb3e440 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -46,6 +46,7 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMa mDepthShader("shaders/depth.vert", "shaders/depth.frag"), mPhongShader("shaders/phong.vert", "shaders/phong.frag"), mQuadShader("shaders/quad.vert", "shaders/quad.frag"), + mColorShader("shaders/color.vert", "shaders/color.frag"), mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { shadowMapTextureLevel++; @@ -84,6 +85,11 @@ SceneDemo::~SceneDemo() { mFBOShadowMap.destroy(); mVBOQuad.destroy(); + mDepthShader.destroy(); + mPhongShader.destroy(); + mQuadShader.destroy(); + mColorShader.destroy(); + // Destroy the contact points removeAllContactPoints(); @@ -156,7 +162,7 @@ void SceneDemo::render() { if (mIsShadowMappingEnabled) mShadowMapTexture.bind(); const GLuint textureUnit = 0; - // Set the variables of the shader + // Set the variables of the phong shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); @@ -166,6 +172,12 @@ void SceneDemo::render() { mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); + mPhongShader.unbind(); + + // Set the variables of the color shader + mColorShader.bind(); + mColorShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); + mColorShader.unbind(); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -289,20 +301,19 @@ void SceneDemo::updateContactPoints() { for (it = contactPoints.begin(); it != contactPoints.end(); ++it) { // Create a visual contact point for rendering - VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath); + VisualContactPoint* point = new VisualContactPoint(it->point, mMeshFolderPath, it->point + it->normal, it->color); mContactPoints.push_back(point); } } } // Render the contact points -void SceneDemo::renderContactPoints(openglframework::Shader& shader, - const openglframework::Matrix4& worldToCameraMatrix) { +void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) { // Render all the raycast hit points for (std::vector::iterator it = mContactPoints.begin(); it != mContactPoints.end(); ++it) { - (*it)->render(shader, worldToCameraMatrix); + (*it)->render(mColorShader, worldToCameraMatrix); } } @@ -335,7 +346,9 @@ std::vector SceneDemo::computeContactPointsOfWorld(const rp3d::Dyn rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i); rp3d::Vector3 point = contactPoint->getWorldPointOnBody1(); - ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z)); + rp3d::Vector3 normalWorld = contactPoint->getNormal(); + openglframework::Vector3 normal = openglframework::Vector3(normalWorld.x, normalWorld.y, normalWorld.z); + ContactPoint contact(openglframework::Vector3(point.x, point.y, point.z), normal, openglframework::Color::red()); contactPoints.push_back(contact); } diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index c64c8a9b..f7b5f7ce 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -73,6 +73,9 @@ class SceneDemo : public Scene { /// Phong shader openglframework::Shader mPhongShader; + /// Constant color shader + openglframework::Shader mColorShader; + // TODO : Delete this openglframework::Shader mQuadShader;