Start working on shadow mapping

This commit is contained in:
Daniel Chappuis 2015-07-21 23:18:32 +00:00
parent 58992169e7
commit cec1ac7937
17 changed files with 383 additions and 149 deletions

View File

@ -39,6 +39,8 @@ SET(TESTBED_SOURCES
src/Gui.cpp src/Gui.cpp
src/Scene.h src/Scene.h
src/Scene.cpp src/Scene.cpp
src/SceneDemo.h
src/SceneDemo.cpp
src/Timer.h src/Timer.h
src/Timer.cpp src/Timer.cpp
) )

View File

@ -59,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, openglframework::Shader& shader) reactphysics3d::CollisionWorld* world)
: openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) {
// Initialize the size of the box // Initialize the size of the box
@ -98,7 +98,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
if (totalNbBoxes == 0) { if (totalNbBoxes == 0) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBOAndVAO(shader); createVBOAndVAO();
} }
totalNbBoxes++; totalNbBoxes++;
@ -108,7 +108,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, openglframework::Shader& shader) float mass, reactphysics3d::DynamicsWorld* world)
: openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) { : openglframework::Object3D(), mColor(0.01f, 0.62f, 0.39f, 1.0f) {
// Initialize the size of the box // Initialize the size of the box
@ -147,7 +147,7 @@ Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &p
if (totalNbBoxes == 0) { if (totalNbBoxes == 0) {
// Create the Vertex Buffer // Create the Vertex Buffer
createVBOAndVAO(shader); createVBOAndVAO();
} }
totalNbBoxes++; totalNbBoxes++;
@ -173,9 +173,14 @@ Box::~Box() {
void Box::render(openglframework::Shader& shader, void Box::render(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix) { const openglframework::Matrix4& worldToCameraMatrix) {
// Bind the VAO
mVAO.bind();
// Bind the shader // Bind the shader
shader.bind(); shader.bind();
mVBOVertices.bind();
// Set the model to camera matrix // Set the model to camera matrix
const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix;
shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix);
@ -184,18 +189,30 @@ void Box::render(openglframework::Shader& shader,
// model-view matrix) // model-view matrix)
const openglframework::Matrix3 normalMatrix = const openglframework::Matrix3 normalMatrix =
localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose();
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color // Set the vertex color
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, false);
// Bind the VAO // Get the location of shader attribute variables
mVAO.bind(); GLint vertexPositionLoc = shader.getAttribLocation("vertexPosition");
GLint vertexNormalLoc = shader.getAttribLocation("vertexNormal", false);
glEnableVertexAttribArray(vertexPositionLoc);
if (vertexNormalLoc != -1) glEnableVertexAttribArray(vertexNormalLoc);
glVertexAttribPointer(vertexPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
if (vertexNormalLoc != -1) glVertexAttribPointer(vertexNormalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
// 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);
glDisableVertexAttribArray(vertexPositionLoc);
if (vertexNormalLoc != -1) glDisableVertexAttribArray(vertexNormalLoc);
mVBOVertices.unbind();
// Unbind the VAO // Unbind the VAO
mVAO.unbind(); mVAO.unbind();
@ -230,14 +247,7 @@ 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::createVBOAndVAO(openglframework::Shader& shader) { void Box::createVBOAndVAO() {
// 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 // Create the VBO for the vertices data
mVBOVertices.create(); mVBOVertices.create();
@ -258,20 +268,11 @@ void Box::createVBOAndVAO(openglframework::Shader& shader) {
// Bind the VBO of vertices // Bind the VBO of vertices
mVBOVertices.bind(); 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 // Bind the VBO of indices
mVBOIndices.bind(); mVBOIndices.bind();
// Unbind the VAO // Unbind the VAO
mVAO.unbind(); mVAO.unbind();
// Unbind the shader
shader.unbind();
} }
// Reset the transform // Reset the transform

View File

@ -86,7 +86,7 @@ class Box : public openglframework::Object3D {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Create a the VAO and VBOs to render to box with OpenGL /// Create a the VAO and VBOs to render to box with OpenGL
static void createVBOAndVAO(openglframework::Shader &shader); static void createVBOAndVAO();
public : public :
@ -94,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, openglframework::Shader &shader); reactphysics3d::CollisionWorld* world);
/// 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, openglframework::Shader& shader); float mass, reactphysics3d::DynamicsWorld *world);
/// Destructor /// Destructor
~Box(); ~Box();

View File

@ -34,6 +34,7 @@
#include "maths/Vector4.h" #include "maths/Vector4.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <exception>
#include <GL/glew.h> #include <GL/glew.h>
namespace openglframework { namespace openglframework {
@ -78,57 +79,57 @@ 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
GLint getUniformLocation(const std::string& variableName) const; GLint getUniformLocation(const std::string& variableName, bool errorIfMissing = true) const;
// Return the location of an attribute variable inside a shader program // Return the location of an attribute variable inside a shader program
GLint getAttribLocation(const std::string& variableName) const; GLint getAttribLocation(const std::string& variableName, bool errorIfMissing = true) 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setFloatUniform(const std::string& variableName, float value) const; void setFloatUniform(const std::string& variableName, float value, bool errorIfMissing = true) const;
// Set an int uniform value to this shader (be careful if the uniform is not // Set an int 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setIntUniform(const std::string& variableName, int value) const; void setIntUniform(const std::string& variableName, int value, bool errorIfMissing = true) const;
// Set a vector 2 uniform value to this shader (be careful if the uniform is not // Set a vector 2 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setVector2Uniform(const std::string& variableName, const Vector2& v) const; void setVector2Uniform(const std::string& variableName, const Vector2& v, bool errorIfMissing = true) const;
// Set a vector 3 uniform value to this shader (be careful if the uniform is not // Set a vector 3 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setVector3Uniform(const std::string& variableName, const Vector3& v) const; void setVector3Uniform(const std::string& variableName, const Vector3& v, bool errorIfMissing = true) const;
// Set a vector 4 uniform value to this shader (be careful if the uniform is not // Set a vector 4 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setVector4Uniform(const std::string& variableName, const Vector4 &v) const; void setVector4Uniform(const std::string& variableName, const Vector4 &v, bool errorIfMissing = true) const;
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // Set a 3x3 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setMatrix3x3Uniform(const std::string& variableName, const float* matrix, void setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
bool transpose = false) const; bool transpose = false, bool errorIfMissing = true) const;
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // Set a 3x3 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const; void setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix, bool errorIfMissing = true) const;
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // Set a 4x4 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
void setMatrix4x4Uniform(const std::string& variableName, const float* matrix, void setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
bool transpose = false) const; bool transpose = false, bool errorIfMissing = true) const;
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // Set a 4x4 matrix 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
// 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, bool errorIfMissing = true) const;
// Return the shader object program ID // Return the shader object program ID
GLuint getProgramObjectId() const; GLuint getProgramObjectId() const;
@ -150,28 +151,30 @@ 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 GLint Shader::getUniformLocation(const std::string& variableName) const { inline GLint Shader::getUniformLocation(const std::string& variableName, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
GLint location = glGetUniformLocation(mProgramObjectID, variableName.c_str()); GLint location = glGetUniformLocation(mProgramObjectID, variableName.c_str());
if (location == -1) { if (location == -1 && errorIfMissing) {
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
<< std::endl; << std::endl;
throw std::logic_error("Error in Shader");
} }
assert(location != -1);
return location; return location;
} }
// Return the location of an attribute variable inside a shader program // Return the location of an attribute variable inside a shader program
inline GLint Shader::getAttribLocation(const std::string& variableName) const { inline GLint Shader::getAttribLocation(const std::string& variableName, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
GLint location = glGetAttribLocation(mProgramObjectID, variableName.c_str()); GLint location = glGetAttribLocation(mProgramObjectID, variableName.c_str());
if (location == -1) { if (location == -1 && errorIfMissing) {
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
<< std::endl; << std::endl;
throw std::logic_error("Error in Shader");
} }
assert(location != -1);
return location; return location;
} }
@ -184,56 +187,74 @@ inline void Shader::destroy() {
// 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setFloatUniform(const std::string& variableName, float value) const { inline void Shader::setFloatUniform(const std::string& variableName, float value, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniform1f(getUniformLocation(variableName), value); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform1f(location, value);
}
} }
// Set an int uniform value to this shader (be careful if the uniform is not // Set an int 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setIntUniform(const std::string& variableName, int value) const { inline void Shader::setIntUniform(const std::string& variableName, int value, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniform1i(getUniformLocation(variableName), value); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform1i(location, value);
}
} }
// Set a vector 2 uniform value to this shader (be careful if the uniform is not // Set a vector 2 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const { inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniform2f(getUniformLocation(variableName), v.x, v.y); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform2f(location, v.x, v.y);
}
} }
// Set a vector 3 uniform value to this shader (be careful if the uniform is not // Set a vector 3 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const { inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform3f(location, v.x, v.y, v.z);
}
} }
// Set a vector 4 uniform value to this shader (be careful if the uniform is not // Set a vector 4 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const { inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform4f(location, v.x, v.y, v.z, v.w);
}
} }
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // Set a 4x4 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix, inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
bool transpose) const { bool transpose, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniformMatrix3fv(location, 1, transpose, matrix);
}
} }
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not // Set a 3x3 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix) const { inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const Matrix3& matrix, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
GLfloat mat[9]; GLfloat mat[9];
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
@ -241,22 +262,28 @@ inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const M
mat[i*3 + j] = matrix.getValue(i, j); mat[i*3 + j] = matrix.getValue(i, j);
} }
} }
glUniformMatrix3fv(getUniformLocation(variableName), 1, true, mat); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniformMatrix3fv(location, 1, true, mat);
}
} }
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // Set a 4x4 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix, inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
bool transpose) const { bool transpose, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniformMatrix4fv(location, 1, transpose, matrix);
}
} }
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not // Set a 4x4 matrix 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
// to set it, an assert will occur) // to set it, an assert will occur)
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const { inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix, bool errorIfMissing) const {
assert(mProgramObjectID != 0); assert(mProgramObjectID != 0);
GLfloat mat[16]; GLfloat mat[16];
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
@ -264,7 +291,10 @@ inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const M
mat[i*4 + j] = matrix.m[i][j]; mat[i*4 + j] = matrix.m[i][j];
} }
} }
glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat); GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniformMatrix4fv(location, 1, true, mat);
}
} }
// Return the shader object program ID // Return the shader object program ID

View File

@ -72,6 +72,28 @@ void Texture2D::create(uint width, uint height, uint internalFormat, uint format
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
// Create the texture
void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type,
uint minFilter, uint maxFilter, uint wrapS, uint wrapT, void* data) {
// Destroy the current texture
destroy();
mWidth = width;
mHeight = height;
// Create the OpenGL texture
glGenTextures(1, &mID);
assert(mID != 0);
glBindTexture(GL_TEXTURE_2D, mID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data);
glBindTexture(GL_TEXTURE_2D, 0);
}
// Destroy the texture // Destroy the texture
void Texture2D::destroy() { void Texture2D::destroy() {
if (mID != 0) { if (mID != 0) {

View File

@ -71,6 +71,10 @@ class Texture2D {
void create(uint width, uint height, uint internalFormat, uint format, uint type, void create(uint width, uint height, uint internalFormat, uint format, uint type,
void* data = NULL); void* data = NULL);
// Create the texture
void create(uint width, uint height, uint internalFormat, uint format, uint type,
uint minFilter, uint maxFilter, uint wrapS, uint wrapT, void* data);
// Destroy the texture // Destroy the texture
void destroy(); void destroy();

View File

@ -90,7 +90,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, mPhongShader); Box* box = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld);
// 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();
@ -208,7 +208,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, mPhongShader); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
// 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

@ -32,18 +32,13 @@ using namespace cubesscene;
// Constructor // Constructor
CubesScene::CubesScene(const std::string& name) CubesScene::CubesScene(const std::string& name)
: Scene(name), mLight0(0), : SceneDemo(name, SCENE_RADIUS) {
mPhongShader("shaders/phong.vert", "shaders/phong.frag") {
// Move the light 0
mLight0.translateWorld(Vector3(7, 15, 15));
// Compute the radius and the center of the scene // Compute the radius and the center of the scene
float radiusScene = 30.0f;
openglframework::Vector3 center(0, 5, 0); openglframework::Vector3 center(0, 5, 0);
// Set the center of the scene // Set the center of the scene
setScenePosition(center, radiusScene); setScenePosition(center, SCENE_RADIUS);
// Gravity vector in the dynamics world // Gravity vector in the dynamics world
rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0); rp3d::Vector3 gravity(0, rp3d::decimal(-5.81), 0);
@ -69,7 +64,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, mPhongShader); Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld);
// 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 +76,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, mPhongShader); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
// 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);
@ -171,39 +166,25 @@ void CubesScene::update() {
} }
} }
// Render the scene // Render the scene in a single pass
void CubesScene::render() { void CubesScene::renderSinglePass(Shader& shader) {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
// Get the world-space to camera-space matrix // Get the world-space to camera-space matrix
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// Bind the shader // Bind the shader
mPhongShader.bind(); shader.bind();
// Set the variables of the shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
const Color& diffCol = mLight0.getDiffuseColor();
const Color& specCol = mLight0.getSpecularColor();
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 60.0f);
// 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(shader, worldToCameraMatrix);
} }
// Render the floor // Render the floor
mFloor->render(mPhongShader, worldToCameraMatrix); mFloor->render(shader, worldToCameraMatrix);
// Unbind the shader // Unbind the shader
mPhongShader.unbind(); shader.unbind();
} }
// Reset the scene // Reset the scene

View File

@ -30,11 +30,12 @@
#include "openglframework.h" #include "openglframework.h"
#include "reactphysics3d.h" #include "reactphysics3d.h"
#include "Box.h" #include "Box.h"
#include "Scene.h" #include "SceneDemo.h"
namespace cubesscene { namespace cubesscene {
// Constants // Constants
const float SCENE_RADIUS = 30.0f; // Radius of the scene in meters
const int NB_CUBES = 20; // Number of boxes in the scene const int NB_CUBES = 20; // Number of boxes in the scene
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters
@ -42,18 +43,12 @@ const float BOX_MASS = 1.0f; // Box mass in kilogr
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
// Class CubesScene // Class CubesScene
class CubesScene : public Scene { class CubesScene : public SceneDemo {
protected : protected :
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Light 0
openglframework::Light mLight0;
/// Phong shader
openglframework::Shader mPhongShader;
/// All the boxes of the scene /// All the boxes of the scene
std::vector<Box*> mBoxes; std::vector<Box*> mBoxes;
@ -80,8 +75,8 @@ class CubesScene : public Scene {
/// Update the scene (take a simulation step) /// Update the scene (take a simulation step)
virtual void update(); virtual void update();
/// Render the scene /// Render the scene in a single pass
virtual void render(); virtual void renderSinglePass(openglframework::Shader& shader);
/// Reset the scene /// Reset the scene
virtual void reset(); virtual void reset();

View File

@ -291,7 +291,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, mPhongShader); mDynamicsWorld);
// The fist box cannot move (static body) // The fist box cannot move (static body)
if (i == 0) { if (i == 0) {
@ -336,7 +336,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, mPhongShader); mSliderJointBottomBox = new Box(box1Dimension, positionBox1 , BOX_MASS, mDynamicsWorld);
// The fist box cannot move // The fist box cannot move
mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC); mSliderJointBottomBox->getRigidBody()->setType(rp3d::STATIC);
@ -352,7 +352,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, mPhongShader); mSliderJointTopBox = new Box(box2Dimension, positionBox2, BOX_MASS, mDynamicsWorld);
// 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();
@ -388,7 +388,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, mPhongShader); mPropellerBox = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld);
// 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();
@ -423,7 +423,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, mPhongShader); mFixedJointBox1 = new Box(boxDimension, positionBox1 , BOX_MASS, mDynamicsWorld);
// 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();
@ -435,7 +435,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, mPhongShader); mFixedJointBox2 = new Box(boxDimension, positionBox2 , BOX_MASS, mDynamicsWorld);
// 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();
@ -470,7 +470,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, mPhongShader); mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
// 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

@ -60,7 +60,7 @@ RaycastScene::RaycastScene(const std::string& name)
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, mPhongShader); mBox = new Box(BOX_SIZE, position2, mCollisionWorld);
mBox->getCollisionBody()->setIsActive(false); mBox->getCollisionBody()->setIsActive(false);
// ---------- Sphere ---------- // // ---------- Sphere ---------- //

View File

@ -1,3 +1,5 @@
#version 330
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
@ -23,10 +25,11 @@
* * * *
********************************************************************************/ ********************************************************************************/
void main(void) { // Out variable
out vec4 color; // Output color
// Compute the depth of the pixel void main() {
float depth =
gl_FragColor = vec4(depth, depth, depth, 1); // Compute the final color
color = vec4(1, 1, 1, 1);
} }

View File

@ -1,3 +1,5 @@
#version 330
/******************************************************************************** /********************************************************************************
* OpenGL-Framework * * OpenGL-Framework *
* Copyright (c) 2015 Daniel Chappuis * * Copyright (c) 2015 Daniel Chappuis *
@ -24,13 +26,14 @@
********************************************************************************/ ********************************************************************************/
// Uniform variables // Uniform variables
uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix
uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix
uniform mat4 projectionMatrix; // Projection matrix uniform mat4 projectionMatrix; // Projection matrix
void main(void) { // In variables
in vec4 vertexPosition;
void main() {
// Compute the clip-space vertex coordinates // Compute the clip-space vertex coordinates
gl_Position = projectionMatrix * worldToCameraMatrix * gl_Position = projectionMatrix * localToCameraMatrix * vertexPosition;
modelToWorldMatrix * gl_Vertex;
} }

View File

@ -1,10 +0,0 @@
#version 330
uniform sampler2D Texture;
in vec2 Frag_UV;
in vec4 Frag_Color;
out vec4 Out_Color;
void main()
{
Out_Color = Frag_Color * texture( Texture, Frag_UV.st);
}

View File

@ -1,15 +0,0 @@
#version 330
uniform mat4 ProjMtx;
in vec2 Position;
in vec2 UV;
in vec4 Color;
out vec2 Frag_UV;
out vec4 Frag_Color;
void main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy,0,1);
}

124
testbed/src/SceneDemo.cpp Normal file
View File

@ -0,0 +1,124 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "SceneDemo.h"
#include <GLFW/glfw3.h>
using namespace openglframework;
// Constructor
SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mLight0(0),
mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
mPhongShader("shaders/phong.vert", "shaders/phong.frag") {
// Move the light0
mLight0.translateWorld(Vector3(7, 15, 15));
// Camera at light0 postion for the shadow map
mShadowMapLightCamera.translateWorld(mLight0.getOrigin());
mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
mShadowMapLightCamera.setFieldOfView(45.0f);
mShadowMapLightCamera.setSceneRadius(sceneRadius);
mShadowMapLightCamera.setZoom(1.0);
// Bias matrix for the shadow map
mShadowMapBiasMatrix.setAllValues(0.5f, 0.0f, 0.0f, 0.5f,
0.0f, 0.5f, 0.5f, 0.5f,
0.0f, 0.0f, 0.0f, 0.5f,
0.0f, 0.0f, 0.0f, 1.0f);
// Create the Shadow map FBO and texture
createShadowMapFBOAndTexture();
}
// Destructor
SceneDemo::~SceneDemo() {
mShadowMapTexture.destroy();
mFBOShadowMap.destroy();
}
// Render the scene (in multiple passes for shadow mapping)
void SceneDemo::render() {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
// Get the world-space to camera-space matrix
const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse();
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
// Bind the shader
mDepthShader.bind();
// Set the variables of the shader
mDepthShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
// Render the objects of the scene
renderSinglePass(mDepthShader);
// Unbind the shader
mDepthShader.unbind();
// ---------- Render the scene for final rendering (second pass) ----------- //
mPhongShader.bind();
// Set the variables of the shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
const Color& diffCol = mLight0.getDiffuseColor();
const Color& specCol = mLight0.getSpecularColor();
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
mPhongShader.setFloatUniform("shininess", 60.0f);
// Render the objects of the scene
renderSinglePass(mPhongShader);
mPhongShader.unbind();
}
// Create the Shadow map FBO and texture
void SceneDemo::createShadowMapFBOAndTexture() {
// Create the texture for the depth values
mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL);
// Create the FBO for the shadow map
mFBOShadowMap.create(0, 0, false);
mFBOShadowMap.bind(GL_NONE);
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMapTexture.getID());
}
// Render the shadow map
void SceneDemo::renderShadowMap() {
}

94
testbed/src/SceneDemo.h Normal file
View File

@ -0,0 +1,94 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef SCENEDEMO_H
#define SCENEDEMO_H
// Libraries
#include "Scene.h"
// Constants
const int SHADOWMAP_WIDTH = 1024;
const int SHADOWMAP_HEIGHT = 1024;
// Class SceneDemo
// Abstract class that represents a 3D scene for the ReactPhysics3D examples.
// This scene has a single light source with shadow mapping.
class SceneDemo : public Scene {
protected:
// -------------------- Attributes -------------------- //
/// Light 0
openglframework::Light mLight0;
/// FBO for the shadow map
openglframework::FrameBufferObject mFBOShadowMap;
/// Shadow map texture
openglframework::Texture2D mShadowMapTexture;
/// Camera at light0 position for the shadow map
openglframework::Camera mShadowMapLightCamera;
/// Bias matrix for the shadow map
openglframework::Matrix4 mShadowMapBiasMatrix;
/// Depth shader to render the shadow map
openglframework::Shader mDepthShader;
/// Phong shader
openglframework::Shader mPhongShader;
// -------------------- Methods -------------------- //
// Create the Shadow map FBO and texture
void createShadowMapFBOAndTexture();
// Render the shadow map
void renderShadowMap();
public:
// -------------------- Methods -------------------- //
/// Constructor
SceneDemo(const std::string& name, float sceneRadius);
/// Destructor
virtual ~SceneDemo();
/// Render the scene (possibly in multiple passes for shadow mapping)
virtual void render();
/// Render the scene in a single pass
virtual void renderSinglePass(openglframework::Shader& shader)=0;
};
#endif