Improve rendering of testbed application (flat shading, 3 light sources, ...)

This commit is contained in:
Daniel Chappuis 2019-10-21 07:22:18 +02:00
parent bcb4febb16
commit 43b818573a
24 changed files with 2588 additions and 2237 deletions

View File

@ -84,12 +84,6 @@ Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::Dynam
const std::string& meshFolderPath)
: PhysicsObject(meshFolderPath + "cube.obj") {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cube.obj", *this);
// Calculate the normals of the mesh
calculateNormals();
// Initialize the size of the box
mSize[0] = size.x * 0.5f;
mSize[1] = size.y * 0.5f;
@ -200,8 +194,7 @@ void Box::render(openglframework::Shader& shader, const openglframework::Matrix4
}
// 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
/// in the simulation.
/// We create two VBOs (one for vertices and one for indices) to render the box
void Box::createVBOAndVAO() {
// Create the VBO for the vertices data
@ -227,7 +220,7 @@ void Box::createVBOAndVAO() {
mVBOTextureCoords.unbind();
}
// Create th VBO for the indices data
// Create the VBO for the indices data
mVBOIndices.create();
mVBOIndices.bind();
size_t sizeIndices = mIndices[0].size() * sizeof(unsigned int);

View File

@ -25,6 +25,7 @@
// Libraries
#include "ConvexMesh.h"
#include <unordered_set>
// Constructor
ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
@ -39,6 +40,19 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) {
const openglframework::Vector3 vertex = mVertices[mIndices[0][f*3 + v]];
int vIndex = findVertexIndex(mConvexMeshVertices, vertex);
if (vIndex == -1) {
vIndex = mConvexMeshVertices.size();
mConvexMeshVertices.push_back(vertex);
}
mConvexMeshIndices.push_back(vIndex);
}
face->indexBase = f * 3;
face->nbVertices = 3;
face++;
@ -46,8 +60,8 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath)
// Create the polygon vertex array
mPolygonVertexArray =
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
&(mIndices[0][0]), sizeof(int),
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
&(mConvexMeshIndices[0]), sizeof(int),
getNbFaces(0), mPolygonFaces,
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
@ -86,6 +100,19 @@ ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) {
const openglframework::Vector3 vertex = mVertices[mIndices[0][f*3 + v]];
int vIndex = findVertexIndex(mConvexMeshVertices, vertex);
if (vIndex == -1) {
vIndex = mConvexMeshVertices.size();
mConvexMeshVertices.push_back(vertex);
}
mConvexMeshIndices.push_back(vIndex);
}
face->indexBase = f * 3;
face->nbVertices = 3;
face++;
@ -93,8 +120,8 @@ ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std
// Create the polygon vertex array
mPolygonVertexArray =
new rp3d::PolygonVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
&(mIndices[0][0]), sizeof(int),
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
&(mConvexMeshIndices[0]), sizeof(int),
getNbFaces(0), mPolygonFaces,
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
@ -254,3 +281,16 @@ void ConvexMesh::createVBOAndVAO() {
// Unbind the VAO
mVAO.unbind();
}
// Return the index of a given vertex in the mesh
int ConvexMesh::findVertexIndex(const std::vector<openglframework::Vector3>& vertices, const openglframework::Vector3& vertex) {
for (int i = 0; i < vertices.size(); i++) {
if (vertices[i] == vertex) {
return i;
}
}
return -1;
}

View File

@ -69,11 +69,21 @@ class ConvexMesh : public PhysicsObject {
/// Vertex Array Object for the vertex data
openglframework::VertexArrayObject mVAO;
/// Array with the vertices of the convex mesh
/// (only the vertices used for the physics shape, not duplicate vertices used for rendering)
std::vector<openglframework::Vector3> mConvexMeshVertices;
/// Array with the vertex indices of the convex mesh (used for the physics shape)
std::vector<int> mConvexMeshIndices;
// -------------------- Methods -------------------- //
// Create the Vertex Buffer Objects used to render with OpenGL.
/// Create the Vertex Buffer Objects used to render with OpenGL.
void createVBOAndVAO();
/// Return the index of a given vertex in the mesh
int findVertexIndex(const std::vector<openglframework::Vector3>& vertices, const openglframework::Vector3& vertex);
public :
// -------------------- Methods -------------------- //

View File

@ -40,8 +40,12 @@ PhysicsObject::PhysicsObject(const std::string& meshPath) : PhysicsObject() {
// Load the mesh from a file
openglframework::MeshReaderWriter::loadMeshFromFile(meshPath, *this);
// If the mesh file do not have normals
if (mNormals.empty()) {
// Calculate the normals of the mesh
calculateNormals();
}
}
// Compute the new transform matrix

View File

@ -1,125 +1,205 @@
# Blender v2.66 (sub 0) OBJ File: ''
# Blender v2.80 (sub 75) OBJ File: ''
# www.blender.org
v 0.000000 -1.000000 0.000000
v 0.723607 -0.447220 0.525725
v -0.276388 -0.447220 0.850649
v -0.894426 -0.447216 0.000000
v -0.276388 -0.447220 -0.850649
v 0.723607 -0.447220 -0.525725
v 0.276388 0.447220 0.850649
v -0.723607 0.447220 0.525725
v -0.723607 0.447220 -0.525725
v 0.276388 0.447220 -0.850649
v 0.894426 0.447216 0.000000
v 0.000000 1.000000 0.000000
v 0.000000 -1.000000 -0.000000
v 0.425323 -0.850654 0.309011
v 0.262869 -0.525738 0.809012
v -0.162456 -0.850654 0.499995
v 0.425323 -0.850654 -0.309011
v 0.850648 -0.525736 0.000000
v -0.688189 -0.525736 0.499997
v -0.525730 -0.850652 0.000000
v -0.688189 -0.525736 -0.499997
v 0.723607 -0.447220 0.525725
v 0.850648 -0.525736 -0.000000
v -0.525730 -0.850652 -0.000000
v -0.162456 -0.850654 -0.499995
v 0.262869 -0.525738 -0.809012
v 0.951058 0.000000 -0.309013
v 0.951058 0.000000 0.309013
v 0.587786 0.000000 0.809017
v 0.000000 0.000000 1.000000
v -0.587786 0.000000 0.809017
v -0.951058 0.000000 0.309013
v -0.951058 0.000000 -0.309013
v 0.425323 -0.850654 -0.309011
v 0.951058 -0.000000 0.309013
v -0.276388 -0.447220 0.850649
v 0.262869 -0.525738 0.809012
v 0.000000 -0.000000 1.000000
v -0.894426 -0.447216 -0.000000
v -0.688189 -0.525736 0.499997
v -0.951058 -0.000000 0.309013
v -0.276388 -0.447220 -0.850649
v -0.688189 -0.525736 -0.499997
v -0.587786 0.000000 -0.809017
v 0.000000 0.000000 -1.000000
v 0.723607 -0.447220 -0.525725
v 0.262869 -0.525738 -0.809012
v 0.587786 0.000000 -0.809017
v 0.587786 -0.000000 0.809017
v -0.587786 -0.000000 0.809017
v -0.951058 0.000000 -0.309013
v 0.000000 0.000000 -1.000000
v 0.951058 0.000000 -0.309013
v 0.276388 0.447220 0.850649
v 0.688189 0.525736 0.499997
v 0.162456 0.850654 0.499995
v -0.723607 0.447220 0.525725
v -0.262869 0.525738 0.809012
v -0.425323 0.850654 0.309011
v -0.723607 0.447220 -0.525725
v -0.850648 0.525736 0.000000
v -0.425323 0.850654 -0.309011
v 0.276388 0.447220 -0.850649
v -0.262869 0.525738 -0.809012
v 0.162456 0.850654 -0.499995
v 0.894426 0.447216 0.000000
v 0.688189 0.525736 -0.499997
v 0.525730 0.850652 0.000000
v 0.162456 0.850654 0.499995
v -0.425323 0.850654 0.309011
v -0.425323 0.850654 -0.309011
v 0.162456 0.850654 -0.499995
v 0.000000 1.000000 0.000000
vn 0.1024 -0.9435 0.3151
vn 0.7002 -0.6617 0.2680
vn -0.2680 -0.9435 0.1947
vn -0.2680 -0.9435 -0.1947
vn 0.1024 -0.9435 -0.3151
vn 0.9050 -0.3304 0.2680
vn 0.0247 -0.3304 0.9435
vn -0.8897 -0.3304 0.3151
vn -0.5746 -0.3304 -0.7488
vn 0.5346 -0.3304 -0.7779
vn 0.8026 -0.1256 0.5831
vn -0.3066 -0.1256 0.9435
vn -0.9921 -0.1256 -0.0000
vn -0.3066 -0.1256 -0.9435
vn 0.8026 -0.1256 -0.5831
vn 0.4089 0.6617 0.6284
vn -0.4713 0.6617 0.5831
vn -0.7002 0.6617 -0.2680
vn 0.0385 0.6617 -0.7488
vn 0.7240 0.6617 -0.1947
vn -0.0385 -0.6617 0.7488
vn 0.1876 -0.7947 0.5773
vn 0.4713 -0.6617 0.5831
vn 0.7002 -0.6617 -0.2680
vn 0.6071 -0.7947 0.0000
vn 0.3313 -0.9435 -0.0000
vn -0.7240 -0.6617 0.1947
vn -0.4911 -0.7947 0.3568
vn -0.4089 -0.6617 0.6284
vn -0.4089 -0.6617 -0.6284
vn -0.4911 -0.7947 -0.3568
vn -0.7240 -0.6617 -0.1947
vn 0.4713 -0.6617 -0.5831
vn 0.1876 -0.7947 -0.5773
vn -0.0385 -0.6617 -0.7488
vn 0.9921 0.1256 0.0000
vn 0.9822 -0.1876 -0.0000
vn 0.9050 -0.3304 -0.2680
vn 0.3066 0.1256 0.9435
vn 0.3035 -0.1876 0.9342
vn 0.5346 -0.3304 0.7779
vn -0.8026 0.1256 0.5831
vn -0.7947 -0.1876 0.5773
vn -0.5746 -0.3304 0.7488
vn -0.8026 0.1256 -0.5831
vn -0.7947 -0.1876 -0.5773
vn -0.8897 -0.3304 -0.3151
vn 0.3066 0.1256 -0.9435
vn 0.3035 -0.1876 -0.9342
vn 0.0247 -0.3304 -0.9435
vn 0.5746 0.3304 0.7488
vn 0.7947 0.1876 0.5773
vn 0.8897 0.3304 0.3151
vn -0.5346 0.3304 0.7779
vn -0.3035 0.1876 0.9342
vn -0.0247 0.3304 0.9435
vn -0.9050 0.3304 -0.2680
vn -0.9822 0.1876 0.0000
vn -0.9050 0.3304 0.2680
vn -0.0247 0.3304 -0.9435
vn -0.3035 0.1876 -0.9342
vn -0.5346 0.3304 -0.7779
vn 0.8897 0.3304 -0.3151
vn 0.7947 0.1876 -0.5773
vn 0.5746 0.3304 -0.7488
vn 0.2680 0.9435 0.1947
vn 0.4911 0.7947 0.3568
vn 0.7240 0.6617 0.1947
vn -0.1024 0.9435 0.3151
vn -0.1876 0.7947 0.5773
vn 0.0385 0.6617 0.7488
vn -0.3313 0.9435 0.0000
vn -0.6071 0.7947 0.0000
vn -0.7002 0.6617 0.2680
vn -0.1024 0.9435 -0.3151
vn -0.1876 0.7947 -0.5773
vn -0.4713 0.6617 -0.5831
vn 0.2680 0.9435 -0.1947
vn 0.4911 0.7947 -0.3568
vn 0.4089 0.6617 -0.6284
s off
f 1 13 15
f 2 13 17
f 1 15 19
f 1 19 21
f 1 21 16
f 2 17 24
f 3 14 26
f 4 18 28
f 5 20 30
f 6 22 32
f 2 24 25
f 3 26 27
f 4 28 29
f 5 30 31
f 6 32 23
f 7 33 39
f 8 34 40
f 9 35 41
f 10 36 42
f 11 37 38
f 15 14 3
f 15 13 14
f 13 2 14
f 17 16 6
f 17 13 16
f 13 1 16
f 19 18 4
f 19 15 18
f 15 3 18
f 21 20 5
f 21 19 20
f 19 4 20
f 16 22 6
f 16 21 22
f 21 5 22
f 24 23 11
f 24 17 23
f 17 6 23
f 26 25 7
f 26 14 25
f 14 2 25
f 28 27 8
f 28 18 27
f 18 3 27
f 30 29 9
f 30 20 29
f 20 4 29
f 32 31 10
f 32 22 31
f 22 5 31
f 25 33 7
f 25 24 33
f 24 11 33
f 27 34 8
f 27 26 34
f 26 7 34
f 29 35 9
f 29 28 35
f 28 8 35
f 31 36 10
f 31 30 36
f 30 9 36
f 23 37 11
f 23 32 37
f 32 10 37
f 39 38 12
f 39 33 38
f 33 11 38
f 40 39 12
f 40 34 39
f 34 7 39
f 41 40 12
f 41 35 40
f 35 8 40
f 42 41 12
f 42 36 41
f 36 9 41
f 38 42 12
f 38 37 42
f 37 10 42
f 1//1 2//1 3//1
f 4//2 2//2 5//2
f 1//3 3//3 6//3
f 1//4 6//4 7//4
f 1//5 7//5 8//5
f 4//6 5//6 9//6
f 10//7 11//7 12//7
f 13//8 14//8 15//8
f 16//9 17//9 18//9
f 19//10 20//10 21//10
f 4//11 9//11 22//11
f 10//12 12//12 23//12
f 13//13 15//13 24//13
f 16//14 18//14 25//14
f 19//15 21//15 26//15
f 27//16 28//16 29//16
f 30//17 31//17 32//17
f 33//18 34//18 35//18
f 36//19 37//19 38//19
f 39//20 40//20 41//20
f 3//21 11//21 10//21
f 3//22 2//22 11//22
f 2//23 4//23 11//23
f 5//24 8//24 19//24
f 5//25 2//25 8//25
f 2//26 1//26 8//26
f 6//27 14//27 13//27
f 6//28 3//28 14//28
f 3//29 10//29 14//29
f 7//30 17//30 16//30
f 7//31 6//31 17//31
f 6//32 13//32 17//32
f 8//33 20//33 19//33
f 8//34 7//34 20//34
f 7//35 16//35 20//35
f 9//36 26//36 39//36
f 9//37 5//37 26//37
f 5//38 19//38 26//38
f 12//39 22//39 27//39
f 12//40 11//40 22//40
f 11//41 4//41 22//41
f 15//42 23//42 30//42
f 15//43 14//43 23//43
f 14//44 10//44 23//44
f 18//45 24//45 33//45
f 18//46 17//46 24//46
f 17//47 13//47 24//47
f 21//48 25//48 36//48
f 21//49 20//49 25//49
f 20//50 16//50 25//50
f 22//51 28//51 27//51
f 22//52 9//52 28//52
f 9//53 39//53 28//53
f 23//54 31//54 30//54
f 23//55 12//55 31//55
f 12//56 27//56 31//56
f 24//57 34//57 33//57
f 24//58 15//58 34//58
f 15//59 30//59 34//59
f 25//60 37//60 36//60
f 25//61 18//61 37//61
f 18//62 33//62 37//62
f 26//63 40//63 39//63
f 26//64 21//64 40//64
f 21//65 36//65 40//65
f 29//66 41//66 42//66
f 29//67 28//67 41//67
f 28//68 39//68 41//68
f 32//69 29//69 42//69
f 32//70 31//70 29//70
f 31//71 27//71 29//71
f 35//72 32//72 42//72
f 35//73 34//73 32//73
f 34//74 30//74 32//74
f 38//75 35//75 42//75
f 38//76 37//76 35//76
f 37//77 33//77 35//77
f 41//78 38//78 42//78
f 41//79 40//79 38//79
f 40//80 36//80 38//80

View File

@ -1,17 +1,43 @@
# Blender v2.72 (sub 0) OBJ File: ''
# Blender v2.80 (sub 75) OBJ File: ''
# www.blender.org
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.375000 0.750000
vt 0.125000 0.750000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
s off
f 5 6 2 1
f 6 7 3 2
f 7 8 4 3
f 8 5 1 4
f 1 2 3 4
f 8 7 6 5
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/6/2 7/7/2 8/8/2
f 8/8/3 7/7/3 5/9/3 6/10/3
f 6/10/4 2/11/4 4/12/4 8/13/4
f 2/14/5 1/15/5 3/16/5 4/17/5
f 6/18/6 5/19/6 1/20/6 2/11/6

View File

@ -31,6 +31,8 @@
#include <cctype>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <tuple>
using namespace openglframework;
using namespace std;
@ -112,6 +114,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
std::vector<uint> normalsIndices;
std::vector<uint> uvsIndices;
// ---------- Collect the data from the file ---------- //
// For each line of the file
@ -142,7 +145,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
line = buffer;
found1 = (int)line.find("/");
bool isFaceQuad = false;
int foundNext = (int)line.substr(found1+1).find("/");
found2 = (int)line.substr(found1+1).find("/");
// If the face definition is of the form "f v1 v2 v3 v4"
if(found1 == string::npos) {
@ -150,11 +153,21 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if (nbVertices == 4) isFaceQuad = true;
}
// If the face definition is of the form "f v1// v2// v3// v4//"
else if (foundNext == 0) {
else if (found2 == 0 && (int)line.substr(found1+found2+1).find(" ") == 0) {
int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4);
if (nbVertices == 4) isFaceQuad = true;
}
else { // If the face definition contains vertices and texture coordinates
else { // If the face definition contains vertices and (texture coordinates or normals)
tId1 = -1;
tId2 = -1;
tId3 = -1;
tId4 = -1;
nId1 = -1;
nId2 = -1;
nId3 = -1;
nId4 = -1;
//get the part of the string until the second index
tmp = line.substr(found1+1);
@ -166,6 +179,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if(found2 == string::npos) {
int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4);
if (n == 8) isFaceQuad = true;
uvsIndices.push_back(tId1-1);
uvsIndices.push_back(tId2-1);
uvsIndices.push_back(tId3-1);
@ -174,8 +188,11 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
else {
tmp = line.substr(found1+1);
found2 = (int)tmp.find("/");
if (found2 > 1000) {
int test = 2;
}
// If the face definition is of the form "f vert1/normal1 vert2/normal2 ..."
// If the face definition is of the form "f vert1//normal1 vert2//normal2 ..."
if(found2 == 0) {
int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4);
if (n == 8) isFaceQuad = true;
@ -213,39 +230,84 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
// Destroy the current mesh
meshToCreate.destroy();
// This is used to create duplicate vertices if a vertex with index "i" from a face does not
// have same texture coordinates or normals as a previous vertex with index "i".
unordered_map<tuple<int, int, int>, uint> mapVertNormTexToVertexIndex;
// Mesh data
vector<std::vector<uint> > meshIndices;
vector<Vector3> meshVertices;
vector<Vector3> meshNormals;
if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
//if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
vector<Vector2> meshUVs;
if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
//if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
// We cannot load mesh with several parts for the moment
uint meshPart = 0;
const bool hasNormals = !normalsIndices.empty() && !normals.empty();
const bool hasUvs = !uvsIndices.empty() && !uvs.empty();
// Fill in the vertex indices
// We also triangulate each quad face
meshIndices.push_back(std::vector<uint>());
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
// Get the current vertex IDs
uint i1 = verticesIndices[i];
uint i2 = verticesIndices[i+1];
uint i3 = verticesIndices[i+2];
// 3 if the current vertices form a triangle and 4 if they form a quad
const int nbVertices = isQuad[j] ? 4 : 3;
int newVerticesIndices[4] = { -1, -1, -1, -1 };
// For each vertex, we check if there is already a vertex with same UV and normals.
for (int v = 0; v < nbVertices; v++) {
int normalIndex = hasNormals ? normalsIndices[i + v] : -1;
int uvIndex = hasUvs ? uvsIndices[i + v] : -1;
// If the vertex with same UV and normal doesn't exist yet in the map
tuple<int, int, int> key = std::make_tuple(verticesIndices[i+v], normalIndex, uvIndex);
auto itFound = mapVertNormTexToVertexIndex.find(key);
if (itFound == mapVertNormTexToVertexIndex.end()) {
// Create a new vertex
newVerticesIndices[v]= meshVertices.size();
meshVertices.push_back(vertices[verticesIndices[i+v]]);
if (hasNormals) {
meshNormals.push_back(normals[normalsIndices[i+v]]);
}
if (hasUvs) {
meshUVs.push_back(uvs[uvsIndices[i+v]]);
}
mapVertNormTexToVertexIndex.insert(std::make_pair(key, newVerticesIndices[v]));
}
else {
// Get the vertex index to use
newVerticesIndices[v] = itFound->second;
}
}
// Get the current vertex IDs
uint i1 = newVerticesIndices[0];
uint i2 = newVerticesIndices[1];
uint i3 = newVerticesIndices[2];
uint i4 = newVerticesIndices[3];
/*
// Add the vertex normal
if (!normalsIndices.empty() && !normals.empty()) {
if (hasNormals) {
meshNormals[i1] = normals[normalsIndices[i]];
meshNormals[i2] = normals[normalsIndices[i+1]];
meshNormals[i3] = normals[normalsIndices[i+2]];
}
// Add the vertex UV texture coordinates
if (!uvsIndices.empty() && !uvs.empty()) {
if (hasUvs) {
meshUVs[i1] = uvs[uvsIndices[i]];
meshUVs[i2] = uvs[uvsIndices[i+1]];
meshUVs[i3] = uvs[uvsIndices[i+2]];
}
*/
// If the current vertex not in a quad (it is part of a triangle)
if (!isQuad[j]) {
@ -259,11 +321,10 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
}
else { // If the current vertex is in a quad
Vector3 v1 = vertices[i1];
Vector3 v2 = vertices[i2];
Vector3 v3 = vertices[i3];
uint i4 = verticesIndices[i+3];
Vector3 v4 = vertices[i4];
Vector3 v1 = meshVertices[i1];
Vector3 v2 = meshVertices[i2];
Vector3 v3 = meshVertices[i3];
Vector3 v4 = meshVertices[i4];
Vector3 v13 = v3-v1;
Vector3 v12 = v2-v1;
@ -288,6 +349,7 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
meshIndices[meshPart].push_back(i4);
}
/*
// Add the vertex normal
if (!normalsIndices.empty() && !normals.empty()) {
meshNormals[i4] = normals[normalsIndices[i]];
@ -297,17 +359,18 @@ void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
if (!uvsIndices.empty() && !uvs.empty()) {
meshUVs[i4] = uvs[uvsIndices[i]];
}
*/
i+=4;
}
}
assert(meshNormals.empty() || meshNormals.size() == vertices.size());
assert(meshUVs.empty() || meshUVs.size() == vertices.size());
assert(meshNormals.empty() || meshNormals.size() == meshVertices.size());
assert(meshUVs.empty() || meshUVs.size() == meshVertices.size());
// Set the data to the mesh
meshToCreate.setIndices(meshIndices);
meshToCreate.setVertices(vertices);
meshToCreate.setVertices(meshVertices);
meshToCreate.setNormals(meshNormals);
meshToCreate.setUVs(meshUVs);
}

View File

@ -93,4 +93,15 @@ class VertexMergingDataComparison {
}
namespace std {
template<>
struct hash<std::tuple<int, int, int>>
{
size_t operator()(const std::tuple<int, int, int>& key) const
{
return std::get<0>(key) ^ std::get<1>(key) ^ std::get<2>(key);
}
};
}
#endif

View File

@ -95,6 +95,11 @@ class Shader {
// to set it, an assert will occur)
void setIntUniform(const std::string& variableName, int value, bool errorIfMissing = true) const;
// Set an array of int uniform values to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)
void setIntArrayUniform(const std::string& variableName, GLint* values, int nbValues, bool errorIfMissing = true) const;
// 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
// to set it, an assert will occur)
@ -159,7 +164,7 @@ inline GLint Shader::getUniformLocation(const std::string& variableName, bool er
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
<< std::endl;
throw std::logic_error("Error in Shader");
//throw std::logic_error("Error in Shader");
}
return location;
@ -209,6 +214,16 @@ inline void Shader::setIntUniform(const std::string& variableName, int value, bo
}
}
// Set an array of int uniform values to this shader (be careful if the uniform is not
// used in the shader, the compiler will remove it, then when you will try
// to set it, an assert will occur)
inline void Shader::setIntArrayUniform(const std::string& variableName, GLint* values, int nbValues, bool errorIfMissing) const {
assert(mProgramObjectID != 0);
GLint location = getUniformLocation(variableName, errorIfMissing);
if (location != -1) {
glUniform1iv(location, nbValues, values);
}
}
// 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
// to set it, an assert will occur)

View File

@ -61,8 +61,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mSphere1);
// Set the color
mSphere1->setColor(mGreyColorDemo);
mSphere1->setSleepingColor(mRedColorDemo);
mSphere1->setColor(mObjectColorDemo);
mSphere1->setSleepingColor(mSleepingColorDemo);
//mSphere1->setScaling(0.5f);
mPhysicsObjects.push_back(mSphere1);
@ -73,8 +73,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mSphere2);
// Set the color
mSphere2->setColor(mGreyColorDemo);
mSphere2->setSleepingColor(mRedColorDemo);
mSphere2->setColor(mObjectColorDemo);
mSphere2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mSphere2);
@ -85,8 +85,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mCapsule1);
// Set the color
mCapsule1->setColor(mGreyColorDemo);
mCapsule1->setSleepingColor(mRedColorDemo);
mCapsule1->setColor(mObjectColorDemo);
mCapsule1->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule1);
// ---------- Capsule 2 ---------- //
@ -96,8 +96,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mCapsule2);
// Set the color
mCapsule2->setColor(mGreyColorDemo);
mCapsule2->setSleepingColor(mRedColorDemo);
mCapsule2->setColor(mObjectColorDemo);
mCapsule2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule2);
// ---------- Concave Mesh ---------- //
@ -107,8 +107,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mConcaveMesh);
// Set the color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mRedColorDemo);
mConcaveMesh->setColor(mObjectColorDemo);
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Box 1 ---------- //
@ -118,8 +118,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mBox1);
// Set the color
mBox1->setColor(mGreyColorDemo);
mBox1->setSleepingColor(mRedColorDemo);
mBox1->setColor(mObjectColorDemo);
mBox1->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox1);
// ---------- Box 2 ---------- //
@ -129,8 +129,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mBox2);
// Set the color
mBox2->setColor(mGreyColorDemo);
mBox2->setSleepingColor(mRedColorDemo);
mBox2->setColor(mObjectColorDemo);
mBox2->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox2);
// ---------- Convex Mesh ---------- //
@ -140,8 +140,8 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mAllShapes.push_back(mConvexMesh);
// Set the color
mConvexMesh->setColor(mGreyColorDemo);
mConvexMesh->setSleepingColor(mRedColorDemo);
mConvexMesh->setColor(mObjectColorDemo);
mConvexMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConvexMesh);
// ---------- Heightfield ---------- //
@ -150,11 +150,11 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
mHeightField = new HeightField(mPhysicsWorld);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mRedColorDemo);
mHeightField->setColor(mObjectColorDemo);
mHeightField->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mHeightField);
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
mAllShapes[mSelectedShapeIndex]->setColor(mObjectColorDemo);
}
// Reset the scene
@ -233,8 +233,8 @@ void CollisionDetectionScene::selectNextShape() {
mSelectedShapeIndex = 0;
}
mAllShapes[previousIndex]->setColor(mGreyColorDemo);
mAllShapes[mSelectedShapeIndex]->setColor(mBlueColorDemo);
mAllShapes[previousIndex]->setColor(mObjectColorDemo);
mAllShapes[mSelectedShapeIndex]->setColor(mSelectedObjectColorDemo);
}
// Called when a keyboard event occurs

View File

@ -57,8 +57,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -76,8 +76,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -98,8 +98,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -120,8 +120,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f));
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -139,8 +139,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -157,8 +157,8 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
mPhysicsObjects.push_back(mFloor);
// Set the box color
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -58,8 +58,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -77,8 +77,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -99,8 +99,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
sphere->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -121,8 +121,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08));
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -140,8 +140,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -164,8 +164,8 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);
// Set the box color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mGreyColorDemo);
mConcaveMesh->setColor(mFloorColorDemo);
mConcaveMesh->setSleepingColor(mFloorColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);

View File

@ -56,8 +56,8 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
cube->setColor(mDemoColors[i % mNbDemoColors]);
cube->setSleepingColor(mRedColorDemo);
cube->setColor(mObjectColorDemo);
cube->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
@ -72,8 +72,8 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
// Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -58,8 +58,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
Box* cube = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
cube->setColor(mDemoColors[i % mNbDemoColors]);
cube->setSleepingColor(mRedColorDemo);
cube->setColor(mObjectColorDemo);
cube->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
@ -75,8 +75,8 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
// Create the floor
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -57,8 +57,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
Dumbbell* dumbbell = new Dumbbell(getDynamicsWorld(), meshFolderPath);
// Set the box color
dumbbell->setColor(mDemoColors[i % mNbDemoColors]);
dumbbell->setSleepingColor(mRedColorDemo);
dumbbell->setColor(mObjectColorDemo);
dumbbell->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = dumbbell->getRigidBody()->getMaterial();
@ -76,8 +76,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
Box* box = new Box(BOX_SIZE, BOX_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
box->setColor(mDemoColors[i % mNbDemoColors]);
box->setSleepingColor(mRedColorDemo);
box->setColor(mObjectColorDemo);
box->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = box->getRigidBody()->getMaterial();
@ -98,8 +98,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
sphere->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color
sphere->setColor(mDemoColors[i % mNbDemoColors]);
sphere->setSleepingColor(mRedColorDemo);
sphere->setColor(mObjectColorDemo);
sphere->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = sphere->getRigidBody()->getMaterial();
@ -120,8 +120,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f);
// Set the box color
capsule->setColor(mDemoColors[i % mNbDemoColors]);
capsule->setSleepingColor(mRedColorDemo);
capsule->setColor(mObjectColorDemo);
capsule->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = capsule->getRigidBody()->getMaterial();
@ -139,8 +139,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, getDynamicsWorld(), meshFolderPath + "convexmesh.obj");
// Set the box color
mesh->setColor(mDemoColors[i % mNbDemoColors]);
mesh->setSleepingColor(mRedColorDemo);
mesh->setColor(mObjectColorDemo);
mesh->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mesh->getRigidBody()->getMaterial();
@ -165,8 +165,8 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
mPhysicsObjects.push_back(mHeightField);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mGreyColorDemo);
mHeightField->setColor(mFloorColorDemo);
mHeightField->setSleepingColor(mFloorColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mHeightField->getRigidBody()->getMaterial();

View File

@ -214,8 +214,8 @@ void JointsScene::createBallAndSocketJoints() {
mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity()));
// Set the box color
mBallAndSocketJointChainBoxes[i]->setColor(mDemoColors[i % mNbDemoColors]);
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mRedColorDemo);
mBallAndSocketJointChainBoxes[i]->setColor(mObjectColorDemo);
mBallAndSocketJointChainBoxes[i]->setSleepingColor(mSleepingColorDemo);
// The fist box cannot move (static body)
if (i == 0) {
@ -266,8 +266,8 @@ void JointsScene::createSliderJoint() {
mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mSliderJointBottomBox->setColor(mBlueColorDemo);
mSliderJointBottomBox->setSleepingColor(mRedColorDemo);
mSliderJointBottomBox->setColor(mObjectColorDemo);
mSliderJointBottomBox->setSleepingColor(mSleepingColorDemo);
// The fist box cannot move
mSliderJointBottomBox->getRigidBody()->setType(rp3d::BodyType::STATIC);
@ -288,8 +288,8 @@ void JointsScene::createSliderJoint() {
mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color
mSliderJointTopBox->setColor(mOrangeColorDemo);
mSliderJointTopBox->setSleepingColor(mRedColorDemo);
mSliderJointTopBox->setColor(mObjectColorDemo);
mSliderJointTopBox->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
@ -330,8 +330,8 @@ void JointsScene::createPropellerHingeJoint() {
mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mPropellerBox->setColor(mYellowColorDemo);
mPropellerBox->setSleepingColor(mRedColorDemo);
mPropellerBox->setColor(mObjectColorDemo);
mPropellerBox->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
@ -371,8 +371,8 @@ void JointsScene::createFixedJoints() {
mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity()));
// Set the box color
mFixedJointBox1->setColor(mPinkColorDemo);
mFixedJointBox1->setSleepingColor(mRedColorDemo);
mFixedJointBox1->setColor(mObjectColorDemo);
mFixedJointBox1->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
@ -389,8 +389,8 @@ void JointsScene::createFixedJoints() {
mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity()));
// Set the box color
mFixedJointBox2->setColor(mBlueColorDemo);
mFixedJointBox2->setSleepingColor(mRedColorDemo);
mFixedJointBox2->setColor(mObjectColorDemo);
mFixedJointBox2->setSleepingColor(mSleepingColorDemo);
// Change the material properties of the rigid body
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
@ -429,8 +429,8 @@ void JointsScene::createFloor() {
mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath);
// Set the box color
mFloor->setColor(mGreyColorDemo);
mFloor->setSleepingColor(mGreyColorDemo);
mFloor->setColor(mFloorColorDemo);
mFloor->setSleepingColor(mFloorColorDemo);
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -56,8 +56,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mDumbbell = new Dumbbell(mPhysicsWorld, mMeshFolderPath);
// Set the box color
mDumbbell->setColor(mGreyColorDemo);
mDumbbell->setSleepingColor(mRedColorDemo);
mDumbbell->setColor(mObjectColorDemo);
mDumbbell->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mDumbbell);
// ---------- Box ---------- //
@ -67,8 +67,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mBox->getCollisionBody()->setIsActive(false);
// Set the box color
mBox->setColor(mGreyColorDemo);
mBox->setSleepingColor(mRedColorDemo);
mBox->setColor(mObjectColorDemo);
mBox->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mBox);
// ---------- Sphere ---------- //
@ -77,8 +77,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath);
// Set the color
mSphere->setColor(mGreyColorDemo);
mSphere->setSleepingColor(mRedColorDemo);
mSphere->setColor(mObjectColorDemo);
mSphere->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mSphere);
// ---------- Capsule ---------- //
@ -88,8 +88,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath);
// Set the color
mCapsule->setColor(mGreyColorDemo);
mCapsule->setSleepingColor(mRedColorDemo);
mCapsule->setColor(mObjectColorDemo);
mCapsule->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mCapsule);
// ---------- Convex Mesh ---------- //
@ -98,8 +98,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
// Set the color
mConvexMesh->setColor(mGreyColorDemo);
mConvexMesh->setSleepingColor(mRedColorDemo);
mConvexMesh->setColor(mObjectColorDemo);
mConvexMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConvexMesh);
// ---------- Concave Mesh ---------- //
@ -108,8 +108,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj");
// Set the color
mConcaveMesh->setColor(mGreyColorDemo);
mConcaveMesh->setSleepingColor(mRedColorDemo);
mConcaveMesh->setColor(mObjectColorDemo);
mConcaveMesh->setSleepingColor(mSleepingColorDemo);
mPhysicsObjects.push_back(mConcaveMesh);
// ---------- Heightfield ---------- //
@ -118,8 +118,8 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
mHeightField = new HeightField(mPhysicsWorld);
// Set the color
mHeightField->setColor(mGreyColorDemo);
mHeightField->setSleepingColor(mRedColorDemo);
mHeightField->setColor(mObjectColorDemo);
mHeightField->setSleepingColor(mObjectColorDemo);
mPhysicsObjects.push_back(mHeightField);
// Create the lines that will be used for raycasting

View File

@ -27,10 +27,14 @@
// Uniform variables
uniform vec3 lightAmbientColor; // Lights ambient color
uniform vec3 light0PosCameraSpace; // Camera-space position of the light
uniform vec3 light0PosCameraSpace; // Camera-space position of the light 0
uniform vec3 light1PosCameraSpace; // Camera-space position of the light 1
uniform vec3 light2PosCameraSpace; // Camera-space position of the light 2
uniform vec3 light0DiffuseColor; // Light 0 diffuse color
uniform vec3 light1DiffuseColor; // Light 1 diffuse color
uniform vec3 light2DiffuseColor; // Light 2 diffuse color
uniform sampler2D textureSampler; // Texture
uniform sampler2D shadowMapSampler; // Shadow map texture sampler
uniform sampler2D shadowMapSampler[3]; // Shadow map texture sampler
uniform bool isTexture; // True if we need to use the texture
uniform vec4 vertexColor; // Vertex color
uniform bool isShadowEnabled; // True if shadow mapping is enabled
@ -40,7 +44,7 @@ uniform vec2 shadowMapDimension; // Shadow map dimension
in vec3 vertexPosCameraSpace; // Camera-space position of the vertex
in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
in vec2 texCoords; // Texture coordinates
in vec4 shadowMapCoords; // Shadow map texture coords
in vec4 shadowMapCoords[3]; // Shadow map texture coords
// Out variable
out vec4 color; // Output color
@ -64,10 +68,24 @@ void main() {
// Compute the surface normal vector
vec3 N = normalize(vertexNormalCameraSpace);
color = vec4(ambient, 1);
vec3 lightPosCameraSpace[3];
lightPosCameraSpace[0] = light0PosCameraSpace;
lightPosCameraSpace[1] = light1PosCameraSpace;
lightPosCameraSpace[2] = light2PosCameraSpace;
vec3 lightDiffuseColor[3];
lightDiffuseColor[0] = light0DiffuseColor;
lightDiffuseColor[1] = light1DiffuseColor;
lightDiffuseColor[2] = light2DiffuseColor;
// For each light source
for (int l=0; l < 3; l++) {
// Compute the diffuse term of light 0
vec3 L0 = normalize(light0PosCameraSpace - vertexPosCameraSpace);
vec3 L0 = normalize(lightPosCameraSpace[l] - vertexPosCameraSpace);
float diffuseFactor = max(dot(N, L0), 0.0);
vec3 diffuse = light0DiffuseColor * diffuseFactor * textureColor;
vec3 diffuse = lightDiffuseColor[l] * diffuseFactor * textureColor;
// Compute shadow factor
float shadow = 1.0;
@ -75,29 +93,23 @@ void main() {
shadow = 0.0;
float bias = 0.0003;
float shadowBias = -0.000;
vec4 shadowMapUV = shadowMapCoords;
vec4 shadowMapUV = shadowMapCoords[l];
shadowMapUV.z -= shadowBias;
vec4 shadowMapCoordsOverW = shadowMapUV / shadowMapUV.w;
// PCF Shadow Mapping
for (float i=-1; i<=1; i++) {
for (float j=-1; j<=1; j++) {
float distInShadowMap = textureLookupPCF(shadowMapSampler, shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
if (shadowMapCoords.w > 0) {
float distInShadowMap = textureLookupPCF(shadowMapSampler[l], shadowMapCoordsOverW.xy, vec2(i, j)) + bias;
if (shadowMapCoords[l].w > 0) {
shadow += distInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
}
}
shadow /= 9.0;
/*
float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r + bias;
if (shadowMapCoords.w > 0) {
shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.5 : 1.0;
}
*/
}
// Compute the final color
color = vec4(ambient + shadow * diffuse, 1.0);
color += vec4(shadow * diffuse, 0.0);
}
}

View File

@ -29,9 +29,13 @@
uniform mat4 localToWorldMatrix; // Local-space to world-space matrix
uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix
uniform mat4 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping)
uniform mat4 worldToLight1CameraMatrix; // World-space to light1 camera-space matrix (for shadow mapping)
uniform mat4 worldToLight2CameraMatrix; // World-space to light2 camera-space matrix (for shadow mapping)
uniform mat4 projectionMatrix; // Projection matrix
uniform mat3 normalMatrix; // Normal matrix
uniform mat4 shadowMapProjectionMatrix; // Shadow map projection matrix
uniform mat4 shadowMapLight0ProjectionMatrix; // Shadow map projection matrix for light 0
uniform mat4 shadowMapLight1ProjectionMatrix; // Shadow map projection matrix for light 1
uniform mat4 shadowMapLight2ProjectionMatrix; // Shadow map projection matrix for light 2
// In variables
in vec4 vertexPosition;
@ -42,7 +46,7 @@ in vec2 textureCoords;
out vec3 vertexPosCameraSpace; // Camera-space position of the vertex
out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space
out vec2 texCoords; // Texture coordinates
out vec4 shadowMapCoords; // Shadow map texture coords
out vec4 shadowMapCoords[3]; // Shadow map texture coords
void main() {
@ -57,7 +61,17 @@ void main() {
texCoords = textureCoords;
// Compute the texture coords of the vertex in the shadow map
shadowMapCoords = shadowMapProjectionMatrix * worldToLight0CameraMatrix * localToWorldMatrix * vertexPosition;
mat4 worldToLightCameraMatrix[3];
worldToLightCameraMatrix[0] = worldToLight0CameraMatrix;
worldToLightCameraMatrix[1] = worldToLight1CameraMatrix;
worldToLightCameraMatrix[2] = worldToLight2CameraMatrix;
mat4 shadowMapProjectionMatrix[3];
shadowMapProjectionMatrix[0] = shadowMapLight0ProjectionMatrix;
shadowMapProjectionMatrix[1] = shadowMapLight1ProjectionMatrix;
shadowMapProjectionMatrix[2] = shadowMapLight2ProjectionMatrix;
for (int l=0; l < 3; l++) {
shadowMapCoords[l] = shadowMapProjectionMatrix[l] * worldToLightCameraMatrix[l] * localToWorldMatrix * vertexPosition;
}
// Compute the clip-space vertex coordinates
gl_Position = projectionMatrix * positionCameraSpace;

View File

@ -35,9 +35,24 @@ int main(int argc, char** argv) {
nanogui::init();
{
// Create and start the testbed application
bool isFullscreen = false;
nanogui::ref<TestbedApplication> application = new TestbedApplication(isFullscreen);
// Get the primary monitor
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
// Window size
int windowWidth = mode->width;
int windowHeight = mode->height;
if (!isFullscreen) {
windowWidth *= 0.9;
windowHeight *= 0.9;
}
// Create and start the testbed application
nanogui::ref<TestbedApplication> application = new TestbedApplication(isFullscreen, windowWidth, windowHeight);
application->setVisible(true);
nanogui::mainloop();

View File

@ -33,15 +33,10 @@
using namespace openglframework;
int SceneDemo::shadowMapTextureLevel = 0;
openglframework::Color SceneDemo::mGreyColorDemo = Color(0.70f, 0.70f, 0.7f, 1.0f);
openglframework::Color SceneDemo::mYellowColorDemo = Color(0.9f, 0.88f, 0.145f, 1.0f);
openglframework::Color SceneDemo::mBlueColorDemo = Color(0, 0.66f, 0.95f, 1.0f);
openglframework::Color SceneDemo::mOrangeColorDemo = Color(0.9f, 0.35f, 0, 1.0f);
openglframework::Color SceneDemo::mPinkColorDemo = Color(0.83f, 0.48f, 0.64f, 1.0f);
openglframework::Color SceneDemo::mRedColorDemo = Color(0.95f, 0, 0, 1.0f);
int SceneDemo::mNbDemoColors = 4;
openglframework::Color SceneDemo::mDemoColors[] = {SceneDemo::mYellowColorDemo, SceneDemo::mBlueColorDemo,
SceneDemo::mOrangeColorDemo, SceneDemo::mPinkColorDemo};
openglframework::Color SceneDemo::mObjectColorDemo = Color(0.76f, 0.67f, 0.47f, 1.0f);
openglframework::Color SceneDemo::mFloorColorDemo = Color(0.47f, 0.48f, 0.49f, 1.0f);
openglframework::Color SceneDemo::mSleepingColorDemo = Color(1.0f, 0.25f, 0.25f, 1.0f);
openglframework::Color SceneDemo::mSelectedObjectColorDemo = Color(0.09f, 0.59f, 0.88f, 1.0f);
// Constructor
SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sceneRadius, bool isShadowMappingEnabled)
@ -55,17 +50,34 @@ SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sc
shadowMapTextureLevel++;
// Move the light0
mLight0.translateWorld(Vector3(-2, 35, 40));
// Move the lights
float lightsRadius = 30.0f;
float lightsHeight = 20.0f;
mLight0.translateWorld(Vector3(0 * lightsRadius, lightsHeight, 1 * lightsRadius));
mLight1.translateWorld(Vector3(0.95f * lightsRadius, lightsHeight, -0.3f * lightsRadius));
mLight2.translateWorld(Vector3(-0.58f * lightsRadius, lightsHeight, -0.81f * lightsRadius));
// Camera at light0 postion for the shadow map
mShadowMapLightCamera.translateWorld(mLight0.getOrigin());
mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
mShadowMapLightCamera.rotateWorld(Vector3(0, 1, 0), PI / 8.0f);
// Set the lights colors
mLight0.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mLight1.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mLight2.setDiffuseColor(Color(0.6f, 0.6f, 0.6f, 1.0f));
mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
mShadowMapLightCamera.setFieldOfView(80.0f);
mShadowMapLightCamera.setSceneRadius(100);
mShadowMapLightCameras[0].translateWorld(mLight0.getOrigin());
mShadowMapLightCameras[0].rotateLocal(Vector3(1, 0, 0), -PI / 4.0f);
mShadowMapLightCameras[1].translateWorld(mLight1.getOrigin());
mShadowMapLightCameras[1].rotateLocal(Vector3(0, 1, 0), -5.0f * PI/3.7f);
mShadowMapLightCameras[1].rotateLocal(Vector3(1, 0, 0), -PI/4.0f);
mShadowMapLightCameras[2].translateWorld(mLight2.getOrigin());
mShadowMapLightCameras[2].rotateLocal(Vector3(0, 1, 0), 5 * PI/4.0f);
mShadowMapLightCameras[2].rotateLocal(Vector3(1, 0 , 0), -PI/4.0f);
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapLightCameras[i].setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
mShadowMapLightCameras[i].setFieldOfView(100.0f);
mShadowMapLightCameras[i].setSceneRadius(100);
}
mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
@ -88,8 +100,12 @@ SceneDemo::SceneDemo(const std::string& name, EngineSettings& settings, float sc
// Destructor
SceneDemo::~SceneDemo() {
mShadowMapTexture.destroy();
mFBOShadowMap.destroy();
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].destroy();
mFBOShadowMap[i].destroy();
}
mVBOQuad.destroy();
mDepthShader.destroy();
@ -134,15 +150,18 @@ void SceneDemo::updatePhysics() {
// Render the scene (in multiple passes for shadow mapping)
void SceneDemo::render() {
const Color& diffCol = mLight0.getDiffuseColor();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
Matrix4 shadowMapProjMatrix[NB_SHADOW_MAPS];
openglframework::Matrix4 worldToLightCameraMatrix[NB_SHADOW_MAPS];
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
const Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix();
const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse();
shadowMapProjMatrix[i] = mShadowMapLightCameras[i].getProjectionMatrix();
worldToLightCameraMatrix[i] = mShadowMapLightCameras[i].getTransformMatrix().getInverse();
}
// ---------- Render the scene to generate the shadow map (first pass) ----------- //
// If Shadow Mapping is enabled
if (mIsShadowMappingEnabled) {
@ -150,13 +169,16 @@ void SceneDemo::render() {
// Culling switching, rendering only backface, this is done to avoid self-shadowing
glCullFace(GL_BACK);
mFBOShadowMap.bind();
// For each shadow map
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mFBOShadowMap[i].bind();
// Bind the shader
mDepthShader.bind();
// Set the variables of the shader
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix);
mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix[i]);
// Set the viewport to render into the shadow map texture
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT);
@ -168,12 +190,13 @@ void SceneDemo::render() {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Render the objects of the scene
renderSinglePass(mDepthShader, worldToLightCameraMatrix);
renderSinglePass(mDepthShader, worldToLightCameraMatrix[i]);
// Unbind the shader
mDepthShader.unbind();
mFBOShadowMap.unbind();
mFBOShadowMap[i].unbind();
}
glDisable(GL_POLYGON_OFFSET_FILL);
}
@ -187,17 +210,34 @@ void SceneDemo::render() {
mPhongShader.bind();
if (mIsShadowMappingEnabled) mShadowMapTexture.bind();
const GLuint textureUnit = 0;
// Is shadow mapping is enabled
GLint textureUnits[NB_SHADOW_MAPS];
if (mIsShadowMappingEnabled) {
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].bind();
}
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
textureUnits[i] = mShadowMapTexture[i].getUnit();
}
}
// Set the variables of the phong shader
mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix());
mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix);
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix);
mPhongShader.setMatrix4x4Uniform("shadowMapLight0ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[0]);
mPhongShader.setMatrix4x4Uniform("shadowMapLight1ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[1]);
mPhongShader.setMatrix4x4Uniform("shadowMapLight2ProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix[2]);
mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix[0]);
mPhongShader.setMatrix4x4Uniform("worldToLight1CameraMatrix", worldToLightCameraMatrix[1]);
mPhongShader.setMatrix4x4Uniform("worldToLight2CameraMatrix", worldToLightCameraMatrix[2]);
mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.4f, 0.4f, 0.4f));
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
mPhongShader.setIntUniform("shadowMapSampler", textureUnit);
mPhongShader.setVector3Uniform("light1PosCameraSpace", worldToCameraMatrix * mLight1.getOrigin());
mPhongShader.setVector3Uniform("light2PosCameraSpace", worldToCameraMatrix * mLight2.getOrigin());
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(mLight0.getDiffuseColor().r, mLight0.getDiffuseColor().g, mLight0.getDiffuseColor().b));
mPhongShader.setVector3Uniform("light1DiffuseColor", Vector3(mLight1.getDiffuseColor().r, mLight1.getDiffuseColor().g, mLight1.getDiffuseColor().b));
mPhongShader.setVector3Uniform("light2DiffuseColor", Vector3(mLight2.getDiffuseColor().r, mLight2.getDiffuseColor().g, mLight2.getDiffuseColor().b));
mPhongShader.setIntArrayUniform("shadowMapSampler", textureUnits, NB_SHADOW_MAPS);
mPhongShader.setIntUniform("isShadowEnabled", mIsShadowMappingEnabled);
mPhongShader.setVector2Uniform("shadowMapDimension", Vector2(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT));
mPhongShader.unbind();
@ -229,7 +269,14 @@ void SceneDemo::render() {
renderAABBs(worldToCameraMatrix);
}
if (mIsShadowMappingEnabled) mShadowMapTexture.unbind();
// Is shadow mapping is enabled
if (mIsShadowMappingEnabled) {
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
mShadowMapTexture[i].unbind();
}
}
mPhongShader.unbind();
//drawTextureQuad();
@ -261,20 +308,33 @@ void SceneDemo::renderSinglePass(openglframework::Shader& shader, const openglfr
// Create the Shadow map FBO and texture
void SceneDemo::createShadowMapFBOAndTexture() {
// For each shadow map
for (int i = 0; i < NB_SHADOW_MAPS; i++) {
// Create the texture for the depth values
mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, NULL);
mShadowMapTexture[i].create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, NULL);
mShadowMapTexture[i].setUnit(i);
// Make sure that texture lookups outside the texture coords range will not
// treated as beeing in shadow
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture[i].getID());
GLfloat border[] = { 1.0f, 0.0f, 0.0f, 0.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
glBindTexture(GL_TEXTURE_2D, 0);
// Create the FBO for the shadow map
mFBOShadowMap.create(0, 0, false);
mFBOShadowMap.bind();
mFBOShadowMap[i].create(0, 0, false);
mFBOShadowMap[i].bind();
// Tell OpenGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture.getID());
mFBOShadowMap.unbind();
mFBOShadowMap[i].attachTexture(GL_DEPTH_ATTACHMENT, mShadowMapTexture[i].getID());
mFBOShadowMap[i].unbind();
}
mIsShadowMappingInitialized = true;
}
@ -310,11 +370,13 @@ void SceneDemo::drawTextureQuad() {
// Clear previous frame values
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const GLuint textureUnit = 0;
const int SHADOW_MAP_TEXTURE_TO_DRAW = 0;
const GLuint textureUnit = SHADOW_MAP_TEXTURE_TO_DRAW;
mVAOQuad.bind();
mQuadShader.bind();
mShadowMapTexture.bind();
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].bind();
mQuadShader.setIntUniform("textureSampler", textureUnit);
mVBOQuad.bind();
@ -336,7 +398,7 @@ void SceneDemo::drawTextureQuad() {
glDisableVertexAttribArray(vertexPositionLoc);
mVBOQuad.unbind();
mShadowMapTexture.unbind();
mShadowMapTexture[SHADOW_MAP_TEXTURE_TO_DRAW].unbind();
mQuadShader.unbind();
mVAOQuad.unbind();
}

View File

@ -43,19 +43,29 @@ class SceneDemo : public Scene {
protected:
// -------------------- Constants -------------------- //
static constexpr int NB_SHADOW_MAPS = 3;
// -------------------- Attributes -------------------- //
/// Light 0
openglframework::Light mLight0;
/// Light 1
openglframework::Light mLight1;
/// Light 2
openglframework::Light mLight2;
/// True if the shadows FBO, textures have been created
bool mIsShadowMappingInitialized;
/// FBO for the shadow map
openglframework::FrameBufferObject mFBOShadowMap;
/// Array of FBO for the shadow maps
openglframework::FrameBufferObject mFBOShadowMap[NB_SHADOW_MAPS];
/// Shadow map texture
openglframework::Texture2D mShadowMapTexture;
openglframework::Texture2D mShadowMapTexture[NB_SHADOW_MAPS];
static int shadowMapTextureLevel;
@ -65,8 +75,8 @@ class SceneDemo : public Scene {
/// Shadow map bias matrix
openglframework::Matrix4 mShadowMapBiasMatrix;
/// Camera at light0 position for the shadow map
openglframework::Camera mShadowMapLightCamera;
/// Cameras at lights position for the shadow maps
openglframework::Camera mShadowMapLightCameras[NB_SHADOW_MAPS];
/// Depth shader to render the shadow map
openglframework::Shader mDepthShader;
@ -85,14 +95,10 @@ class SceneDemo : public Scene {
openglframework::VertexBufferObject mVBOQuad;
static openglframework::Color mGreyColorDemo;
static openglframework::Color mYellowColorDemo;
static openglframework::Color mBlueColorDemo;
static openglframework::Color mOrangeColorDemo;
static openglframework::Color mPinkColorDemo;
static openglframework::Color mRedColorDemo;
static openglframework::Color mDemoColors[];
static int mNbDemoColors;
static openglframework::Color mObjectColorDemo;
static openglframework::Color mFloorColorDemo;
static openglframework::Color mSleepingColorDemo;
static openglframework::Color mSelectedObjectColorDemo;
std::string mMeshFolderPath;

View File

@ -52,13 +52,13 @@ using namespace cubestackscene;
const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f;
// Constructor
TestbedApplication::TestbedApplication(bool isFullscreen)
: Screen(Vector2i(1280, 800), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
TestbedApplication::TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight)
: Screen(Vector2i(windowWidth, windowHeight), "Testbed ReactPhysics3D", true, isFullscreen, 8, 8, 24, 8, 8),
mIsInitialized(false), mGui(this), mCurrentScene(nullptr),
mEngineSettings(EngineSettings::defaultSettings()),
mFPS(0), mNbFrames(0), mPreviousTime(0),
mLastTimeComputedFPS(0), mFrameTime(0), mPhysicsTime(0),
mWidth(1280), mHeight(720),
mWidth(windowWidth), mHeight(windowHeight),
mSinglePhysicsStepEnabled(false), mSinglePhysicsStepDone(false),
mWindowToFramebufferRatio(Vector2(1, 1)), mIsShadowMappingEnabled(true),
mIsContactPointsDisplayed(false), mIsAABBsDisplayed(false), mIsWireframeEnabled(false),

View File

@ -164,7 +164,7 @@ class TestbedApplication : public Screen {
// -------------------- Methods -------------------- //
/// Private constructor (for the singleton class)
TestbedApplication(bool isFullscreen);
TestbedApplication(bool isFullscreen, int windowWidth, int windowHeight);
/// Destructor
virtual ~TestbedApplication() override;