#include "mesh.h" #include #include "glassert.h" #define BUFFER_OFFSET(i) ((char *)NULL + (i)) Mesh::~Mesh() { destroyGL(); } bool Mesh::hasNormals() { return normals.size() != 0; } bool Mesh::hasTexCoords() { return texCoords.size() != 0; } bool Mesh::hasTangents() { return tangents.size() != 0; } void Mesh::initGL(bool isDynamic) { if(locked) destroyGL(); GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; // create VAO glAssert(glGenVertexArrays(1, &vao)); glAssert(glBindVertexArray(vao)); int nb_buffers = 2; if(hasNormals()) ++nb_buffers; if(hasTexCoords()) ++nb_buffers; if(hasTangents()) ++nb_buffers; // create VBOs glAssert(glGenBuffers(nb_buffers, vbo)); // init indices vbo glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INDICES_BUFFER])); glAssert(glBufferData(GL_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)); locked = true; } void Mesh::destroyGL() { if(locked) { locked = false; glAssert(glDeleteVertexArrays(1, &vao)); glAssert(glDeleteBuffers(2, vbo)); } } void Mesh::draw() { if(locked) { 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(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(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(hasTangents()) { glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER])); glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Tangents), BUFFER_OFFSET(0))); glAssert(glEnableVertexAttribArray(3)); glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Tangents), BUFFER_OFFSET(sizeof(glm::vec3)))); glAssert(glEnableVertexAttribArray(4)); } glAssert(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data())); } }