#include <GL/glew.h>
+#include <GL/gl.h>
+#include <gmath/gmath.h>
#include "mesh-gl.h"
MeshGL::MeshGL()
{
- which_mask = 0;
-
vao = 0;
vbo_vertices = 0;
vbo_normals = 0;
+ vbo_tex_coords = 0;
ibo = 0;
num_vertices = 0;
num_indices = 0;
+
+ /* draw normals */
+ nvao = nvbo = 0;
}
MeshGL::MeshGL(const MeshGL &mesh)
indices = mesh.indices;
vertices = mesh.vertices;
normals = mesh.normals;
+ tex_coords = mesh.tex_coords;
vbo_vertices = 0;
vbo_normals = 0;
+ vbo_tex_coords = 0;
ibo = 0;
+ vao = 0;
+
+ /* draw normals */
+ nvao = nvbo = 0;
/*
* if we set these to the actual
indices = mesh.indices;
vertices = mesh.vertices;
normals = mesh.normals;
+ tex_coords = mesh.tex_coords;
return *this;
}
vertices.clear();
normals.clear();
+ tex_coords.clear();
+ indices.clear();
}
-/*
void MeshGL::draw() const
{
- // save the previously bound vao, vbo just in case
- int curr_vao;
- int curr_vbo;
- glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vao);
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &curr_vbo);
-
+ if(!vdata_valid) {
+ ((MeshGL *)this)->update_vertex_data();
+ }
glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
- glVertexPointer(3, GL_FLOAT, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
- glNormalPointer(GL_FLOAT, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
- glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
+ glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, 0);
+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
+ glBindVertexArray(0);
+}
+
+void MeshGL::draw_normals(float scale) const
+{
+ if(!nvao) {
+ glGenVertexArrays(1, &nvao);
+ glBindVertexArray(nvao);
- // return to previous state
- glBindBuffer(GL_ARRAY_BUFFER, curr_vbo);
- glBindVertexArray(curr_vao);
+ glGenBuffers(1, &nvbo);
+ glBindBuffer(GL_ARRAY_BUFFER, nvbo);
+
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3) * 2, 0, GL_STATIC_DRAW);
+ Vec3 *data = (Vec3 *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+ for(size_t i = 0; i < normals.size(); i++) {
+ *data++ = vertices[i];
+ *data++ = vertices[i] + normals[i] * scale;
+ }
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+
+ glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
+ glEnableVertexAttribArray(MESH_VERTEX);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ else {
+ glBindVertexArray(nvao);
+ }
+
+ glDrawArrays(GL_LINES, 0, normals.size() * 2);
+ glBindVertexArray(0);
}
-*/
-void MeshGL::update_vertex_data()
+bool MeshGL::update_vertex_data()
{
update_vbo();
+ return true;
}
void MeshGL::update_vbo()
{
- // save the previously bound vao, vbo just in case
- int curr_vao;
- int curr_vbo;
- glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vao);
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &curr_vbo);
+ if(vertices.empty()) {
+ printf("empty vertices\n");
+ return;
+ }
+ /* vao */
if(!vao)
glGenVertexArrays(1, &vao);
-
glBindVertexArray(vao);
- if(which_mask & MESH_NORMAL) {
- if(!vbo_normals) {
- glGenBuffers(1, &vbo_normals);
- }
- glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
- if(num_vertices != (int)normals.size()) {
- glBufferData(GL_ARRAY_BUFFER, normals.size() * 3 * sizeof(float),
- &normals[0], GL_STREAM_DRAW);
- }
- else {
- glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * 3 * sizeof(float),
- &normals[0]);
- }
- }
+ /* vertices */
- if(which_mask & MESH_VERTEX) {
- if(!vbo_vertices) {
- glGenBuffers(1, &vbo_vertices);
- }
- glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
- if(num_vertices != (int)vertices.size()) {
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float),
- &vertices[0], GL_STREAM_DRAW);
- }
- else {
- glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * 3 * sizeof(float),
- &vertices[0]);
- }
- num_vertices = vertices.size();
- }
+ if(!vbo_vertices)
+ glGenBuffers(1, &vbo_vertices);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
+ if(num_vertices != (int)vertices.size())
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vec3),
+ &vertices[0], GL_STATIC_DRAW);
+ else
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vec3),
+ &vertices[0]);
+ glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
+
+ /* normals */
+
+ if(!vbo_normals)
+ glGenBuffers(1, &vbo_normals);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
+ if(num_vertices != (int)normals.size())
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3),
+ &normals[0], GL_STATIC_DRAW);
+ else
+ glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * sizeof(Vec3),
+ &normals[0]);
+ glVertexAttribPointer(MESH_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
+
+ /* texture coordinates */
+
+ if(!vbo_tex_coords)
+ glGenBuffers(1, &vbo_tex_coords);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords);
+ if(num_vertices != (int)tex_coords.size())
+ glBufferData(GL_ARRAY_BUFFER, tex_coords.size() * sizeof(Vec2), &tex_coords[0], GL_STATIC_DRAW);
+ else
+ glBufferSubData(GL_ARRAY_BUFFER, 0, tex_coords.size() * sizeof(Vec2), &tex_coords[0]);
+ glVertexAttribPointer(MESH_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vec2), 0);
+
+ num_vertices = vertices.size();
+
+ /* indices */
+
+ if(!ibo)
+ glGenBuffers(1, &ibo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
+ if(num_indices != (int)indices.size())
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
+ &indices[0], GL_STATIC_DRAW);
+ else
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
+ &indices[0]);
- if(which_mask & MESH_INDEX) {
- if(!ibo) {
- glGenBuffers(1, &ibo);
- }
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
- if(num_indices != (int)indices.size()) {
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
- &indices[0], GL_STATIC_DRAW);
- }
- else {
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
- &indices[0]);
- }
- num_indices = indices.size();
- }
+ num_indices = indices.size();
- /* bind previously bound vbo */
- glBindBuffer(GL_ARRAY_BUFFER, curr_vbo);
- glBindVertexArray(curr_vao);
+ glEnableVertexAttribArray(MESH_VERTEX);
+ glEnableVertexAttribArray(MESH_NORMAL);
+ glEnableVertexAttribArray(MESH_TEXTURE);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
}
void MeshGL::destroy_vbo()
glDeleteBuffers(1, &vbo_vertices);
if(vbo_normals)
glDeleteBuffers(1, &vbo_normals);
+ if(vbo_tex_coords)
+ glDeleteBuffers(1, &vbo_tex_coords);
if(ibo)
glDeleteBuffers(1, &ibo);
if(vao)
glDeleteVertexArrays(1, &vao);
-}
\ No newline at end of file
+
+ if(nvbo)
+ glDeleteBuffers(1, &nvbo);
+ if(nvao)
+ glDeleteVertexArrays(1, &nvao);
+}