#include "phongentity.h" #include "shader.h" #include #include "phongmaterial.h" #include "mesh.h" #include #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::draw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights) { if(SparrowRenderer::isModernOpenGLAvailable()) modernDraw(viewMatrix, projectionMatrix, dirLight, pointLights); else crappyDraw(viewMatrix, projectionMatrix, dirLight, pointLights); } void PhongEntity::modernDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights) { glm::mat4 modelViewMatrix = viewMatrix * modelMatrix; glm::mat4 mvp = projectionMatrix * modelViewMatrix; glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); for(int i=0; iindiceGroups.size(); ++i) { Material* mat = mesh->indiceGroups[i].material; mat->bindAttributes(); Shader* shader = mat->getShader(); shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix); shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix); shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix); shader->bindMatrix(shader->getLocation("MVP"), mvp); shader->bindVec3Array(shader->getLocation("dirLight"), (glm::vec3*)dirLight, 2); pointLights->bind(shader->getLocation("pointLights"), shader->getLocation("nbPointLights"), shader); drawGroup(i); } } void PhongEntity::crappyDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights) { glMatrixMode(GL_MODELVIEW); glm::mat4 modelViewMatrix = viewMatrix * modelMatrix; glLoadMatrixf(glm::value_ptr(modelViewMatrix)); glMatrixMode(GL_PROJECTION); glLoadMatrixf(glm::value_ptr(projectionMatrix)); glCallList(displayList); } 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(const Mesh::Group &g : mesh->indiceGroups) { // init indices vbos glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INDICES_BUFFER])); glAssert(glBufferData(GL_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; iindiceGroups.size(); ++i) { PhongMaterial* mat = (PhongMaterial*)(mesh->indiceGroups[i].material); mat->bindAttributes(); glAssert(glBegin(GL_TRIANGLES)); for(int j=0; jindiceGroups[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) { 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()) { 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()) { 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()) { 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(glDrawElements(GL_TRIANGLES, mesh->indiceGroups[groupId].indices.size(), GL_UNSIGNED_INT, mesh->indiceGroups[groupId].indices.data())); } 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; }