#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::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(NULL); 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())); } 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; }