126 lines
3.5 KiB
C++
126 lines
3.5 KiB
C++
#include "mesh.h"
|
|
#include <glm/ext.hpp>
|
|
#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()));
|
|
}
|
|
}
|
|
|