first commit of mesh refactoring
This commit is contained in:
parent
a25344dbaf
commit
b303c4b1ff
@ -14,7 +14,6 @@ endif(WIN32)
|
|||||||
set(LIB_SRC_LIST
|
set(LIB_SRC_LIST
|
||||||
src/framebuffer.cpp
|
src/framebuffer.cpp
|
||||||
src/meshbuilder.cpp
|
src/meshbuilder.cpp
|
||||||
src/phongentity.cpp
|
|
||||||
src/phongmaterial.cpp
|
src/phongmaterial.cpp
|
||||||
src/crappymodule.cpp
|
src/crappymodule.cpp
|
||||||
src/shader.cpp
|
src/shader.cpp
|
||||||
@ -30,6 +29,7 @@ set(LIB_SRC_LIST
|
|||||||
src/posteffectmodule.cpp
|
src/posteffectmodule.cpp
|
||||||
src/textureblur.cpp
|
src/textureblur.cpp
|
||||||
src/textureredux.cpp
|
src/textureredux.cpp
|
||||||
|
src/mesh.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARY_NAME ${PROJECT_NAME})
|
set(LIBRARY_NAME ${PROJECT_NAME})
|
||||||
@ -45,7 +45,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
|||||||
set(CPP_DEFINES -DRENDER_DEBUG)
|
set(CPP_DEFINES -DRENDER_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(GLOB LIBRARY_RES_FILES *.h shaders/*.glsl)
|
file(GLOB LIBRARY_RES_FILES src/*.h shaders/*.glsl)
|
||||||
|
|
||||||
add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST} ${LIBRARY_RES_FILES})
|
add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST} ${LIBRARY_RES_FILES})
|
||||||
add_definitions(-std=c++11 ${CPP_DEFINES})
|
add_definitions(-std=c++11 ${CPP_DEFINES})
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "crappymodule.h"
|
#include "crappymodule.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "phongentity.h"
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "sparrowrenderer.h"
|
#include "sparrowrenderer.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "glassert.h"
|
#include "glassert.h"
|
||||||
|
#include "material.h"
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
|
void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
|
||||||
@ -37,16 +37,16 @@ void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
||||||
entityIt->isValid(); entityIt->next())
|
geometryIt->isValid(); geometryIt->next())
|
||||||
{
|
{
|
||||||
PhongEntity* entity = entityIt->getItem();
|
GeometryNode* node = geometryIt->getItem();
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix;
|
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
||||||
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
|
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadMatrixf(glm::value_ptr(myCamera->getProjectionMatrix()));
|
glLoadMatrixf(glm::value_ptr(myCamera->getProjectionMatrix()));
|
||||||
entity->drawDisplayList();
|
node->mesh->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
glAssert(glDisable(GL_LIGHTING));
|
glAssert(glDisable(GL_LIGHTING));
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "forwardmodule.h"
|
#include "forwardmodule.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "phongentity.h"
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
@ -84,17 +83,17 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
||||||
entityIt->isValid(); entityIt->next())
|
geometryIt->isValid(); geometryIt->next())
|
||||||
{
|
{
|
||||||
// compute matrix attributes
|
// compute matrix attributes
|
||||||
PhongEntity* entity = entityIt->getItem();
|
GeometryNode* node = geometryIt->getItem();
|
||||||
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix;
|
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
||||||
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
||||||
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
|
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
|
||||||
if(light != NULL && light->isShadowCaster())
|
if(light != NULL && light->isShadowCaster())
|
||||||
{
|
{
|
||||||
glm::mat4 lightMVP = Light::biasMatrix * light->getProjectionMatrix() * light->getViewMatrix() * entity->modelMatrix;
|
glm::mat4 lightMVP = Light::biasMatrix * light->getProjectionMatrix() * light->getViewMatrix() * node->modelMatrix;
|
||||||
shader->bindMat4(shader->getLocation("lightMVP"), lightMVP);
|
shader->bindMat4(shader->getLocation("lightMVP"), lightMVP);
|
||||||
}
|
}
|
||||||
shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix());
|
shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix());
|
||||||
@ -102,16 +101,11 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
|
|||||||
shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix));
|
shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix));
|
||||||
shader->bindMat4(shader->getLocation("MVP"), mvp);
|
shader->bindMat4(shader->getLocation("MVP"), mvp);
|
||||||
// loop over material groups
|
// loop over material groups
|
||||||
for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j)
|
for(int j=0; j<node->mesh->indiceGroups.size(); ++j)
|
||||||
{
|
{
|
||||||
Material* mat = entity->getMesh()->indiceGroups[j].material;
|
Material* mat = node->getMesh()->indiceGroups[j].material;
|
||||||
if(mat->getFlags() == geometryFlagList[i])
|
if(mat->getFlags() == geometryFlagList[i])
|
||||||
{
|
node->mesh->draw(shader);
|
||||||
// bind material attributes
|
|
||||||
mat->bindAttributes(shader);
|
|
||||||
// draw geometry
|
|
||||||
entity->drawGroup(j);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
304
src/mesh.cpp
Normal file
304
src/mesh.cpp
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
#include "mesh.h"
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <set>
|
||||||
|
#include "glassert.h"
|
||||||
|
#include "sparrowrenderer.h"
|
||||||
|
|
||||||
|
Mesh::Mesh() :
|
||||||
|
material(NULL),
|
||||||
|
vao(0),
|
||||||
|
nb_buffers(0),
|
||||||
|
vbo(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Mesh::~Mesh()
|
||||||
|
{
|
||||||
|
destroyGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::initGL(bool isDynamic)
|
||||||
|
{
|
||||||
|
if(vbo != NULL)
|
||||||
|
destroyGL();
|
||||||
|
|
||||||
|
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
||||||
|
|
||||||
|
// create VAO
|
||||||
|
glAssert(glGenVertexArrays(1, &vao));
|
||||||
|
glAssert(glBindVertexArray(vao));
|
||||||
|
|
||||||
|
nb_buffers = 2; // positions and indices buffers
|
||||||
|
if(mesh->hasNormals())
|
||||||
|
++nb_buffers;
|
||||||
|
if(mesh->hasTexCoords())
|
||||||
|
++nb_buffers;
|
||||||
|
if(mesh->hasTangents())
|
||||||
|
++nb_buffers;
|
||||||
|
|
||||||
|
// create VBOs
|
||||||
|
vbo = new GLuint[nb_buffers]();
|
||||||
|
glAssert(glGenBuffers(nb_buffers, vbo));
|
||||||
|
|
||||||
|
// init indices vbos
|
||||||
|
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
|
||||||
|
glAssert(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), buffer_type));
|
||||||
|
|
||||||
|
// init positions vbo
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
||||||
|
glAssert(glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(glm::vec3), positions.data(), buffer_type));
|
||||||
|
|
||||||
|
if(hasNormals())
|
||||||
|
{
|
||||||
|
// init normals vbo
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
||||||
|
glAssert(glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), buffer_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasNormals())
|
||||||
|
{
|
||||||
|
// init texCoords vbo
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
||||||
|
glAssert(glBufferData(GL_ARRAY_BUFFER, texCoords.size() * sizeof(glm::vec2), texCoords.data(), buffer_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasTangents())
|
||||||
|
{
|
||||||
|
// init tangents vbo
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
||||||
|
glAssert(glBufferData(GL_ARRAY_BUFFER, tangents.size() * sizeof(glm::vec3)*2, tangents.data(), buffer_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
// unbind vao
|
||||||
|
glAssert(glBindVertexArray(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTangents)
|
||||||
|
{
|
||||||
|
bool crappy = (shader == NULL);
|
||||||
|
material.bindAttributes(shader);
|
||||||
|
glAssert(glBindVertexArray(vao));
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
||||||
|
if(crappy)
|
||||||
|
{
|
||||||
|
glAssert(glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
|
glAssert(glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
||||||
|
glAssert(glEnableVertexAttribArray(0));
|
||||||
|
}
|
||||||
|
if(hasNormals() && drawNormals)
|
||||||
|
{
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
||||||
|
if(crappy)
|
||||||
|
{
|
||||||
|
glAssert(glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
|
glAssert(glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
||||||
|
glAssert(glEnableVertexAttribArray(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasTexCoords() && drawTexCoord)
|
||||||
|
{
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
||||||
|
if(crappy)
|
||||||
|
{
|
||||||
|
glAssert(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||||
|
glAssert(glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
|
||||||
|
glAssert(glEnableVertexAttribArray(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasTangents() && drawTangents && !crappy)
|
||||||
|
{
|
||||||
|
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
||||||
|
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(0)));
|
||||||
|
glAssert(glEnableVertexAttribArray(3));
|
||||||
|
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
|
||||||
|
glAssert(glEnableVertexAttribArray(4));
|
||||||
|
}
|
||||||
|
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
|
||||||
|
glAssert(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, NULL));
|
||||||
|
glAssert(glBindVertexArray(0));
|
||||||
|
if(crappy)
|
||||||
|
{
|
||||||
|
glAssert(glDisableClientState(GL_VERTEX_ARRAY));
|
||||||
|
if(hasNormals() && drawNormals)
|
||||||
|
glAssert(glDisableClientState(GL_NORMAL_ARRAY));
|
||||||
|
if(hasTexCoords() && drawTexCoord)
|
||||||
|
glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::destroyGL()
|
||||||
|
{
|
||||||
|
if(vbo != NULL)
|
||||||
|
{
|
||||||
|
glAssert(glDeleteVertexArrays(1, &vao));
|
||||||
|
glAssert(glDeleteBuffers(nb_buffers, vbo));
|
||||||
|
delete[] vbo;
|
||||||
|
vao = 0;
|
||||||
|
nb_buffers = 0;
|
||||||
|
vbo = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertexComparator
|
||||||
|
{
|
||||||
|
// c'est plutot crade mais j'ai pas trouve d'autre moyen pour le moment
|
||||||
|
static Mesh* mesh;
|
||||||
|
static void setMesh(MeshBuilder* m) {VertexComparator::mesh = m;}
|
||||||
|
|
||||||
|
bool operator() (const int& vertId1, const int& vertId2) const
|
||||||
|
{
|
||||||
|
if(mesh->positions[vertId1].x != mesh->positions[vertId2].x)
|
||||||
|
return (mesh->positions[vertId1].x < mesh->positions[vertId2].x);
|
||||||
|
if(mesh->positions[vertId1].y != mesh->positions[vertId2].y)
|
||||||
|
return (mesh->positions[vertId1].y < mesh->positions[vertId2].y);
|
||||||
|
if(mesh->positions[vertId1].z != mesh->positions[vertId2].z)
|
||||||
|
return (mesh->positions[vertId1].z < mesh->positions[vertId2].z);
|
||||||
|
if(mesh->hasTexCoords())
|
||||||
|
{
|
||||||
|
if(mesh->texCoords[vertId1].x != mesh->texCoords[vertId2].x)
|
||||||
|
return (mesh->texCoords[vertId1].x < mesh->texCoords[vertId2].x);
|
||||||
|
if(mesh->texCoords[vertId1].y != mesh->texCoords[vertId2].y)
|
||||||
|
return (mesh->texCoords[vertId1].y < mesh->texCoords[vertId2].y);
|
||||||
|
}
|
||||||
|
if(mesh->hasNormals())
|
||||||
|
{
|
||||||
|
if(mesh->normals[vertId1].x != mesh->normals[vertId2].x)
|
||||||
|
return (mesh->normals[vertId1].x < mesh->normals[vertId2].x);
|
||||||
|
if(mesh->normals[vertId1].y != mesh->normals[vertId2].y)
|
||||||
|
return (mesh->normals[vertId1].y < mesh->normals[vertId2].y);
|
||||||
|
if(mesh->normals[vertId1].z != mesh->normals[vertId2].z)
|
||||||
|
return (mesh->normals[vertId1].z < mesh->normals[vertId2].z);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Mesh* VertexComparator::mesh = NULL;
|
||||||
|
|
||||||
|
void Mesh::mergeVertices()
|
||||||
|
{
|
||||||
|
std::vector<int> swapped;
|
||||||
|
std::set<int, VertexComparator> vertexSet;
|
||||||
|
VertexComparator::setMesh(this);
|
||||||
|
|
||||||
|
int swappedOffset = positions.size() - 1;
|
||||||
|
|
||||||
|
for(int i=0; i<indices.size(); ++i)
|
||||||
|
{
|
||||||
|
if(indices[i] >= positions.size())
|
||||||
|
indices[i] = swapped[swappedOffset - indices[i]];
|
||||||
|
std::pair<std::set<int,VertexComparator>::iterator,bool> ret = vertexSet.insert(g.indices[i]);
|
||||||
|
if(!ret.second) // duplicate found
|
||||||
|
{
|
||||||
|
// updating indices references
|
||||||
|
int toDelete = indices[i];
|
||||||
|
swapped.push_back(toDelete);
|
||||||
|
indices[i] = *(ret.first);
|
||||||
|
// deleting the duplicate
|
||||||
|
positions[toDelete] = positions.back();
|
||||||
|
positions.pop_back();
|
||||||
|
if(hasTexCoords())
|
||||||
|
{
|
||||||
|
texCoords[toDelete] = texCoords.back();
|
||||||
|
texCoords.pop_back();
|
||||||
|
}
|
||||||
|
if(hasNormals())
|
||||||
|
{
|
||||||
|
normals[toDelete] = normals.back();
|
||||||
|
normals.pop_back();
|
||||||
|
}
|
||||||
|
if(hasTangents())
|
||||||
|
{
|
||||||
|
tangents[indices[i]].tangent += tangents[toDelete].tangent;
|
||||||
|
tangents[indices[i]].binormal += tangents[toDelete].binormal;
|
||||||
|
tangents[toDelete] = tangents.back();
|
||||||
|
tangents.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Tangents &t : tangents)
|
||||||
|
{
|
||||||
|
t.tangent = glm::normalize(t.tangent);
|
||||||
|
t.binormal = glm::normalize(t.binormal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::computeNormals()
|
||||||
|
{
|
||||||
|
normals.resize(positions.size());
|
||||||
|
for (int i=0; i < indices.size(); i += 3)
|
||||||
|
{
|
||||||
|
int v0 = indices[i];
|
||||||
|
int v1 = indices[i+1];
|
||||||
|
int v2 = indices[i+2];
|
||||||
|
glm::vec3 n = glm::cross(positions[v1] - positions[v0], positions[v2] - positions[v0]);
|
||||||
|
normals[v0] += n;
|
||||||
|
normals[v1] += n;
|
||||||
|
normals[v2] += n;
|
||||||
|
}
|
||||||
|
for(glm::vec3 &n : normals)
|
||||||
|
n = glm::normalize(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::computeTangents()
|
||||||
|
{
|
||||||
|
if(!hasTexCoords())
|
||||||
|
return;
|
||||||
|
tangents = std::vector<Tangents>(positions.size());
|
||||||
|
|
||||||
|
for (int j=0; j < indices.size(); j += 3)
|
||||||
|
{
|
||||||
|
int vertexId0 = indices[j];
|
||||||
|
int vertexId1 = indices[j+1];
|
||||||
|
int vertexId2 = indices[j+2];
|
||||||
|
|
||||||
|
const glm::vec3 &v1 = positions[vertexId0];
|
||||||
|
const glm::vec3 &v2 = positions[vertexId1];
|
||||||
|
const glm::vec3 &v3 = positions[vertexId2];
|
||||||
|
|
||||||
|
const glm::vec2& w1 = texCoords[vertexId0];
|
||||||
|
const glm::vec2& w2 = texCoords[vertexId1];
|
||||||
|
const glm::vec2& w3 = texCoords[vertexId2];
|
||||||
|
|
||||||
|
float x1 = v2.x - v1.x;
|
||||||
|
float x2 = v3.x - v1.x;
|
||||||
|
float y1 = v2.y - v1.y;
|
||||||
|
float y2 = v3.y - v1.y;
|
||||||
|
float z1 = v2.z - v1.z;
|
||||||
|
float z2 = v3.z - v1.z;
|
||||||
|
|
||||||
|
float s1 = w2.x - w1.x;
|
||||||
|
float s2 = w3.x - w1.x;
|
||||||
|
float t1 = w2.y - w1.y;
|
||||||
|
float t2 = w3.y - w1.y;
|
||||||
|
|
||||||
|
float r = 1.0f / (s1 * t2 - s2 * t1);
|
||||||
|
glm::vec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||||
|
(t2 * z1 - t1 * z2) * r);
|
||||||
|
glm::vec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||||
|
(s1 * z2 - s2 * z1) * r);
|
||||||
|
|
||||||
|
Tangents& tan1 = tangents[vertexId0];
|
||||||
|
Tangents& tan2 = tangents[vertexId1];
|
||||||
|
Tangents& tan3 = tangents[vertexId2];
|
||||||
|
|
||||||
|
tan1.tangent += sdir;
|
||||||
|
tan2.tangent += sdir;
|
||||||
|
tan3.tangent += sdir;
|
||||||
|
|
||||||
|
tan1.binormal += tdir;
|
||||||
|
tan2.binormal += tdir;
|
||||||
|
tan3.binormal += tdir;
|
||||||
|
}
|
||||||
|
}
|
43
src/mesh.h
43
src/mesh.h
@ -1,31 +1,64 @@
|
|||||||
#ifndef MESH_H
|
#ifndef MESH_H
|
||||||
#define MESH_H
|
#define MESH_H
|
||||||
|
|
||||||
|
#include <glew/glew.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
class Material;
|
class Material;
|
||||||
|
class Shader;
|
||||||
|
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// geometry data
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
glm::vec3 tangent;
|
glm::vec3 tangent;
|
||||||
glm::vec3 binormal;
|
glm::vec3 binormal;
|
||||||
} Tangents;
|
} Tangents;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
std::vector<unsigned int> indices;
|
|
||||||
Material* material;
|
Material* material;
|
||||||
} Group;
|
|
||||||
|
|
||||||
std::vector<glm::vec3> positions;
|
std::vector<glm::vec3> positions;
|
||||||
std::vector<glm::vec3> normals;
|
std::vector<glm::vec3> normals;
|
||||||
std::vector<glm::vec2> texCoords;
|
std::vector<glm::vec2> texCoords;
|
||||||
std::vector<Tangents> tangents;
|
std::vector<Tangents> tangents;
|
||||||
std::vector<Group> indiceGroups;
|
std::vector<unsigned int> indices;
|
||||||
|
|
||||||
|
// opengl
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// required buffers
|
||||||
|
POSITION_BUFFER,
|
||||||
|
// optionnal buffers :
|
||||||
|
NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER,
|
||||||
|
// indices buffers
|
||||||
|
INDICES_BUFFER
|
||||||
|
};
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
int nb_buffers;
|
||||||
|
GLuint* vbo;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mesh();
|
||||||
|
~Mesh();
|
||||||
|
|
||||||
|
void initGL(bool isDynamic = false);
|
||||||
|
void draw(Shader* shader = NULL, bool drawNormals = true, bool drawTexCoord = true, bool drawTangents = true);
|
||||||
|
void destroyGL();
|
||||||
|
|
||||||
|
// merge same vertices
|
||||||
|
void mergeVertices();
|
||||||
|
bool operator() (const int& vertId1, const int& vertId2) const;
|
||||||
|
// require positions and indices
|
||||||
|
void computeNormals();
|
||||||
|
// require normals and texCoord
|
||||||
|
void computeTangents();
|
||||||
|
|
||||||
bool hasNormals() const
|
bool hasNormals() const
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include "meshbuilder.h"
|
#include "meshbuilder.h"
|
||||||
#include <glm/ext.hpp>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
void MeshBuilder::addPosition(float x, float y, float z)
|
void MeshBuilder::addPosition(float x, float y, float z)
|
||||||
{
|
{
|
||||||
@ -54,201 +52,12 @@ void MeshBuilder::addVertex(const glm::vec3 &position, const glm::vec3 &normal,
|
|||||||
|
|
||||||
void MeshBuilder::addTriangle(int i1, int i2, int i3)
|
void MeshBuilder::addTriangle(int i1, int i2, int i3)
|
||||||
{
|
{
|
||||||
indiceGroups[currentGroup].indices.push_back(i1);
|
indices.push_back(i1);
|
||||||
indiceGroups[currentGroup].indices.push_back(i2);
|
indices.push_back(i2);
|
||||||
indiceGroups[currentGroup].indices.push_back(i3);
|
indices.push_back(i3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshBuilder::addGroup(Material* myMaterial)
|
void MeshBuilder::setMaterial(Material* myMaterial)
|
||||||
{
|
{
|
||||||
Group g;
|
material = myMaterial;
|
||||||
g.material = myMaterial;
|
|
||||||
setCurrentGroup(getNbGroups());
|
|
||||||
indiceGroups.push_back(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshBuilder::setCurrentGroup(int groupId)
|
|
||||||
{
|
|
||||||
currentGroup = groupId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshBuilder::setCurrentGroupMaterial(Material* myMaterial)
|
|
||||||
{
|
|
||||||
indiceGroups[currentGroup].material = myMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MeshBuilder::getNbGroups()
|
|
||||||
{
|
|
||||||
return indiceGroups.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
class VertexComparator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// c'est crade mais j'ai pas trouvé d'autre moyen pour le moment
|
|
||||||
static MeshBuilder* mesh;
|
|
||||||
static void setMesh(MeshBuilder* m) {VertexComparator::mesh = m;}
|
|
||||||
|
|
||||||
bool operator() (const int& vertId1, const int& vertId2) const
|
|
||||||
{
|
|
||||||
if(mesh->positions[vertId1].x != mesh->positions[vertId2].x)
|
|
||||||
return (mesh->positions[vertId1].x < mesh->positions[vertId2].x);
|
|
||||||
if(mesh->positions[vertId1].y != mesh->positions[vertId2].y)
|
|
||||||
return (mesh->positions[vertId1].y < mesh->positions[vertId2].y);
|
|
||||||
if(mesh->positions[vertId1].z != mesh->positions[vertId2].z)
|
|
||||||
return (mesh->positions[vertId1].z < mesh->positions[vertId2].z);
|
|
||||||
if(mesh->hasTexCoords())
|
|
||||||
{
|
|
||||||
if(mesh->texCoords[vertId1].x != mesh->texCoords[vertId2].x)
|
|
||||||
return (mesh->texCoords[vertId1].x < mesh->texCoords[vertId2].x);
|
|
||||||
if(mesh->texCoords[vertId1].y != mesh->texCoords[vertId2].y)
|
|
||||||
return (mesh->texCoords[vertId1].y < mesh->texCoords[vertId2].y);
|
|
||||||
}
|
|
||||||
if(mesh->hasNormals())
|
|
||||||
{
|
|
||||||
if(mesh->normals[vertId1].x != mesh->normals[vertId2].x)
|
|
||||||
return (mesh->normals[vertId1].x < mesh->normals[vertId2].x);
|
|
||||||
if(mesh->normals[vertId1].y != mesh->normals[vertId2].y)
|
|
||||||
return (mesh->normals[vertId1].y < mesh->normals[vertId2].y);
|
|
||||||
if(mesh->normals[vertId1].z != mesh->normals[vertId2].z)
|
|
||||||
return (mesh->normals[vertId1].z < mesh->normals[vertId2].z);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
MeshBuilder* VertexComparator::mesh = NULL;
|
|
||||||
|
|
||||||
void MeshBuilder::mergeVertices()
|
|
||||||
{
|
|
||||||
std::vector<int> swapped;
|
|
||||||
std::set<int, VertexComparator> vertexSet;
|
|
||||||
VertexComparator::setMesh(this);
|
|
||||||
|
|
||||||
int swappedOffset = positions.size() - 1;
|
|
||||||
|
|
||||||
for(Group &g : indiceGroups)
|
|
||||||
for(int i=0; i<g.indices.size(); ++i)
|
|
||||||
{
|
|
||||||
if(g.indices[i] >= positions.size())
|
|
||||||
g.indices[i] = swapped[swappedOffset - g.indices[i]];
|
|
||||||
std::pair<std::set<int,VertexComparator>::iterator,bool> ret = vertexSet.insert(g.indices[i]);
|
|
||||||
if(!ret.second) // duplicate found
|
|
||||||
{
|
|
||||||
// updating indices references
|
|
||||||
int toDelete = g.indices[i];
|
|
||||||
swapped.push_back(toDelete);
|
|
||||||
g.indices[i] = *(ret.first);
|
|
||||||
// deleting the duplicate
|
|
||||||
positions[toDelete] = positions.back();
|
|
||||||
positions.pop_back();
|
|
||||||
if(hasTexCoords())
|
|
||||||
{
|
|
||||||
texCoords[toDelete] = texCoords.back();
|
|
||||||
texCoords.pop_back();
|
|
||||||
}
|
|
||||||
if(hasNormals())
|
|
||||||
{
|
|
||||||
normals[toDelete] = normals.back();
|
|
||||||
normals.pop_back();
|
|
||||||
}
|
|
||||||
if(hasTangents())
|
|
||||||
{
|
|
||||||
tangents[g.indices[i]].tangent += tangents[toDelete].tangent;
|
|
||||||
tangents[g.indices[i]].binormal += tangents[toDelete].binormal;
|
|
||||||
tangents[toDelete] = tangents.back();
|
|
||||||
tangents.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(Tangents &t : tangents)
|
|
||||||
{
|
|
||||||
t.tangent = glm::normalize(t.tangent);
|
|
||||||
t.binormal = glm::normalize(t.binormal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshBuilder::computeNormals()
|
|
||||||
{
|
|
||||||
normals.resize(positions.size());
|
|
||||||
for(const Group &g : indiceGroups)
|
|
||||||
for (int i=0; i < g.indices.size(); i += 3)
|
|
||||||
{
|
|
||||||
int v0 = g.indices[i];
|
|
||||||
int v1 = g.indices[i+1];
|
|
||||||
int v2 = g.indices[i+2];
|
|
||||||
glm::vec3 n = glm::cross(positions[v1] - positions[v0], positions[v2] - positions[v0]);
|
|
||||||
normals[v0] += n;
|
|
||||||
normals[v1] += n;
|
|
||||||
normals[v2] += n;
|
|
||||||
}
|
|
||||||
for(glm::vec3 &n : normals)
|
|
||||||
n = glm::normalize(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshBuilder::computeTangents()
|
|
||||||
{
|
|
||||||
if(!hasTexCoords())
|
|
||||||
return;
|
|
||||||
tangents = std::vector<Tangents>(positions.size());
|
|
||||||
|
|
||||||
for(const Group &g : indiceGroups)
|
|
||||||
for (int j=0; j < g.indices.size(); j += 3)
|
|
||||||
{
|
|
||||||
int vertexId0 = g.indices[j];
|
|
||||||
int vertexId1 = g.indices[j+1];
|
|
||||||
int vertexId2 = g.indices[j+2];
|
|
||||||
|
|
||||||
const glm::vec3 &v1 = positions[vertexId0];
|
|
||||||
const glm::vec3 &v2 = positions[vertexId1];
|
|
||||||
const glm::vec3 &v3 = positions[vertexId2];
|
|
||||||
|
|
||||||
const glm::vec2& w1 = texCoords[vertexId0];
|
|
||||||
const glm::vec2& w2 = texCoords[vertexId1];
|
|
||||||
const glm::vec2& w3 = texCoords[vertexId2];
|
|
||||||
|
|
||||||
float x1 = v2.x - v1.x;
|
|
||||||
float x2 = v3.x - v1.x;
|
|
||||||
float y1 = v2.y - v1.y;
|
|
||||||
float y2 = v3.y - v1.y;
|
|
||||||
float z1 = v2.z - v1.z;
|
|
||||||
float z2 = v3.z - v1.z;
|
|
||||||
|
|
||||||
float s1 = w2.x - w1.x;
|
|
||||||
float s2 = w3.x - w1.x;
|
|
||||||
float t1 = w2.y - w1.y;
|
|
||||||
float t2 = w3.y - w1.y;
|
|
||||||
|
|
||||||
float r = 1.0f / (s1 * t2 - s2 * t1);
|
|
||||||
glm::vec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
|
||||||
(t2 * z1 - t1 * z2) * r);
|
|
||||||
glm::vec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
|
||||||
(s1 * z2 - s2 * z1) * r);
|
|
||||||
|
|
||||||
Tangents& tan1 = tangents[vertexId0];
|
|
||||||
Tangents& tan2 = tangents[vertexId1];
|
|
||||||
Tangents& tan3 = tangents[vertexId2];
|
|
||||||
|
|
||||||
tan1.tangent += sdir;
|
|
||||||
tan2.tangent += sdir;
|
|
||||||
tan3.tangent += sdir;
|
|
||||||
|
|
||||||
tan1.binormal += tdir;
|
|
||||||
tan2.binormal += tdir;
|
|
||||||
tan3.binormal += tdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// building tangent matrix
|
|
||||||
/*
|
|
||||||
for (long a = 0; a < vertexCount; a++)
|
|
||||||
{
|
|
||||||
const Vector3D& n = normal[a];
|
|
||||||
const Vector3D& t = tan1[a];
|
|
||||||
|
|
||||||
// Gram-Schmidt orthogonalize
|
|
||||||
tangent[a] = (t - n * Dot(n, t)).Normalize();
|
|
||||||
|
|
||||||
// Calculate handedness
|
|
||||||
tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
class MeshBuilder : public Mesh
|
class MeshBuilder : public Mesh
|
||||||
{
|
{
|
||||||
int currentGroup;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void addTriangle(int i1, int i2, int i3);
|
void addTriangle(int i1, int i2, int i3);
|
||||||
|
|
||||||
@ -21,18 +19,7 @@ public:
|
|||||||
void addVertex(const glm::vec3 &position, const glm::vec2 &texCoord);
|
void addVertex(const glm::vec3 &position, const glm::vec2 &texCoord);
|
||||||
void addVertex(const glm::vec3 &position, const glm::vec3 &normal, const glm::vec2 &texCoord);
|
void addVertex(const glm::vec3 &position, const glm::vec3 &normal, const glm::vec2 &texCoord);
|
||||||
|
|
||||||
void addGroup(Material* myMaterial);
|
void setMaterial(Material* myMaterial);
|
||||||
void setCurrentGroup(int groupId);
|
|
||||||
void setCurrentGroupMaterial(Material* myMaterial);
|
|
||||||
int getNbGroups();
|
|
||||||
|
|
||||||
// merge same vertices
|
|
||||||
void mergeVertices();
|
|
||||||
bool operator() (const int& vertId1, const int& vertId2) const;
|
|
||||||
// require positions and indices
|
|
||||||
void computeNormals();
|
|
||||||
// require normals and texCoord
|
|
||||||
void computeTangents();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESHBUILDER_H
|
#endif // MESHBUILDER_H
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
Sphere::Sphere(Material* mat, int n)
|
Sphere::Sphere(Material* mat, int n)
|
||||||
{
|
{
|
||||||
// icosahedron :
|
// icosahedron :
|
||||||
addGroup(mat);
|
|
||||||
Group* group = &(indiceGroups[0]);
|
|
||||||
|
|
||||||
// top cap
|
// top cap
|
||||||
createVertex(0, 1);
|
createVertex(0, 1);
|
||||||
@ -37,7 +35,7 @@ Sphere::Sphere(Material* mat, int n)
|
|||||||
|
|
||||||
// geodesic subdivisions :
|
// geodesic subdivisions :
|
||||||
for(int i=0; i<n; i++)
|
for(int i=0; i<n; i++)
|
||||||
subdivide(group);
|
subdivide();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Sphere::getEdge(int a, int b)
|
int Sphere::getEdge(int a, int b)
|
||||||
@ -78,27 +76,27 @@ int Sphere::getEdge(int a, int b)
|
|||||||
return vid;
|
return vid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sphere::subdivide(Group* group)
|
void Sphere::subdivide()
|
||||||
{
|
{
|
||||||
edges = new Edge[positions.size()-1];
|
edges = new Edge[positions.size()-1];
|
||||||
int nb_triangles = group->indices.size()/3;
|
int nb_triangles = indices.size()/3;
|
||||||
for(int j=0; j<nb_triangles; j++)
|
for(int j=0; j<nb_triangles; j++)
|
||||||
{
|
{
|
||||||
int vid[3];
|
int vid[3];
|
||||||
for(int k=0; k<3; k++)
|
for(int k=0; k<3; k++)
|
||||||
{
|
{
|
||||||
int idA = group->indices[j*3 + k];
|
int idA = indices[j*3 + k];
|
||||||
int idB = group->indices[j*3 + (k+1)%3];
|
int idB = indices[j*3 + (k+1)%3];
|
||||||
int a = idA < idB ? idA : idB;
|
int a = idA < idB ? idA : idB;
|
||||||
int b = idA > idB ? idA : idB;
|
int b = idA > idB ? idA : idB;
|
||||||
vid[k] = getEdge(a, b);
|
vid[k] = getEdge(a, b);
|
||||||
}
|
}
|
||||||
for(int k=0; k<3; k++)
|
for(int k=0; k<3; k++)
|
||||||
addTriangle(group->indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
addTriangle(indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
||||||
addTriangle(vid[0], vid[1], vid[2]);
|
addTriangle(vid[0], vid[1], vid[2]);
|
||||||
}
|
}
|
||||||
delete[](edges);
|
delete[](edges);
|
||||||
group->indices.erase(group->indices.begin(), group->indices.begin()+nb_triangles*3);
|
indices.erase(indices.begin(), indices.begin()+nb_triangles*3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sphere::createVertex(float u, float v)
|
void Sphere::createVertex(float u, float v)
|
||||||
@ -113,7 +111,7 @@ void Sphere::createVertex(float u, float v)
|
|||||||
|
|
||||||
GridMesh::GridMesh(Material* mat, int width, int height, bool alternate)
|
GridMesh::GridMesh(Material* mat, int width, int height, bool alternate)
|
||||||
{
|
{
|
||||||
addGroup(mat);
|
setMaterial(mat);
|
||||||
for(int i=0; i<=width; ++i)
|
for(int i=0; i<=width; ++i)
|
||||||
{
|
{
|
||||||
for(int j=0; j<=height; ++j)
|
for(int j=0; j<=height; ++j)
|
||||||
|
@ -22,7 +22,7 @@ private:
|
|||||||
Edge* edges;
|
Edge* edges;
|
||||||
int getEdge(int a, int b);
|
int getEdge(int a, int b);
|
||||||
void createVertex(float u, float v);
|
void createVertex(float u, float v);
|
||||||
void subdivide(Group* group);
|
void subdivide();
|
||||||
public:
|
public:
|
||||||
Sphere(Material* mat, int n = 0);
|
Sphere(Material* mat, int n = 0);
|
||||||
};
|
};
|
||||||
|
@ -1,166 +0,0 @@
|
|||||||
#include "phongentity.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include "phongmaterial.h"
|
|
||||||
#include "mesh.h"
|
|
||||||
#include <glm/ext.hpp>
|
|
||||||
#include "glassert.h"
|
|
||||||
#include "sparrowrenderer.h"
|
|
||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
|
||||||
|
|
||||||
PhongEntity::PhongEntity(Mesh* myMesh) :
|
|
||||||
mesh(myMesh),
|
|
||||||
vao(0),
|
|
||||||
nb_buffers(0),
|
|
||||||
vbo(NULL),
|
|
||||||
displayList(0),
|
|
||||||
modelMatrix()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void PhongEntity::modernInit(bool isDynamic)
|
|
||||||
{
|
|
||||||
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
|
||||||
|
|
||||||
// create VAO
|
|
||||||
glAssert(glGenVertexArrays(1, &vao));
|
|
||||||
glAssert(glBindVertexArray(vao));
|
|
||||||
|
|
||||||
nb_buffers = 1; // positions buffer
|
|
||||||
if(mesh->hasNormals())
|
|
||||||
++nb_buffers;
|
|
||||||
if(mesh->hasTexCoords())
|
|
||||||
++nb_buffers;
|
|
||||||
if(mesh->hasTangents())
|
|
||||||
++nb_buffers;
|
|
||||||
|
|
||||||
nb_buffers += mesh->indiceGroups.size();
|
|
||||||
|
|
||||||
// create VBOs
|
|
||||||
vbo = new GLuint[nb_buffers]();
|
|
||||||
glAssert(glGenBuffers(nb_buffers, vbo));
|
|
||||||
|
|
||||||
for(int i=0; i<mesh->indiceGroups.size(); ++i)
|
|
||||||
{
|
|
||||||
const Mesh::Group &g = mesh->indiceGroups[i];
|
|
||||||
// init indices vbos
|
|
||||||
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFERS + i]));
|
|
||||||
glAssert(glBufferData(GL_ELEMENT_ARRAY_BUFFER, g.indices.size() * sizeof(GLuint), g.indices.data(), buffer_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
// init positions vbo
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
|
||||||
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->positions.size() * sizeof(glm::vec3), mesh->positions.data(), buffer_type));
|
|
||||||
|
|
||||||
if(mesh->hasNormals())
|
|
||||||
{
|
|
||||||
// init normals vbo
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
|
||||||
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->normals.size() * sizeof(glm::vec3), mesh->normals.data(), buffer_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mesh->hasNormals())
|
|
||||||
{
|
|
||||||
// init texCoords vbo
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
|
||||||
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->texCoords.size() * sizeof(glm::vec2), mesh->texCoords.data(), buffer_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mesh->hasTangents())
|
|
||||||
{
|
|
||||||
// init tangents vbo
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
|
||||||
glAssert(glBufferData(GL_ARRAY_BUFFER, mesh->tangents.size() * sizeof(glm::vec3)*2, mesh->tangents.data(), buffer_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
// unbind vao
|
|
||||||
glAssert(glBindVertexArray(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhongEntity::crappyInit()
|
|
||||||
{
|
|
||||||
displayList = glAssert(glGenLists(1));
|
|
||||||
glAssert(glNewList(displayList, GL_COMPILE));
|
|
||||||
for(int i=0; i<mesh->indiceGroups.size(); ++i)
|
|
||||||
{
|
|
||||||
PhongMaterial* mat = (PhongMaterial*)(mesh->indiceGroups[i].material);
|
|
||||||
mat->bindAttributes(NULL);
|
|
||||||
glAssert(glBegin(GL_TRIANGLES));
|
|
||||||
for(int j=0; j<mesh->indiceGroups[i].indices.size(); ++j)
|
|
||||||
{
|
|
||||||
int vid = mesh->indiceGroups[i].indices[j];
|
|
||||||
glNormal3fv(glm::value_ptr(mesh->normals[vid]));
|
|
||||||
glTexCoord2fv(glm::value_ptr(mesh->texCoords[vid]));
|
|
||||||
glVertex3fv(glm::value_ptr(mesh->positions[vid]));
|
|
||||||
}
|
|
||||||
glAssert(glEnd());
|
|
||||||
}
|
|
||||||
glAssert(glEndList());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhongEntity::initGL(bool isDynamic)
|
|
||||||
{
|
|
||||||
if(SparrowRenderer::isModernOpenGLAvailable())
|
|
||||||
modernInit(isDynamic);
|
|
||||||
else
|
|
||||||
crappyInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhongEntity::destroyGL()
|
|
||||||
{
|
|
||||||
if(SparrowRenderer::isModernOpenGLAvailable())
|
|
||||||
{
|
|
||||||
glAssert(glDeleteVertexArrays(1, &vao));
|
|
||||||
glAssert(glDeleteBuffers(nb_buffers, vbo));
|
|
||||||
delete[] vbo;
|
|
||||||
vbo = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glAssert(glDeleteLists(displayList, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhongEntity::drawGroup(int groupId, bool drawNormals, bool drawTexCoord, bool drawTangents)
|
|
||||||
{
|
|
||||||
glAssert(glBindVertexArray(vao));
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
|
||||||
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
|
||||||
glAssert(glEnableVertexAttribArray(0));
|
|
||||||
if(mesh->hasNormals() && drawNormals)
|
|
||||||
{
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
|
|
||||||
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
|
|
||||||
glAssert(glEnableVertexAttribArray(1));
|
|
||||||
}
|
|
||||||
if(mesh->hasTexCoords() && drawTexCoord)
|
|
||||||
{
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
|
|
||||||
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
|
|
||||||
glAssert(glEnableVertexAttribArray(2));
|
|
||||||
}
|
|
||||||
if(mesh->hasTangents() && drawTangents)
|
|
||||||
{
|
|
||||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
|
|
||||||
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(0)));
|
|
||||||
glAssert(glEnableVertexAttribArray(3));
|
|
||||||
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
|
|
||||||
glAssert(glEnableVertexAttribArray(4));
|
|
||||||
}
|
|
||||||
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFERS + groupId]));
|
|
||||||
glAssert(glDrawElements(GL_TRIANGLES, mesh->indiceGroups[groupId].indices.size(), GL_UNSIGNED_INT, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhongEntity::drawDisplayList()
|
|
||||||
{
|
|
||||||
glAssert(glCallList(displayList));
|
|
||||||
}
|
|
||||||
|
|
||||||
PhongEntity* PhongEntity::clone()
|
|
||||||
{
|
|
||||||
PhongEntity* myClone = new PhongEntity(mesh);
|
|
||||||
myClone->modelMatrix = modelMatrix;
|
|
||||||
myClone->displayList = displayList;
|
|
||||||
myClone->nb_buffers = nb_buffers;
|
|
||||||
myClone->vao = vao;
|
|
||||||
myClone->vbo = vbo;
|
|
||||||
return myClone;
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
#ifndef PHONGENTITY_H
|
|
||||||
#define PHONGENTITY_H
|
|
||||||
|
|
||||||
#include <glew/glew.h>
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class Mesh;
|
|
||||||
class Material;
|
|
||||||
class Shader;
|
|
||||||
|
|
||||||
class PhongEntity
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Mesh* mesh;
|
|
||||||
|
|
||||||
// modern opengl :
|
|
||||||
|
|
||||||
enum {
|
|
||||||
// required buffers
|
|
||||||
POSITION_BUFFER,
|
|
||||||
// optionnal buffers :
|
|
||||||
NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER,
|
|
||||||
// indices buffers
|
|
||||||
INDICES_BUFFERS
|
|
||||||
};
|
|
||||||
|
|
||||||
GLuint vao;
|
|
||||||
int nb_buffers;
|
|
||||||
GLuint* vbo;
|
|
||||||
|
|
||||||
void modernInit(bool isDynamic);
|
|
||||||
|
|
||||||
// old opengl :
|
|
||||||
|
|
||||||
GLuint displayList;
|
|
||||||
|
|
||||||
void crappyInit();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief the model matrix is public, so the user can manipulate it in any way he desires.
|
|
||||||
*/
|
|
||||||
glm::mat4 modelMatrix;
|
|
||||||
|
|
||||||
PhongEntity(Mesh* myMesh);
|
|
||||||
|
|
||||||
void drawDisplayList();
|
|
||||||
void drawGroup(int groupId, bool drawNormals = true, bool drawTexCoord = true, bool drawTangents = true);
|
|
||||||
|
|
||||||
void initGL(bool isDynamic = false);
|
|
||||||
void destroyGL();
|
|
||||||
|
|
||||||
Mesh* getMesh() {return mesh;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief this method returns a clone of the current entity.
|
|
||||||
* The same VAO/displayList will be used to render both, so there is no need to call initGL on the clone
|
|
||||||
*/
|
|
||||||
PhongEntity* clone();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PHONGENTITY_H
|
|
19
src/scene.h
19
src/scene.h
@ -5,7 +5,8 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "phongentity.h"
|
|
||||||
|
class Mesh;
|
||||||
|
|
||||||
// Scene interface :
|
// Scene interface :
|
||||||
|
|
||||||
@ -20,11 +21,17 @@ public:
|
|||||||
T& getItem() {return operator*();}
|
T& getItem() {return operator*();}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GeometryNode
|
||||||
|
{
|
||||||
|
Mesh* mesh;
|
||||||
|
glm::mat4 modelMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual SceneIterator<Light*>* getLights() = 0;
|
virtual SceneIterator<Light*>* getLights() = 0;
|
||||||
virtual SceneIterator<PhongEntity*>* getGeometry() = 0;
|
virtual SceneIterator<GeometryNode*>* getGeometry() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Some basic implementations :
|
// Some basic implementations :
|
||||||
@ -45,16 +52,16 @@ class ArrayScene : public Scene
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::vector<Light*> lights;
|
std::vector<Light*> lights;
|
||||||
std::vector<PhongEntity*> entities;
|
std::vector<GeometryNode*> geometry;
|
||||||
public:
|
public:
|
||||||
void clearLights() {lights.clear();}
|
void clearLights() {lights.clear();}
|
||||||
void clearEntities() {entities.clear();}
|
void clearEntities() {geometry.clear();}
|
||||||
void clearScene() {clearLights(); clearEntities();}
|
void clearScene() {clearLights(); clearEntities();}
|
||||||
void addEntity(PhongEntity* myEntity) {entities.push_back(myEntity);}
|
void addMesh(GeometryNode* node) {geometry.push_back(node);}
|
||||||
void addLight(Light* myLight) {lights.push_back(myLight);}
|
void addLight(Light* myLight) {lights.push_back(myLight);}
|
||||||
|
|
||||||
virtual SceneIterator<Light*>* getLights() {return new ArraySceneIterator<Light*>(lights);}
|
virtual SceneIterator<Light*>* getLights() {return new ArraySceneIterator<Light*>(lights);}
|
||||||
virtual SceneIterator<PhongEntity*>* getGeometry() {return new ArraySceneIterator<PhongEntity*>(entities);}
|
virtual SceneIterator<GeometryNode*>* getGeometry() {return new ArraySceneIterator<GeometryNode*>(geometry);}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCENE_H
|
#endif // SCENE_H
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <glm/mat3x3.hpp>
|
#include <glm/mat3x3.hpp>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include "skyboxmodule.h"
|
#include "skyboxmodule.h"
|
||||||
#include "phongentity.h"
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user