Add contact point normals and constant color shader in testbed application

This commit is contained in:
Daniel Chappuis 2017-05-17 23:40:17 +02:00
parent 2af87d4804
commit 9d55255c56
11 changed files with 240 additions and 194 deletions

View File

@ -36,17 +36,24 @@ openglframework::Mesh VisualContactPoint::mMesh;
bool VisualContactPoint::mStaticDataCreated = false; bool VisualContactPoint::mStaticDataCreated = false;
// Constructor // Constructor
VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, VisualContactPoint::VisualContactPoint(const openglframework::Vector3& position, const std::string& meshFolderPath,
const std::string& meshFolderPath) const openglframework::Vector3& normalLineEndPointLocal, const openglframework::Color& color)
: mColor(1.0f, 0.0f, 0.0f, 1.0f) { : 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 // Initialize the position where the mesh will be rendered
translateWorld(position); translateWorld(position);
// Create the VBO and VAO to render the contact normal line
createContactNormalLineVBOAndVAO();
} }
// Destructor // Destructor
VisualContactPoint::~VisualContactPoint() { VisualContactPoint::~VisualContactPoint() {
mVAONormalLine.destroy();
mVBOVerticesNormalLine.destroy();
} }
// Load and initialize the mesh for all the contact points // 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 // Render the sphere at the correct position and with the correct orientation
void VisualContactPoint::render(openglframework::Shader& shader, void VisualContactPoint::render(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
const openglframework::Matrix4& worldToCameraMatrix) {
// Bind the VAO // Bind the VAO
mVAO.bind(); mVAO.bind();
@ -93,6 +99,10 @@ void VisualContactPoint::render(openglframework::Shader& shader,
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
// Set the vertex color
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
shader.setVector4Uniform("vertexColor", color, false);
mVBOVertices.bind(); mVBOVertices.bind();
// Set the model to camera matrix // Set the model to camera matrix
@ -106,10 +116,6 @@ void VisualContactPoint::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); 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 // Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false); GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
@ -138,9 +144,56 @@ void VisualContactPoint::render(openglframework::Shader& shader,
// Unbind the shader // Unbind the shader
shader.unbind(); 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) /// We create two VBOs (one for vertices and one for indices)
void VisualContactPoint::createVBOAndVAO() { void VisualContactPoint::createVBOAndVAO() {
@ -181,3 +234,24 @@ void VisualContactPoint::createVBOAndVAO() {
// Unbind the VAO // Unbind the VAO
mVAO.unbind(); 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();
}

View File

@ -28,6 +28,7 @@
// Libraries // Libraries
#include "openglframework.h" #include "openglframework.h"
#include "Line.h"
const float VISUAL_CONTACT_POINT_RADIUS = 0.2f; const float VISUAL_CONTACT_POINT_RADIUS = 0.2f;
@ -56,15 +57,30 @@ 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;
/// 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 /// True if static data (VBO, VAO) has been created already
static bool mStaticDataCreated; static bool mStaticDataCreated;
// Two end-points of the contact normal line
openglframework::Vector3 mContactNormalLinePoints[2];
/// Color /// Color
openglframework::Color mColor; 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(); 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 -------------------- // // -------------------- Methods -------------------- //
public : public :
@ -72,8 +88,8 @@ class VisualContactPoint : public openglframework::Object3D {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
VisualContactPoint(const openglframework::Vector3& position, VisualContactPoint(const openglframework::Vector3& position, const std::string &meshFolderPath,
const std::string &meshFolderPath); const openglframework::Vector3& normalLineEndPointLocal, const openglframework::Color& color);
/// Destructor /// Destructor
~VisualContactPoint(); ~VisualContactPoint();
@ -84,7 +100,7 @@ class VisualContactPoint : public openglframework::Object3D {
/// Destroy the mesh for the contact points /// Destroy the mesh for the contact points
static void destroyStaticData(); 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, void render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix); const openglframework::Matrix4& worldToCameraMatrix);
}; };

View File

@ -34,7 +34,7 @@ using namespace collisiondetectionscene;
CollisionDetectionScene::CollisionDetectionScene(const std::string& name) CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
: SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"), : SceneDemo(name, SCENE_RADIUS, false), mMeshFolderPath("meshes/"),
mContactManager(mPhongShader, mMeshFolderPath), mContactManager(mPhongShader, mMeshFolderPath),
mAreNormalsDisplayed(false), mVBOVertices(GL_ARRAY_BUFFER) { mAreNormalsDisplayed(false) {
mSelectedShapeIndex = 0; mSelectedShapeIndex = 0;
mIsContactPointsDisplayed = true; mIsContactPointsDisplayed = true;
@ -60,7 +60,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
mSphere1->setColor(mGreyColorDemo); mSphere1->setColor(mGreyColorDemo);
mSphere1->setSleepingColor(mRedColorDemo); mSphere1->setSleepingColor(mRedColorDemo);
/*
// ---------- Sphere 2 ---------- // // ---------- Sphere 2 ---------- //
openglframework::Vector3 position2(4, 0, 0); openglframework::Vector3 position2(4, 0, 0);
@ -93,17 +92,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
// Set the color // Set the color
mCapsule2->setColor(mGreyColorDemo); mCapsule2->setColor(mGreyColorDemo);
mCapsule2->setSleepingColor(mRedColorDemo); 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 ---------- // // ---------- Cone ---------- //
//openglframework::Vector3 position4(0, 0, 0); //openglframework::Vector3 position4(0, 0, 0);
@ -158,9 +146,6 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name)
//mHeightField->setColor(mGreyColorDemo); //mHeightField->setColor(mGreyColorDemo);
//mHeightField->setSleepingColor(mRedColorDemo); //mHeightField->setSleepingColor(mRedColorDemo);
// Create the VBO and VAO to render the lines
//createVBOAndVAO(mPhongShader);
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo); mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
} }
@ -172,9 +157,6 @@ void CollisionDetectionScene::reset() {
// Destructor // Destructor
CollisionDetectionScene::~CollisionDetectionScene() { CollisionDetectionScene::~CollisionDetectionScene() {
// Destroy the shader
mPhongShader.destroy();
// Destroy the box rigid body from the dynamics world // Destroy the box rigid body from the dynamics world
//mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); //mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody());
//delete mBox; //delete mBox;
@ -183,7 +165,6 @@ CollisionDetectionScene::~CollisionDetectionScene() {
mCollisionWorld->destroyCollisionBody(mSphere1->getCollisionBody()); mCollisionWorld->destroyCollisionBody(mSphere1->getCollisionBody());
delete mSphere1; delete mSphere1;
/*
mCollisionWorld->destroyCollisionBody(mSphere2->getCollisionBody()); mCollisionWorld->destroyCollisionBody(mSphere2->getCollisionBody());
delete mSphere2; delete mSphere2;
@ -192,10 +173,6 @@ CollisionDetectionScene::~CollisionDetectionScene() {
mCollisionWorld->destroyCollisionBody(mCapsule2->getCollisionBody()); mCollisionWorld->destroyCollisionBody(mCapsule2->getCollisionBody());
delete mCapsule2; delete mCapsule2;
*/
mCollisionWorld->destroyCollisionBody(mBox1->getCollisionBody());
delete mBox1;
/* /*
// Destroy the corresponding rigid body from the dynamics world // Destroy the corresponding rigid body from the dynamics world
@ -246,10 +223,6 @@ CollisionDetectionScene::~CollisionDetectionScene() {
// Destroy the collision world // Destroy the collision world
delete mCollisionWorld; delete mCollisionWorld;
// Destroy the VBOs and VAO
mVBOVertices.destroy();
mVAO.destroy();
} }
// Update the physics world (take a simulation step) // Update the physics world (take a simulation step)
@ -272,57 +245,11 @@ void CollisionDetectionScene::update() {
void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader, void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix) { 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 // Render the shapes
if (mSphere1->getCollisionBody()->isActive()) mSphere1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mSphere1->getCollisionBody()->isActive()) mSphere1->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
/*
if (mSphere2->getCollisionBody()->isActive()) mSphere2->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mSphere2->getCollisionBody()->isActive()) mSphere2->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
if (mCapsule1->getCollisionBody()->isActive()) mCapsule1->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mCapsule1->getCollisionBody()->isActive()) mCapsule1->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
if (mCapsule2->getCollisionBody()->isActive()) mCapsule2->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); if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix);
@ -338,34 +265,6 @@ void CollisionDetectionScene::renderSinglePass(openglframework::Shader& shader,
shader.unbind(); 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() { void CollisionDetectionScene::selectNextShape() {
int previousIndex = mSelectedShapeIndex; int previousIndex = mSelectedShapeIndex;

View File

@ -58,7 +58,7 @@ const int NB_RAYS = 100;
const float RAY_LENGTH = 30.0f; const float RAY_LENGTH = 30.0f;
const int NB_BODIES = 9; const int NB_BODIES = 9;
// Raycast manager // Contact manager
class ContactManager : public rp3d::CollisionCallback { class ContactManager : public rp3d::CollisionCallback {
private: private:
@ -66,16 +66,12 @@ class ContactManager : public rp3d::CollisionCallback {
/// All the visual contact points /// All the visual contact points
std::vector<ContactPoint> mContactPoints; std::vector<ContactPoint> mContactPoints;
/// All the normals at contact points
std::vector<Line*> mNormals;
/// Contact point mesh folder path /// Contact point mesh folder path
std::string mMeshFolderPath; std::string mMeshFolderPath;
public: public:
ContactManager(openglframework::Shader& shader, ContactManager(openglframework::Shader& shader, const std::string& meshFolderPath)
const std::string& meshFolderPath)
: mMeshFolderPath(meshFolderPath) { : mMeshFolderPath(meshFolderPath) {
} }
@ -87,22 +83,20 @@ class ContactManager : public rp3d::CollisionCallback {
rp3d::ContactPointInfo* contactPointInfo = collisionCallbackInfo.contactManifold.getFirstContactPointInfo(); rp3d::ContactPointInfo* contactPointInfo = collisionCallbackInfo.contactManifold.getFirstContactPointInfo();
while (contactPointInfo != nullptr) { while (contactPointInfo != nullptr) {
// Contact normal
rp3d::Vector3 normal = contactPointInfo->normal;
openglframework::Vector3 contactNormal(normal.x, normal.y, normal.z);
rp3d::Vector3 point1 = contactPointInfo->localPoint1; rp3d::Vector3 point1 = contactPointInfo->localPoint1;
point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1; point1 = collisionCallbackInfo.proxyShape1->getLocalToWorldTransform() * point1;
openglframework::Vector3 position1(point1.x, point1.y, point1.z); 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; rp3d::Vector3 point2 = contactPointInfo->localPoint2;
point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2; point2 = collisionCallbackInfo.proxyShape2->getLocalToWorldTransform() * point2;
openglframework::Vector3 position2(point2.x, point2.y, point2.z); openglframework::Vector3 position2(point2.x, point2.y, point2.z);
mContactPoints.push_back(ContactPoint(position2)); mContactPoints.push_back(ContactPoint(position2, contactNormal, openglframework::Color::blue()));
// 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);
contactPointInfo = contactPointInfo->next; contactPointInfo = contactPointInfo->next;
} }
@ -111,13 +105,6 @@ class ContactManager : public rp3d::CollisionCallback {
void resetPoints() { void resetPoints() {
mContactPoints.clear(); mContactPoints.clear();
// Destroy all the normals
for (std::vector<Line*>::iterator it = mNormals.begin();
it != mNormals.end(); ++it) {
delete (*it);
}
mNormals.clear();
} }
std::vector<ContactPoint> getContactPoints() const { std::vector<ContactPoint> getContactPoints() const {
@ -146,7 +133,6 @@ class CollisionDetectionScene : public SceneDemo {
Sphere* mSphere2; Sphere* mSphere2;
Capsule* mCapsule1; Capsule* mCapsule1;
Capsule* mCapsule2; Capsule* mCapsule2;
Box* mBox1;
//Cone* mCone; //Cone* mCone;
//Cylinder* mCylinder; //Cylinder* mCylinder;
//Capsule* mCapsule; //Capsule* mCapsule;
@ -162,18 +148,6 @@ class CollisionDetectionScene : public SceneDemo {
/// Collision world used for the physics simulation /// Collision world used for the physics simulation
rp3d::CollisionWorld* mCollisionWorld; rp3d::CollisionWorld* mCollisionWorld;
/// All the points to render the lines
std::vector<openglframework::Vector3> 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 /// Select the next shape
void selectNextShape(); void selectNextShape();

View File

@ -124,7 +124,7 @@ RaycastScene::RaycastScene(const std::string& name)
createLines(); createLines();
// Create the VBO and VAO to render the lines // Create the VBO and VAO to render the lines
createVBOAndVAO(mPhongShader); createVBOAndVAO();
changeBody(); changeBody();
} }
@ -199,9 +199,6 @@ void RaycastScene::reset() {
// Destructor // Destructor
RaycastScene::~RaycastScene() { RaycastScene::~RaycastScene() {
// Destroy the shader
mPhongShader.destroy();
// Destroy the box rigid body from the dynamics world // Destroy the box rigid body from the dynamics world
mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody()); mCollisionWorld->destroyCollisionBody(mBox->getCollisionBody());
delete mBox; delete mBox;
@ -293,40 +290,33 @@ void RaycastScene::update() {
} }
// Render the scene // Render the scene
void RaycastScene::renderSinglePass(openglframework::Shader& shader, void RaycastScene::renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
const openglframework::Matrix4& worldToCameraMatrix) {
// Bind the VAO // Bind the VAO
mVAO.bind(); mVAO.bind();
// Bind the shader // Bind the shader
shader.bind(); mColorShader.bind();
mVBOVertices.bind(); mVBOVertices.bind();
// Set the model to camera matrix // Set the model to camera matrix
const Matrix4 localToCameraMatrix = Matrix4::identity(); const Matrix4 localToCameraMatrix = Matrix4::identity();
shader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix); mColorShader.setMatrix4x4Uniform("localToWorldMatrix", localToCameraMatrix);
shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); mColorShader.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 // Set the vertex color
openglframework::Vector4 color(1, 0, 0, 1); openglframework::Vector4 color(1, 0.55, 0, 1);
shader.setVector4Uniform("vertexColor", color, false); mColorShader.setVector4Uniform("vertexColor", color, false);
// Get the location of shader attribute variables // Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition"); GLint vertexPositionLoc = mColorShader.getAttribLocation("vertexPosition");
glEnableVertexAttribArray(vertexPositionLoc); glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL); glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Draw the lines // Draw the lines
glDrawArrays(GL_LINES, 0, NB_RAYS); glDrawArrays(GL_LINES, 0, mLinePoints.size() * 2);
glDisableVertexAttribArray(vertexPositionLoc); glDisableVertexAttribArray(vertexPositionLoc);
@ -335,7 +325,7 @@ void RaycastScene::renderSinglePass(openglframework::Shader& shader,
// Unbind the VAO // Unbind the VAO
mVAO.unbind(); mVAO.unbind();
shader.unbind(); mColorShader.unbind();
// Render the shapes // Render the shapes
if (mBox->getCollisionBody()->isActive()) mBox->render(shader, worldToCameraMatrix, mIsWireframeEnabled); 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 (mDumbbell->getCollisionBody()->isActive()) mDumbbell->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
if (mConcaveMesh->getCollisionBody()->isActive()) mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled); if (mConcaveMesh->getCollisionBody()->isActive()) mConcaveMesh->render(shader, worldToCameraMatrix, mIsWireframeEnabled);
if (mHeightField->getCollisionBody()->isActive()) mHeightField->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. // Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices) /// We create two VBOs (one for vertices and one for indices)
void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) { void RaycastScene::createVBOAndVAO() {
// Bind the shader
shader.bind();
// Create the VBO for the vertices data // Create the VBO for the vertices data
mVBOVertices.create(); mVBOVertices.create();
@ -372,9 +357,6 @@ void RaycastScene::createVBOAndVAO(openglframework::Shader& shader) {
// Unbind the VAO // Unbind the VAO
mVAO.unbind(); mVAO.unbind();
// Unbind the shader
shader.unbind();
} }
// Called when a keyboard event occurs // Called when a keyboard event occurs

View File

@ -82,13 +82,16 @@ class RaycastManager : public rp3d::RaycastCallback {
} }
virtual rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) override { 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; rp3d::Vector3 hitPos = raycastInfo.worldPoint;
openglframework::Vector3 position(hitPos.x, hitPos.y, hitPos.z); 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 // Create a line to display the normal at hit point
rp3d::Vector3 n = raycastInfo.worldNormal; // TODO : Remove the mNormals because the VisualContactPoint is now able to display the contact normal on its own
openglframework::Vector3 normal(n.x, n.y, n.z);
Line* normalLine = new Line(position, position + normal); Line* normalLine = new Line(position, position + normal);
mNormals.push_back(normalLine); mNormals.push_back(normalLine);
@ -134,8 +137,6 @@ class RaycastScene : public SceneDemo {
/// True if the hit points normals are displayed /// True if the hit points normals are displayed
bool mAreNormalsDisplayed; bool mAreNormalsDisplayed;
/// Raycast manager
/// All objects on the scene /// All objects on the scene
Box* mBox; Box* mBox;
Sphere* mSphere; Sphere* mSphere;
@ -161,7 +162,7 @@ class RaycastScene : public SceneDemo {
void createLines(); void createLines();
// Create the Vertex Buffer Objects used to render with OpenGL. // Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader); void createVBOAndVAO();
public: public:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -34,9 +34,12 @@ struct ContactPoint {
public: public:
openglframework::Vector3 point; openglframework::Vector3 point;
openglframework::Vector3 normal;
openglframework::Color color;
/// Constructor /// 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) {
} }
}; };

View File

@ -46,6 +46,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"),
mColorShader("shaders/color.vert", "shaders/color.frag"),
mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") { mVBOQuad(GL_ARRAY_BUFFER), mMeshFolderPath("meshes/") {
shadowMapTextureLevel++; shadowMapTextureLevel++;
@ -84,6 +85,11 @@ SceneDemo::~SceneDemo() {
mFBOShadowMap.destroy(); mFBOShadowMap.destroy();
mVBOQuad.destroy(); mVBOQuad.destroy();
mDepthShader.destroy();
mPhongShader.destroy();
mQuadShader.destroy();
mColorShader.destroy();
// Destroy the contact points // Destroy the contact points
removeAllContactPoints(); removeAllContactPoints();
@ -156,7 +162,7 @@ void SceneDemo::render() {
if (mIsShadowMappingEnabled) mShadowMapTexture.bind(); if (mIsShadowMappingEnabled) mShadowMapTexture.bind();
const GLuint textureUnit = 0; const GLuint textureUnit = 0;
// Set the variables of the shader // Set the variables of the phong shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix);
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix);
@ -166,6 +172,12 @@ void SceneDemo::render() {
mPhongShader.setIntUniform("shadowMapSampler", textureUnit); mPhongShader.setIntUniform("shadowMapSampler", textureUnit);
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled); mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT)); 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 // Set the viewport to render the scene
glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight);
@ -289,20 +301,19 @@ void SceneDemo::updateContactPoints() {
for (it = contactPoints.begin(); it != contactPoints.end(); ++it) { for (it = contactPoints.begin(); it != contactPoints.end(); ++it) {
// Create a visual contact point for rendering // 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); mContactPoints.push_back(point);
} }
} }
} }
// Render the contact points // Render the contact points
void SceneDemo::renderContactPoints(openglframework::Shader& shader, void SceneDemo::renderContactPoints(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix) {
const openglframework::Matrix4& worldToCameraMatrix) {
// Render all the raycast hit points // Render all the raycast hit points
for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin(); for (std::vector<VisualContactPoint*>::iterator it = mContactPoints.begin();
it != mContactPoints.end(); ++it) { it != mContactPoints.end(); ++it) {
(*it)->render(shader, worldToCameraMatrix); (*it)->render(mColorShader, worldToCameraMatrix);
} }
} }
@ -335,7 +346,9 @@ std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(const rp3d::Dyn
rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i); rp3d::ContactPoint* contactPoint = manifold->getContactPoint(i);
rp3d::Vector3 point = contactPoint->getWorldPointOnBody1(); 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); contactPoints.push_back(contact);
} }

View File

@ -73,6 +73,9 @@ class SceneDemo : public Scene {
/// Phong shader /// Phong shader
openglframework::Shader mPhongShader; openglframework::Shader mPhongShader;
/// Constant color shader
openglframework::Shader mColorShader;
// TODO : Delete this // TODO : Delete this
openglframework::Shader mQuadShader; openglframework::Shader mQuadShader;