Modify rendering to use OpenGL 3.3

This commit is contained in:
Daniel Chappuis 2015-05-24 17:23:55 +02:00
parent f7f7487304
commit fadedbdb30
32 changed files with 1019 additions and 325 deletions

View File

@ -32,6 +32,7 @@
// Initialize static variables // Initialize static variables
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER); openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
openglframework::VertexArrayObject Box::mVAO;
bool Box::areVBOsCreated = false; bool Box::areVBOsCreated = false;
VertexData Box::mCubeVertices[8] = { 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)},
@ -58,7 +59,7 @@ GLuint Box::mCubeIndices[36] = { 0, 1, 2,
// Constructor // Constructor
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world) reactphysics3d::CollisionWorld* world, openglframework::Shader& shader)
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Initialize the size of the box // Initialize the size of the box
@ -95,8 +96,9 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) { if (!areVBOsCreated) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBO(); createVBOAndVAO(shader);
} }
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -104,7 +106,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
// Constructor // Constructor
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position, Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* world) float mass, reactphysics3d::DynamicsWorld* world, openglframework::Shader& shader)
: openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) { : openglframework::Object3D(), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Initialize the size of the box // Initialize the size of the box
@ -142,7 +144,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
// If the Vertex Buffer object has not been created yet // If the Vertex Buffer object has not been created yet
if (!areVBOsCreated) { if (!areVBOsCreated) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBO(); createVBOAndVAO(shader);
} }
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
@ -151,6 +153,15 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
// Destructor // Destructor
Box::~Box() { Box::~Box() {
if (areVBOsCreated) {
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVAO.destroy();
areVBOsCreated = false;
}
} }
// Render the cube at the correct position and with the correct orientation // Render the cube at the correct position and with the correct orientation
@ -174,33 +185,14 @@ void Box::render(openglframework::Shader& shader,
openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
shader.setVector4Uniform("vertexColor", color); shader.setVector4Uniform("vertexColor", color);
// Bind the vertices VBO // Bind the VAO
mVBOVertices.bind(); mVAO.bind();
// Enable the vertex, normal and color arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
// Set the arrays pointers
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color));
// Bind the indices VBO
mVBOIndices.bind();
// Draw the geometry of the box // Draw the geometry of the box
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL);
// Unbind the VBOs // Unbind the VAO
mVBOVertices.unbind(); mVAO.unbind();
mVBOIndices.unbind();
// Disable the arrays
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -233,15 +225,49 @@ void Box::updateTransform(float interpolationFactor) {
// Create the Vertex Buffer Objects used to render to box with OpenGL. // Create the Vertex Buffer Objects used to render to box with OpenGL.
/// We create two VBOs (one for vertices and one for indices) to render all the boxes /// We create two VBOs (one for vertices and one for indices) to render all the boxes
/// in the simulation. /// in the simulation.
void Box::createVBO() { void Box::createVBOAndVAO(openglframework::Shader& shader) {
// Create the VBOs // Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
// Create the VBO for the vertices data
mVBOVertices.create(); mVBOVertices.create();
mVBOIndices.create(); mVBOVertices.bind();
// Copy the data into the VBOs
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW); mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
mVBOVertices.unbind();
size_t test = sizeof(mCubeVertices);
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW); mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
areVBOsCreated = true; areVBOsCreated = true;
} }

View File

@ -68,6 +68,9 @@ class Box : public openglframework::Object3D {
/// Vertex Buffer Object for the indices used to render the box with OpenGL /// Vertex Buffer Object for the indices used to render the box with OpenGL
static openglframework::VertexBufferObject mVBOIndices; static openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
static openglframework::VertexArrayObject mVAO;
/// Vertex data for each vertex of the cube (used to render the box) /// Vertex data for each vertex of the cube (used to render the box)
static VertexData mCubeVertices[8]; static VertexData mCubeVertices[8];
@ -82,8 +85,8 @@ class Box : public openglframework::Object3D {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Create a Vertex Buffer Object to render to box with OpenGL /// Create a the VAO and VBOs to render to box with OpenGL
static void createVBO(); static void createVBOAndVAO(openglframework::Shader &shader);
public : public :
@ -91,11 +94,11 @@ class Box : public openglframework::Object3D {
/// Constructor /// Constructor
Box(const openglframework::Vector3& size, const openglframework::Vector3& position, Box(const openglframework::Vector3& size, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world); reactphysics3d::CollisionWorld* world, openglframework::Shader &shader);
/// Constructor /// Constructor
Box(const openglframework::Vector3& size, const openglframework::Vector3& position, Box(const openglframework::Vector3& size, const openglframework::Vector3& position,
float mass, reactphysics3d::DynamicsWorld *world); float mass, reactphysics3d::DynamicsWorld *world, openglframework::Shader& shader);
/// Destructor /// Destructor
~Box(); ~Box();

View File

@ -29,8 +29,10 @@
// Constructor // Constructor
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height) { : openglframework::Mesh(), mRadius(radius), mHeight(height), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(1.0f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this);
@ -66,13 +68,19 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
Capsule::Capsule(float radius, float height, const openglframework::Vector3& position, Capsule::Capsule(float radius, float height, const openglframework::Vector3& position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader &shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height) { : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "capsule.obj", *this);
@ -108,6 +116,9 @@ Capsule::Capsule(float radius, float height, const openglframework::Vector3& pos
mRigidBody = body; mRigidBody = body;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -115,6 +126,13 @@ Capsule::~Capsule() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -134,29 +152,20 @@ void Capsule::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -185,3 +194,76 @@ void Capsule::updateTransform(float interpolationFactor) {
// Apply the scaling matrix to have the correct sphere dimensions // Apply the scaling matrix to have the correct sphere dimensions
mTransformMatrix = newMatrix * mScalingMatrix; mTransformMatrix = newMatrix * mScalingMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void Capsule::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -52,20 +52,42 @@ class Capsule : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Capsule(float radius, float height, const openglframework::Vector3& position, Capsule(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath,
openglframework::Shader& shader);
/// Constructor /// Constructor
Capsule(float radius, float height, const openglframework::Vector3& position, Capsule(float radius, float height, const openglframework::Vector3& position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath); const std::string& meshFolderPath, openglframework::Shader& shader);
/// Destructor /// Destructor
~Capsule(); ~Capsule();

View File

@ -29,8 +29,11 @@
// Constructor // Constructor
Cone::Cone(float radius, float height, const openglframework::Vector3 &position, Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height) { : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this);
@ -66,13 +69,19 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
Cone::Cone(float radius, float height, const openglframework::Vector3 &position, Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader &shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height) { : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cone.obj", *this);
@ -108,6 +117,9 @@ Cone::Cone(float radius, float height, const openglframework::Vector3 &position,
mRigidBody = body; mRigidBody = body;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -115,6 +127,13 @@ Cone::~Cone() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the cone at the correct position and with the correct orientation // Render the cone at the correct position and with the correct orientation
@ -134,29 +153,20 @@ void Cone::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -186,3 +196,77 @@ void Cone::updateTransform(float interpolationFactor) {
// Apply the scaling matrix to have the correct cone dimensions // Apply the scaling matrix to have the correct cone dimensions
mTransformMatrix = newMatrix * mScalingMatrix; mTransformMatrix = newMatrix * mScalingMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void Cone::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -52,19 +52,41 @@ class Cone : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Cone(float radius, float height, const openglframework::Vector3& position, Cone(float radius, float height, const openglframework::Vector3& position,
rp3d::CollisionWorld* world, const std::string& meshFolderPath); rp3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader &shader);
/// Constructor /// Constructor
Cone(float radius, float height, const openglframework::Vector3& position, Cone(float radius, float height, const openglframework::Vector3& position,
float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
openglframework::Shader& shader);
/// Destructor /// Destructor
~Cone(); ~Cone();

View File

@ -29,8 +29,11 @@
// Constructor // Constructor
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath,
: openglframework::Mesh() { openglframework::Shader& shader)
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
@ -86,13 +89,18 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
// Add a collision shape to the body and specify the mass of the collision shape // Add a collision shape to the body and specify the mass of the collision shape
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass, ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
reactphysics3d::DynamicsWorld* dynamicsWorld, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader &shader)
: openglframework::Mesh() { : openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "convexmesh.obj", *this);
@ -147,6 +155,9 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass); body->addCollisionShape(collisionShape, rp3d::Transform::identity(), mass);
mRigidBody = body; mRigidBody = body;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -154,6 +165,13 @@ ConvexMesh::~ConvexMesh() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -173,29 +191,20 @@ void ConvexMesh::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -224,3 +233,76 @@ void ConvexMesh::updateTransform(float interpolationFactor) {
// Apply the scaling matrix to have the correct sphere dimensions // Apply the scaling matrix to have the correct sphere dimensions
mTransformMatrix = newMatrix; mTransformMatrix = newMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void ConvexMesh::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -43,19 +43,41 @@ class ConvexMesh : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConvexMesh(const openglframework::Vector3& position, ConvexMesh(const openglframework::Vector3& position,
rp3d::CollisionWorld* world, const std::string& meshFolderPath); rp3d::CollisionWorld* world, const std::string& meshFolderPath, openglframework::Shader &shader);
/// Constructor /// Constructor
ConvexMesh(const openglframework::Vector3& position, float mass, ConvexMesh(const openglframework::Vector3& position, float mass,
rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
openglframework::Shader& shader);
/// Destructor /// Destructor
~ConvexMesh(); ~ConvexMesh();

View File

@ -29,8 +29,12 @@
// Constructor // Constructor
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath,
: openglframework::Mesh(), mRadius(radius), mHeight(height) { openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this);
@ -66,13 +70,19 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position, Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& position,
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld, float mass, reactphysics3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius), mHeight(height) { : openglframework::Mesh(), mRadius(radius), mHeight(height),
mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER),
mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER),
mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cylinder.obj", *this);
@ -108,6 +118,9 @@ Cylinder::Cylinder(float radius, float height, const openglframework::Vector3& p
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
mRigidBody = body; mRigidBody = body;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -115,6 +128,13 @@ Cylinder::~Cylinder() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the cylinder at the correct position and with the correct orientation // Render the cylinder at the correct position and with the correct orientation
@ -134,29 +154,20 @@ void Cylinder::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -185,3 +196,76 @@ void Cylinder::updateTransform(float interpolationFactor) {
// Apply the scaling matrix to have the correct cylinder dimensions // Apply the scaling matrix to have the correct cylinder dimensions
mTransformMatrix = newMatrix * mScalingMatrix; mTransformMatrix = newMatrix * mScalingMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void Cylinder::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -52,19 +52,42 @@ class Cylinder : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Cylinder(float radius, float height, const openglframework::Vector3& position, Cylinder(float radius, float height, const openglframework::Vector3& position,
rp3d::CollisionWorld* world, const std::string &meshFolderPath); rp3d::CollisionWorld* world, const std::string &meshFolderPath,
openglframework::Shader& shader);
/// Constructor /// Constructor
Cylinder(float radius, float height, const openglframework::Vector3& position, Cylinder(float radius, float height, const openglframework::Vector3& position,
float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string &meshFolderPath); float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string &meshFolderPath,
openglframework::Shader &shader);
/// Destructor /// Destructor
~Cylinder(); ~Cylinder();

View File

@ -28,8 +28,11 @@
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) reactphysics3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
: openglframework::Mesh() { openglframework::Shader& shader)
: openglframework::Mesh(),mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -86,12 +89,18 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mBody = body; mBody = body;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
Dumbbell::Dumbbell(const openglframework::Vector3 &position, Dumbbell::Dumbbell(const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath,
: openglframework::Mesh() { openglframework::Shader& shader)
: openglframework::Mesh(), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "dumbbell.obj", *this);
@ -144,6 +153,9 @@ Dumbbell::Dumbbell(const openglframework::Vector3 &position,
mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape); mBody->addCollisionShape(cylinderCollisionShape, transformCylinderShape);
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -151,6 +163,13 @@ Dumbbell::~Dumbbell() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -170,29 +189,20 @@ void Dumbbell::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -222,3 +232,75 @@ void Dumbbell::updateTransform(float interpolationFactor) {
mTransformMatrix = newMatrix * mScalingMatrix; mTransformMatrix = newMatrix * mScalingMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void Dumbbell::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -49,19 +49,40 @@ class Dumbbell : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld, Dumbbell(const openglframework::Vector3& position, rp3d::DynamicsWorld* dynamicsWorld,
const std::string& meshFolderPath); const std::string& meshFolderPath, openglframework::Shader &shader);
/// Constructor /// Constructor
Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world, Dumbbell(const openglframework::Vector3& position, rp3d::CollisionWorld* world,
const std::string& meshFolderPath); const std::string& meshFolderPath, openglframework::Shader& shader);
/// Destructor /// Destructor

View File

@ -29,8 +29,10 @@
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, const openglframework::Vector3 &position,
reactphysics3d::CollisionWorld* world, reactphysics3d::CollisionWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius) { : openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -66,13 +68,18 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity()); mRigidBody->addCollisionShape(collisionShape, rp3d::Transform::identity());
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Constructor // Constructor
Sphere::Sphere(float radius, const openglframework::Vector3 &position, Sphere::Sphere(float radius, const openglframework::Vector3 &position,
float mass, reactphysics3d::DynamicsWorld* world, float mass, reactphysics3d::DynamicsWorld* world,
const std::string& meshFolderPath) const std::string& meshFolderPath, openglframework::Shader& shader)
: openglframework::Mesh(), mRadius(radius) { : openglframework::Mesh(), mRadius(radius), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER), mColor(0.5f, 0.5f, 0.5f, 1.0f) {
// Load the mesh from a file // Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this); openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "sphere.obj", *this);
@ -108,6 +115,9 @@ Sphere::Sphere(float radius, const openglframework::Vector3 &position,
mRigidBody = body; mRigidBody = body;
mTransformMatrix = mTransformMatrix * mScalingMatrix; mTransformMatrix = mTransformMatrix * mScalingMatrix;
// Create the VBOs and VAO
createVBOAndVAO(shader);
} }
// Destructor // Destructor
@ -115,6 +125,13 @@ Sphere::~Sphere() {
// Destroy the mesh // Destroy the mesh
destroy(); destroy();
// Destroy the VBOs and VAO
mVBOIndices.destroy();
mVBOVertices.destroy();
mVBONormals.destroy();
mVBOTextureCoords.destroy();
mVAO.destroy();
} }
// Render the sphere at the correct position and with the correct orientation // Render the sphere at the correct position and with the correct orientation
@ -134,29 +151,20 @@ void Sphere::render(openglframework::Shader& shader,
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix);
glEnableClientState(GL_VERTEX_ARRAY); // Set the vertex color
glEnableClientState(GL_NORMAL_ARRAY); openglframework::Vector4 color(mColor.r, mColor.g, mColor.b, mColor.a);
if (hasTexture()) { shader.setVector4Uniform("vertexColor", color);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glVertexPointer(3, GL_FLOAT, 0, getVerticesPointer()); // Bind the VAO
glNormalPointer(GL_FLOAT, 0, getNormalsPointer()); mVAO.bind();
if(hasTexture()) {
glTexCoordPointer(2, GL_FLOAT, 0, getUVTextureCoordinatesPointer());
}
// For each part of the mesh // For each part of the mesh
for (unsigned int i=0; i<getNbParts(); i++) { for (unsigned int i=0; i<getNbParts(); i++) {
glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, glDrawElements(GL_TRIANGLES, getNbFaces(i) * 3, GL_UNSIGNED_INT, (char*)NULL);
GL_UNSIGNED_INT, getIndicesPointer());
} }
glDisableClientState(GL_NORMAL_ARRAY); // Unbind the VAO
glDisableClientState(GL_VERTEX_ARRAY); mVAO.unbind();
if (hasTexture()) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Unbind the shader // Unbind the shader
shader.unbind(); shader.unbind();
@ -185,3 +193,76 @@ void Sphere::updateTransform(float interpolationFactor) {
// Apply the scaling matrix to have the correct sphere dimensions // Apply the scaling matrix to have the correct sphere dimensions
mTransformMatrix = newMatrix * mScalingMatrix; mTransformMatrix = newMatrix * mScalingMatrix;
} }
// Create the Vertex Buffer Objects used to render with OpenGL.
/// We create two VBOs (one for vertices and one for indices)
void Sphere::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the shader
shader.bind();
// Get the location of shader attribute variables
GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal");
GLint vertexTexCoordLoc = shader.getAttribLocation("textureCoords");
// Create the VBO for the vertices data
mVBOVertices.create();
mVBOVertices.bind();
size_t sizeVertices = mVertices.size() * sizeof(openglframework::Vector3);
mVBOVertices.copyDataIntoVBO(sizeVertices, getVerticesPointer(), GL_STATIC_DRAW);
mVBOVertices.unbind();
// Create the VBO for the normals data
mVBONormals.create();
mVBONormals.bind();
size_t sizeNormals = mNormals.size() * sizeof(openglframework::Vector3);
mVBONormals.copyDataIntoVBO(sizeNormals, getNormalsPointer(), GL_STATIC_DRAW);
mVBONormals.unbind();
if (hasTexture()) {
// Create the VBO for the texture co data
mVBOTextureCoords.create();
mVBOTextureCoords.bind();
size_t sizeTextureCoords = mUVs.size() * sizeof(openglframework::Vector2);
mVBOTextureCoords.copyDataIntoVBO(sizeTextureCoords, getUVTextureCoordinatesPointer(), GL_STATIC_DRAW);
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(uint);
mVBOIndices.copyDataIntoVBO(sizeIndices, getIndicesPointer(), GL_STATIC_DRAW);
mVBOIndices.unbind();
// Create the VAO for both VBOs
mVAO.create();
mVAO.bind();
// Bind the VBO of vertices
mVBOVertices.bind();
glEnableVertexAttribArray(vertexPositionLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
// Bind the VBO of normals
mVBONormals.bind();
glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
if (hasTexture()) {
// Bind the VBO of texture coords
mVBOTextureCoords.bind();
glEnableVertexAttribArray(vertexTexCoordLoc);
glVertexAttribPointer(vertexTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, (char*)NULL);
}
// Bind the VBO of indices
mVBOIndices.bind();
// Unbind the VAO
mVAO.unbind();
// Unbind the shader
shader.unbind();
}

View File

@ -49,19 +49,42 @@ class Sphere : public openglframework::Mesh {
/// Previous transform (for interpolation) /// Previous transform (for interpolation)
rp3d::Transform mPreviousTransform; rp3d::Transform mPreviousTransform;
/// Vertex Buffer Object for the vertices data
openglframework::VertexBufferObject mVBOVertices;
/// Vertex Buffer Object for the normals data
openglframework::VertexBufferObject mVBONormals;
/// Vertex Buffer Object for the texture coords
openglframework::VertexBufferObject mVBOTextureCoords;
/// Vertex Buffer Object for the indices
openglframework::VertexBufferObject mVBOIndices;
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Color
openglframework::Color mColor;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO(openglframework::Shader& shader);
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Sphere(float radius, const openglframework::Vector3& position, Sphere(float radius, const openglframework::Vector3& position,
rp3d::CollisionWorld* world, const std::string& meshFolderPath); rp3d::CollisionWorld* world, const std::string& meshFolderPath,
openglframework::Shader& shader);
/// Constructor /// Constructor
Sphere(float radius, const openglframework::Vector3& position, Sphere(float radius, const openglframework::Vector3& position,
float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath,
openglframework::Shader& shader);
/// Destructor /// Destructor
~Sphere(); ~Sphere();

View File

@ -71,6 +71,8 @@ SET(OPENGL_FRAMEWORK_SOURCES
"src/TextureReaderWriter.cpp" "src/TextureReaderWriter.cpp"
"src/VertexBufferObject.h" "src/VertexBufferObject.h"
"src/VertexBufferObject.cpp" "src/VertexBufferObject.cpp"
"src/VertexArrayObject.h"
"src/VertexArrayObject.cpp"
) )
IF(USE_JPEG_TEXTURES) IF(USE_JPEG_TEXTURES)

View File

@ -112,7 +112,7 @@ bool Shader::create(const std::string vertexShaderFilename,
glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str); glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str);
// Display the log of the compilation // Display the log of the compilation
std::cerr << "Vertex Shader Error : " << str << std::endl; std::cerr << "Vertex Shader Error (in " << vertexShaderFilename << ") : " << str << std::endl;
delete[] str; delete[] str;
assert(false); assert(false);
return false; return false;
@ -165,7 +165,7 @@ bool Shader::create(const std::string vertexShaderFilename,
glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str); glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str);
// Display the log of the compilation // Display the log of the compilation
std::cerr << "Fragment Shader Error : " << str << std::endl; std::cerr << "Fragment Shader Error (in " << fragmentShaderFilename << ") : " << str << std::endl;
delete[] str; delete[] str;
assert(false); assert(false);
return false; return false;

View File

@ -78,7 +78,10 @@ class Shader {
void unbind() const; void unbind() const;
// Return the location of a uniform variable inside a shader program // Return the location of a uniform variable inside a shader program
int getUniformLocation(const std::string& variableName) const; GLint getUniformLocation(const std::string& variableName) const;
// Return the location of an attribute variable inside a shader program
GLint getAttribLocation(const std::string& variableName) const;
// Set a float uniform value to this shader (be careful if the uniform is not // Set a float uniform value to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try // used in the shader, the compiler will remove it, then when you will try
@ -127,6 +130,9 @@ class Shader {
// to set it, an assert will occur) // to set it, an assert will occur)
void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const; void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const;
// Return the shader object program ID
GLuint getProgramObjectId() const;
// Return true if the needed OpenGL extensions are available // Return true if the needed OpenGL extensions are available
static bool checkOpenGLExtensions(); static bool checkOpenGLExtensions();
}; };
@ -144,9 +150,22 @@ inline void Shader::unbind() const {
} }
// Return the location of a uniform variable inside a shader program // Return the location of a uniform variable inside a shader program
inline int Shader::getUniformLocation(const std::string& variableName) const { inline GLint Shader::getUniformLocation(const std::string& variableName) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
int location = glGetUniformLocation(mProgramObjectID, variableName.c_str()); GLint location = glGetUniformLocation(mProgramObjectID, variableName.c_str());
if (location == -1) {
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
<< std::endl;
}
assert(location != -1);
return location;
}
// Return the location of an attribute variable inside a shader program
inline GLint Shader::getAttribLocation(const std::string& variableName) const {
assert(mProgramObjectID != 0);
GLint location = glGetAttribLocation(mProgramObjectID, variableName.c_str());
if (location == -1) { if (location == -1) {
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader" std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName << mFilenameFragmentShader << " : No Uniform variable : " << variableName
@ -248,6 +267,11 @@ inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const M
glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat); glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat);
} }
// Return the shader object program ID
inline GLuint Shader::getProgramObjectId() const {
return mProgramObjectID;
}
// Return true if the needed OpenGL extensions are available for shaders // Return true if the needed OpenGL extensions are available for shaders
inline bool Shader::checkOpenGLExtensions() { inline bool Shader::checkOpenGLExtensions() {

View File

@ -63,14 +63,8 @@ bool VertexBufferObject::create() {
// Copy data into the VBO // Copy data into the VBO
void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) { void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) {
// Bind the VBO
bind();
// Copy the data into the VBO // Copy the data into the VBO
glBufferData(mTargetData, size, data, usage); glBufferData(mTargetData, size, data, usage);
// Unbind the VBO
unbind();
} }
// Destroy the VBO // Destroy the VBO

View File

@ -36,6 +36,7 @@
#include "Texture2D.h" #include "Texture2D.h"
#include "FrameBufferObject.h" #include "FrameBufferObject.h"
#include "VertexBufferObject.h" #include "VertexBufferObject.h"
#include "VertexArrayObject.h"
#include "Shader.h" #include "Shader.h"
#include "maths/Color.h" #include "maths/Color.h"
#include "maths/Vector2.h" #include "maths/Vector2.h"

View File

@ -72,7 +72,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
radius * sin(angle)); radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
Dumbbell* dumbbell = new Dumbbell(position, mDynamicsWorld, meshFolderPath); Dumbbell* dumbbell = new Dumbbell(position, mDynamicsWorld, meshFolderPath,
mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial(); rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -92,7 +93,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
radius * sin(angle)); radius * sin(angle));
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial(); rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -113,7 +114,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create a sphere and a corresponding rigid in the dynamics world // Create a sphere and a corresponding rigid in the dynamics world
Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld, Sphere* sphere = new Sphere(SPHERE_RADIUS, position , BOX_MASS, mDynamicsWorld,
meshFolderPath); meshFolderPath, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial(); rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -134,7 +135,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create a cone and a corresponding rigid in the dynamics world // Create a cone and a corresponding rigid in the dynamics world
Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position, CONE_MASS, mDynamicsWorld, Cone* cone = new Cone(CONE_RADIUS, CONE_HEIGHT, position, CONE_MASS, mDynamicsWorld,
meshFolderPath); meshFolderPath, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = cone->getRigidBody()->getMaterial(); rp3d::Material& material = cone->getRigidBody()->getMaterial();
@ -155,7 +156,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create a cylinder and a corresponding rigid in the dynamics world // Create a cylinder and a corresponding rigid in the dynamics world
Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position , Cylinder* cylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position ,
CYLINDER_MASS, mDynamicsWorld, meshFolderPath); CYLINDER_MASS, mDynamicsWorld, meshFolderPath, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = cylinder->getRigidBody()->getMaterial(); rp3d::Material& material = cylinder->getRigidBody()->getMaterial();
@ -176,7 +177,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create a cylinder and a corresponding rigid in the dynamics world // Create a cylinder and a corresponding rigid in the dynamics world
Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position , Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position ,
CAPSULE_MASS, mDynamicsWorld, meshFolderPath); CAPSULE_MASS, mDynamicsWorld, meshFolderPath,
mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial(); rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -196,7 +198,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
radius * sin(angle)); radius * sin(angle));
// Create a convex mesh and a corresponding rigid in the dynamics world // Create a convex mesh and a corresponding rigid in the dynamics world
ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath); ConvexMesh* mesh = new ConvexMesh(position, MESH_MASS, mDynamicsWorld, meshFolderPath,
mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial(); rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -208,7 +211,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create the floor // Create the floor
openglframework::Vector3 floorPosition(0, 0, 0); openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader);
// The floor must be a static rigid body // The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC); mFloor->getRigidBody()->setType(rp3d::STATIC);

View File

@ -44,11 +44,11 @@ namespace collisionshapesscene {
// Constants // Constants
const int NB_BOXES = 2; const int NB_BOXES = 3;
const int NB_CUBES = 1; const int NB_CUBES = 3;
const int NB_CONES = 3; const int NB_CONES = 3;
const int NB_CYLINDERS = 2; const int NB_CYLINDERS = 3;
const int NB_CAPSULES = 1; const int NB_CAPSULES = 3;
const int NB_MESHES = 2; const int NB_MESHES = 2;
const int NB_COMPOUND_SHAPES = 2; const int NB_COMPOUND_SHAPES = 2;
const openglframework::Vector3 BOX_SIZE(2, 2, 2); const openglframework::Vector3 BOX_SIZE(2, 2, 2);

View File

@ -69,7 +69,7 @@ CubesScene::CubesScene(const std::string& name)
0); 0);
// Create a cube and a corresponding rigid in the dynamics world // Create a cube and a corresponding rigid in the dynamics world
Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld); Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial(); rp3d::Material& material = cube->getRigidBody()->getMaterial();
@ -81,7 +81,7 @@ CubesScene::CubesScene(const std::string& name)
// Create the floor // Create the floor
openglframework::Vector3 floorPosition(0, 0, 0); openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader);
// The floor must be a static rigid body // The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC); mFloor->getRigidBody()->setType(rp3d::STATIC);
@ -150,6 +150,8 @@ void CubesScene::update() {
// Render the scene // Render the scene
void CubesScene::render() { void CubesScene::render() {
checkOpenGLErrors();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@ -170,19 +172,49 @@ void CubesScene::render() {
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 60.0f); mPhongShader.setFloatUniform("shininess", 60.0f);
checkOpenGLErrors();
// Render all the cubes of the scene // Render all the cubes of the scene
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) { for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
(*it)->render(mPhongShader, worldToCameraMatrix); (*it)->render(mPhongShader, worldToCameraMatrix);
} }
checkOpenGLErrors();
// Render the floor // Render the floor
mFloor->render(mPhongShader, worldToCameraMatrix); mFloor->render(mPhongShader, worldToCameraMatrix);
// Unbind the shader // Unbind the shader
mPhongShader.unbind(); mPhongShader.unbind();
checkOpenGLErrors();
} }
// Reset the scene // Reset the scene
void CubesScene::reset() { void CubesScene::reset() {
} }
// Check the OpenGL errors
void CubesScene::checkOpenGLErrors() {
GLenum glError;
// Get the OpenGL errors
glError = glGetError();
// While there are errors
while (glError != GL_NO_ERROR) {
// Get the error string
const GLubyte* stringError = gluErrorString(glError);
// Display the error
if (stringError)
std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << ")" << std::endl;
else
std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl;
// Get the next error
glError = glGetError();
}
}

View File

@ -85,6 +85,9 @@ class CubesScene : public Scene {
/// Reset the scene /// Reset the scene
virtual void reset(); virtual void reset();
// Check the OpenGL errors
static void checkOpenGLErrors();
}; };
} }

View File

@ -202,7 +202,7 @@ void JointsScene::createBallAndSocketJoints() {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass, mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, positionBox , boxMass,
mDynamicsWorld); mDynamicsWorld, mPhongShader);
// The fist box cannot move (static body) // The fist box cannot move (static body)
if (i == 0) { if (i == 0) {
@ -247,7 +247,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box1Dimension(2, 4, 2); openglframework::Vector3 box1Dimension(2, 4, 2);
mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld); mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader);
// The fist box cannot move // The fist box cannot move
mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC);
@ -263,7 +263,7 @@ void JointsScene::createSliderJoint() {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f);
mSliderJointTopBox = new Box(box2Dimension, positionBox2 , BOX_MASS, mDynamicsWorld); mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial(); rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
@ -299,7 +299,7 @@ void JointsScene::createPropellerHingeJoint() {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 boxDimension(10, 1, 1); openglframework::Vector3 boxDimension(10, 1, 1);
mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial(); rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
@ -334,7 +334,7 @@ void JointsScene::createFixedJoints() {
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); openglframework::Vector3 boxDimension(1.5, 1.5, 1.5);
mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld); mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial(); rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
@ -346,7 +346,7 @@ void JointsScene::createFixedJoints() {
openglframework::Vector3 positionBox2(-5, 7, 0); openglframework::Vector3 positionBox2(-5, 7, 0);
// Create a box and a corresponding rigid in the dynamics world // Create a box and a corresponding rigid in the dynamics world
mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld); mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld, mPhongShader);
// Change the material properties of the rigid body // Change the material properties of the rigid body
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial(); rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
@ -381,7 +381,7 @@ void JointsScene::createFloor() {
// Create the floor // Create the floor
openglframework::Vector3 floorPosition(0, 0, 0); openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld, mPhongShader);
// The floor must be a static rigid body // The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC); mFloor->getRigidBody()->setType(rp3d::STATIC);

View File

@ -57,13 +57,13 @@ RaycastScene::RaycastScene(const std::string& name)
openglframework::Vector3 position1(0, 0, 0); openglframework::Vector3 position1(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // Create a convex mesh and a corresponding collision body in the dynamics world
mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath); mDumbbell = new Dumbbell(position1, mCollisionWorld, meshFolderPath, mPhongShader);
// ---------- Box ---------- // // ---------- Box ---------- //
openglframework::Vector3 position2(0, 0, 0); openglframework::Vector3 position2(0, 0, 0);
// Create a box and a corresponding collision body in the dynamics world // Create a box and a corresponding collision body in the dynamics world
mBox = new Box(BOX_SIZE, position2, mCollisionWorld); mBox = new Box(BOX_SIZE, position2, mCollisionWorld, mPhongShader);
mBox->getCollisionBody()->setIsActive(false); mBox->getCollisionBody()->setIsActive(false);
// ---------- Sphere ---------- // // ---------- Sphere ---------- //
@ -71,34 +71,34 @@ RaycastScene::RaycastScene(const std::string& name)
// Create a sphere and a corresponding collision body in the dynamics world // Create a sphere and a corresponding collision body in the dynamics world
mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld, mSphere = new Sphere(SPHERE_RADIUS, position3, mCollisionWorld,
meshFolderPath); meshFolderPath, mPhongShader);
// ---------- Cone ---------- // // ---------- Cone ---------- //
openglframework::Vector3 position4(0, 0, 0); openglframework::Vector3 position4(0, 0, 0);
// Create a cone and a corresponding collision body in the dynamics world // Create a cone and a corresponding collision body in the dynamics world
mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld, mCone = new Cone(CONE_RADIUS, CONE_HEIGHT, position4, mCollisionWorld,
meshFolderPath); meshFolderPath, mPhongShader);
// ---------- Cylinder ---------- // // ---------- Cylinder ---------- //
openglframework::Vector3 position5(0, 0, 0); openglframework::Vector3 position5(0, 0, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // Create a cylinder and a corresponding collision body in the dynamics world
mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5, mCylinder = new Cylinder(CYLINDER_RADIUS, CYLINDER_HEIGHT, position5,
mCollisionWorld, meshFolderPath); mCollisionWorld, meshFolderPath, mPhongShader);
// ---------- Capsule ---------- // // ---------- Capsule ---------- //
openglframework::Vector3 position6(0, 0, 0); openglframework::Vector3 position6(0, 0, 0);
// Create a cylinder and a corresponding collision body in the dynamics world // Create a cylinder and a corresponding collision body in the dynamics world
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 , mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, position6 ,
mCollisionWorld, meshFolderPath); mCollisionWorld, meshFolderPath, mPhongShader);
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
openglframework::Vector3 position7(0, 0, 0); openglframework::Vector3 position7(0, 0, 0);
// Create a convex mesh and a corresponding collision body in the dynamics world // Create a convex mesh and a corresponding collision body in the dynamics world
mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath); mConvexMesh = new ConvexMesh(position7, mCollisionWorld, meshFolderPath, mPhongShader);
// Create the lines that will be used for raycasting // Create the lines that will be used for raycasting
createLines(); createLines();

View File

@ -1,6 +1,6 @@
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2013 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
********************************************************************************* *********************************************************************************
* * * *
* This software is provided 'as-is', without any express or implied warranty. * * This software is provided 'as-is', without any express or implied warranty. *

View File

@ -1,6 +1,6 @@
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2013 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
********************************************************************************* *********************************************************************************
* * * *
* This software is provided 'as-is', without any express or implied warranty. * * This software is provided 'as-is', without any express or implied warranty. *

View File

@ -1,6 +1,8 @@
#version 330
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2013 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
********************************************************************************* *********************************************************************************
* * * *
* This software is provided 'as-is', without any express or implied warranty. * * This software is provided 'as-is', without any express or implied warranty. *
@ -29,14 +31,17 @@ uniform vec3 light0PosCameraSpace; // Camera-space position of the ligh
uniform vec3 light0DiffuseColor; // Light 0 diffuse color uniform vec3 light0DiffuseColor; // Light 0 diffuse color
uniform vec3 light0SpecularColor; // Light 0 specular color uniform vec3 light0SpecularColor; // Light 0 specular color
uniform float shininess; // Shininess uniform float shininess; // Shininess
uniform sampler2D texture; // Texture uniform sampler2D textureSampler; // Texture
uniform bool isTexture; // True if we need to use the texture uniform bool isTexture; // True if we need to use the texture
uniform vec4 vertexColor; // Vertex color uniform vec4 vertexColor; // Vertex color
// Varying variables // In variables
varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
varying vec2 texCoords; // Texture coordinates in vec2 texCoords; // Texture coordinates
// Out variable
out vec4 color; // Output color
void main() { void main() {
@ -45,7 +50,7 @@ void main() {
// Get the texture color // Get the texture color
vec3 textureColor = vertexColor.rgb; vec3 textureColor = vertexColor.rgb;
if (isTexture) textureColor = texture2D(texture, texCoords).rgb; if (isTexture) textureColor = texture(textureSampler, texCoords).rgb;
// Compute the surface normal vector // Compute the surface normal vector
vec3 N = normalize(vertexNormalCameraSpace); vec3 N = normalize(vertexNormalCameraSpace);
@ -63,5 +68,5 @@ void main() {
vec3 specular = light0SpecularColor * specularFactor; vec3 specular = light0SpecularColor * specularFactor;
// Compute the final color // Compute the final color
gl_FragColor = vec4(ambient + diffuse + specular, 1.0); color = vec4(ambient + diffuse + specular, 1.0);
} }

View File

@ -1,6 +1,8 @@
#version 330
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2013 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
********************************************************************************* *********************************************************************************
* * * *
* This software is provided 'as-is', without any express or implied warranty. * * This software is provided 'as-is', without any express or implied warranty. *
@ -28,22 +30,27 @@ uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix
uniform mat4 projectionMatrix; // Projection matrix uniform mat4 projectionMatrix; // Projection matrix
uniform mat3 normalMatrix; // Normal matrix uniform mat3 normalMatrix; // Normal matrix
// Varying variables // In variables
varying vec3 vertexPosCameraSpace; // Camera-space position of the vertex in vec4 vertexPosition;
varying vec3 vertexNormalCameraSpace; // Vertex normal in camera-space in vec3 vertexNormal;
varying vec2 texCoords; // Texture coordinates in vec2 textureCoords;
// Out variables
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
out vec2 texCoords; // Texture coordinates
void main() { void main() {
// Compute the vertex position // Compute the vertex position
vec4 positionCameraSpace = localToCameraMatrix * gl_Vertex; vec4 positionCameraSpace = localToCameraMatrix * vertexPosition;
vertexPosCameraSpace = positionCameraSpace.xyz; vertexPosCameraSpace = positionCameraSpace.xyz;
// Compute the world surface normal // Compute the world surface normal
vertexNormalCameraSpace = normalMatrix * gl_Normal; vertexNormalCameraSpace = normalMatrix * vertexNormal;
// Get the texture coordinates // Get the texture coordinates
texCoords = gl_MultiTexCoord0.xy; texCoords = textureCoords;
// Compute the clip-space vertex coordinates // Compute the clip-space vertex coordinates
gl_Position = projectionMatrix * positionCameraSpace; gl_Position = projectionMatrix * positionCameraSpace;

View File

@ -32,17 +32,12 @@ double Gui::g_Time = 0.0f;
bool Gui::g_MousePressed[3] = {false, false, false}; bool Gui::g_MousePressed[3] = {false, false, false};
float Gui::g_MouseWheel = 0.0f; float Gui::g_MouseWheel = 0.0f;
GLuint Gui::g_FontTexture = 0; GLuint Gui::g_FontTexture = 0;
int Gui::g_ShaderHandle = 0;
int Gui::g_VertHandle = 0;
int Gui::g_FragHandle = 0;
int Gui::g_AttribLocationTex = 0;
int Gui::g_AttribLocationProjMtx = 0;
int Gui::g_AttribLocationPosition = 0;
int Gui::g_AttribLocationUV = 0;
int Gui::g_AttribLocationColor = 0;
size_t Gui::g_VboSize = 0; size_t Gui::g_VboSize = 0;
unsigned int Gui::g_VboHandle = 0; unsigned int Gui::g_VboHandle = 0;
unsigned int Gui::g_VaoHandle = 0; unsigned int Gui::g_VaoHandle = 0;
int Gui::g_AttribLocationTex = 0, Gui::g_AttribLocationProjMtx = 0;
int Gui::g_AttribLocationPosition = 0, Gui::g_AttribLocationUV = 0, Gui::g_AttribLocationColor = 0;
Shader Gui::mShader;
// Constructor // Constructor
Gui::Gui() { Gui::Gui() {
@ -52,9 +47,6 @@ Gui::Gui() {
g_MousePressed[2] = false; g_MousePressed[2] = false;
g_MouseWheel = 0.0f; g_MouseWheel = 0.0f;
g_FontTexture = 0; g_FontTexture = 0;
g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
g_VboSize = 0; g_VboSize = 0;
g_VboHandle = 0, g_VaoHandle = 0; g_VboHandle = 0, g_VaoHandle = 0;
} }
@ -67,16 +59,7 @@ Gui::~Gui() {
g_VaoHandle = 0; g_VaoHandle = 0;
g_VboHandle = 0; g_VboHandle = 0;
glDetachShader(g_ShaderHandle, g_VertHandle); mShader.destroy();
glDeleteShader(g_VertHandle);
g_VertHandle = 0;
glDetachShader(g_ShaderHandle, g_FragHandle);
glDeleteShader(g_FragHandle);
g_FragHandle = 0;
glDeleteProgram(g_ShaderHandle);
g_ShaderHandle = 0;
if (g_FontTexture) if (g_FontTexture)
{ {
@ -122,48 +105,15 @@ void Gui::init() {
void Gui::createDeviceObjects() { void Gui::createDeviceObjects() {
const GLchar *vertex_shader = /*
"#version 330\n" mShader.create("shaders/gui.vert", "shaders/gui.frag");
"uniform mat4 ProjMtx;\n"
"in vec2 Position;\n"
"in vec2 UV;\n"
"in vec4 Color;\n"
"out vec2 Frag_UV;\n"
"out vec4 Frag_Color;\n"
"void main()\n"
"{\n"
" Frag_UV = UV;\n"
" Frag_Color = Color;\n"
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
"}\n";
const GLchar* fragment_shader = GLuint shaderID = mShader.getProgramObjectId();
"#version 330\n" g_AttribLocationTex = glGetUniformLocation(shaderID, "Texture");
"uniform sampler2D Texture;\n" g_AttribLocationProjMtx = glGetUniformLocation(shaderID, "ProjMtx");
"in vec2 Frag_UV;\n" g_AttribLocationPosition = glGetAttribLocation(shaderID, "Position");
"in vec4 Frag_Color;\n" g_AttribLocationUV = glGetAttribLocation(shaderID, "UV");
"out vec4 Out_Color;\n" g_AttribLocationColor = glGetAttribLocation(shaderID, "Color");
"void main()\n"
"{\n"
" Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n"
"}\n";
g_ShaderHandle = glCreateProgram();
g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(g_VertHandle, 1, &vertex_shader, 0);
glShaderSource(g_FragHandle, 1, &fragment_shader, 0);
glCompileShader(g_VertHandle);
glCompileShader(g_FragHandle);
glAttachShader(g_ShaderHandle, g_VertHandle);
glAttachShader(g_ShaderHandle, g_FragHandle);
glLinkProgram(g_ShaderHandle);
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_VboHandle);
@ -173,7 +123,6 @@ void Gui::createDeviceObjects() {
glEnableVertexAttribArray(g_AttribLocationPosition); glEnableVertexAttribArray(g_AttribLocationPosition);
glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationUV);
glEnableVertexAttribArray(g_AttribLocationColor); glEnableVertexAttribArray(g_AttribLocationColor);
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
@ -183,56 +132,41 @@ void Gui::createDeviceObjects() {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
createFontTextures(); createFontTextures();
*/
} }
// Display the GUI // Display the GUI
void Gui::render() { void Gui::render() {
/*
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
//glfwPollEvents(); //glfwPollEvents();
beginNewFrame(); beginNewFrame();
bool show_test_window = true; bool show_test_window = true;
bool show_another_window = false; bool show_another_window = false;
ImVec4 clear_color = ImColor(114, 144, 154); ImVec4 clear_color = ImColor(255, 255, 255);
// 1. Show a simple window // 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{ {
static float f = 0.0f;
ImGui::Text("Hello, world!"); ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::ColorEdit3("clear color", (float*)&clear_color);
if (ImGui::Button("Test Window")) int test = 1;
if (ImGui::Button("Another Window")) int test = 1;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
} }
// 2. Show another simple window, this time using an explicit Begin/End pair
//if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
//if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
// Render the GUI // Render the GUI
ImGui::Render(); ImGui::Render();
*/
} }
void Gui::beginNewFrame() { void Gui::beginNewFrame() {
/*
if (!g_FontTexture) if (!g_FontTexture)
createDeviceObjects(); createDeviceObjects();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing) // Setup display size (every frame to accommodate for window resizing)
@ -276,6 +210,7 @@ void Gui::beginNewFrame() {
// Start the frame // Start the frame
ImGui::NewFrame(); ImGui::NewFrame();
*/
} }
void Gui::createFontTextures() void Gui::createFontTextures()
@ -301,6 +236,7 @@ void Gui::createFontTextures()
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{ {
std::cout << "OpenGLVersion : " << glGetString(GL_VERSION) << std::endl;
if (cmd_lists_count == 0) if (cmd_lists_count == 0)
return; return;
@ -316,9 +252,14 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
/*
// Setup orthographic projection matrix // Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x; const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y; const float height = ImGui::GetIO().DisplaySize.y;
Matrix4 orthoProj(2.0f / width, 0.0f, 0.0f, 0.0f,
0.0f, 2.0/-height, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f);
const float ortho_projection[4][4] = const float ortho_projection[4][4] =
{ {
{ 2.0f/width, 0.0f, 0.0f, 0.0f }, { 2.0f/width, 0.0f, 0.0f, 0.0f },
@ -326,7 +267,11 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{ 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f },
{ -1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.0f, 1.0f },
}; };
glUseProgram(g_ShaderHandle);
mShader.bind();
//mShader.setIntUniform("Texture", 0);
//mShader.setMatrix4x4Uniform("ProjMtx", orthoProj);
///glUseProgram(g_ShaderHandle);
glUniform1i(g_AttribLocationTex, 0); glUniform1i(g_AttribLocationTex, 0);
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
@ -379,11 +324,14 @@ void Gui::renderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
cmd_offset = vtx_offset; cmd_offset = vtx_offset;
} }
// Restore modified state // Restore modified state
glBindVertexArray(0); glBindVertexArray(0);
glUseProgram(last_program); glUseProgram(last_program);
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
*/
} }
const char* Gui::getClipboardText() { const char* Gui::getClipboardText() {

View File

@ -30,6 +30,9 @@
#include <imgui.h> #include <imgui.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "openglframework.h"
using namespace openglframework;
// Class Gui // Class Gui
class Gui { class Gui {
@ -44,11 +47,13 @@ class Gui {
// TODO : Delete this // TODO : Delete this
static GLFWwindow* mWindow; static GLFWwindow* mWindow;
static Shader mShader;
static double g_Time; static double g_Time;
static bool g_MousePressed[3]; static bool g_MousePressed[3];
static float g_MouseWheel; static float g_MouseWheel;
static GLuint g_FontTexture; static GLuint g_FontTexture;
static int g_ShaderHandle, g_VertHandle, g_FragHandle; //static int g_ShaderHandle, g_VertHandle, g_FragHandle;
static int g_AttribLocationTex, g_AttribLocationProjMtx; static int g_AttribLocationTex, g_AttribLocationProjMtx;
static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor; static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor;
static size_t g_VboSize; static size_t g_VboSize;

View File

@ -55,8 +55,8 @@ TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(
mCurrentScene = NULL; mCurrentScene = NULL;
mEngineSettings.timeStep = DEFAULT_TIMESTEP; mEngineSettings.timeStep = DEFAULT_TIMESTEP;
mIsMultisamplingActive = true; mIsMultisamplingActive = true;
mWidth = 1000; mWidth = 1280;
mHeight = 800; mHeight = 720;
} }
// Destructor // Destructor
@ -85,6 +85,12 @@ void TestbedApplication::init() {
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
// OpenGL version required
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Active the multi-sampling by default // Active the multi-sampling by default
if (mIsMultisamplingActive) { if (mIsMultisamplingActive) {
glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_SAMPLES, 4);
@ -131,7 +137,7 @@ void TestbedApplication::init() {
Gui::getInstance().setWindow(mWindow); Gui::getInstance().setWindow(mWindow);
// Init the GUI // Init the GUI
Gui::getInstance().init(); //Gui::getInstance().init();
mTimer.start(); mTimer.start();
} }
@ -143,20 +149,24 @@ void TestbedApplication::createScenes() {
CubesScene* cubeScene = new CubesScene("Cubes"); CubesScene* cubeScene = new CubesScene("Cubes");
mScenes.push_back(cubeScene); mScenes.push_back(cubeScene);
/*
// Joints scene // Joints scene
JointsScene* jointsScene = new JointsScene("Joints"); JointsScene* jointsScene = new JointsScene("Joints");
mScenes.push_back(jointsScene); mScenes.push_back(jointsScene);
*/
// Collision shapes scene // Collision shapes scene
CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes"); CollisionShapesScene* collisionShapesScene = new CollisionShapesScene("Collision Shapes");
mScenes.push_back(collisionShapesScene); mScenes.push_back(collisionShapesScene);
/*
// Raycast scene // Raycast scene
RaycastScene* raycastScene = new RaycastScene("Raycast"); RaycastScene* raycastScene = new RaycastScene("Raycast");
mScenes.push_back(raycastScene); mScenes.push_back(raycastScene);
*/
assert(mScenes.size() > 0); assert(mScenes.size() > 0);
mCurrentScene = mScenes[0]; mCurrentScene = mScenes[1];
} }
// Remove all the scenes // Remove all the scenes
@ -201,7 +211,6 @@ void TestbedApplication::update() {
// Compute the interpolation factor // Compute the interpolation factor
float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep);
assert(factor >= 0.0f && factor <= 1.0f); assert(factor >= 0.0f && factor <= 1.0f);
std::cout << "Factor : " << factor << std::endl;
// Notify the scene about the interpolation factor // Notify the scene about the interpolation factor
mCurrentScene->setInterpolationFactor(factor); mCurrentScene->setInterpolationFactor(factor);
@ -220,7 +229,7 @@ void TestbedApplication::render() {
mCurrentScene->render(); mCurrentScene->render();
// Display the GUI // Display the GUI
Gui::getInstance().render(); //Gui::getInstance().render();
// Check the OpenGL errors // Check the OpenGL errors
checkOpenGLErrors(); checkOpenGLErrors();
@ -251,6 +260,8 @@ void TestbedApplication::startMainLoop() {
// Loop until the user closes the window // Loop until the user closes the window
while (!glfwWindowShouldClose(mWindow)) { while (!glfwWindowShouldClose(mWindow)) {
checkOpenGLErrors();
// Reshape the viewport // Reshape the viewport
reshape(); reshape();
@ -265,6 +276,8 @@ void TestbedApplication::startMainLoop() {
// Process events // Process events
glfwPollEvents(); glfwPollEvents();
checkOpenGLErrors();
} }
} }
@ -283,7 +296,7 @@ void TestbedApplication::checkOpenGLErrors() {
// Display the error // Display the error
if (stringError) if (stringError)
std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << std::endl; std::cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << ")" << std::endl;
else else
std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl; std::cerr << "OpenGL Error #" << glError << " (no message available)" << std::endl;