fixed terrain tiles generation
[demo] / src / opengl / mesh-gl.cc
index e7cf44d..dd73bf3 100644 (file)
@@ -1,4 +1,5 @@
 #include <GL/glew.h>
+#include <GL/gl.h>
 #include <gmath/gmath.h>
 
 #include "mesh-gl.h"
@@ -14,6 +15,9 @@ MeshGL::MeshGL()
 
        num_vertices = 0;
        num_indices = 0;
+
+       /* draw normals */
+       nvao = nvbo = 0;
 }
 
 MeshGL::MeshGL(const MeshGL &mesh)
@@ -27,6 +31,10 @@ MeshGL::MeshGL(const MeshGL &mesh)
        vbo_normals = 0;
        vbo_tex_coords = 0;
        ibo = 0;
+       vao = 0;
+
+       /* draw normals */
+       nvao = nvbo = 0;
 
        /*
         * if we set these to the actual
@@ -65,12 +73,45 @@ MeshGL::~MeshGL()
 
 void MeshGL::draw() const
 {
+       if(!vdata_valid) {
+               ((MeshGL*)this)->update_vertex_data();
+       }
        glBindVertexArray(vao);
 
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
-       glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, 0);
+       glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, 0);
+
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+       glBindVertexArray(0);
+}
 
+void MeshGL::draw_normals(float scale) const
+{
+       if(!nvao) {
+               glGenVertexArrays(1, &nvao);
+               glBindVertexArray(nvao);
+
+               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);
 }
 
@@ -81,6 +122,11 @@ void MeshGL::update_vertex_data()
 
 void MeshGL::update_vbo()
 {
+       if(vertices.empty()) {
+               printf("empty vertices\n");
+               return;
+       }
+
        /* vao */
        if(!vao)
                glGenVertexArrays(1, &vao);
@@ -92,13 +138,12 @@ void MeshGL::update_vbo()
                glGenBuffers(1, &vbo_vertices);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
        if(num_vertices != (int)vertices.size())
-               glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float) * 3,
-                            &vertices, GL_STATIC_DRAW);
+               glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vec3),
+                            &vertices[0], GL_STATIC_DRAW);
        else
-               glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float) * 3,
-                               &vertices);
-       num_vertices = vertices.size();
-       glBindBuffer(GL_ARRAY_BUFFER, 0);
+               glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vec3),
+                               &vertices[0]);
+       glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
 
        /* normals */
 
@@ -106,22 +151,25 @@ void MeshGL::update_vbo()
                glGenBuffers(1, &vbo_normals);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
        if(num_vertices != (int)normals.size())
-               glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float) * 3,
-                            &normals, GL_STATIC_DRAW);
+               glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3),
+                            &normals[0], GL_STATIC_DRAW);
        else
-               glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * sizeof(float) * 3,
-                               &normals);
-       glBindBuffer(GL_ARRAY_BUFFER, 0);
+               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(float) * 2, &tex_coords, GL_STATIC_DRAW);
+               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(float) * 2, &tex_coords);
-       glBindBuffer(GL_ARRAY_BUFFER, 0);
+               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 */
 
@@ -134,22 +182,15 @@ void MeshGL::update_vbo()
        else
                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
                                &indices[0]);
+
        num_indices = indices.size();
-       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
        glEnableVertexAttribArray(MESH_VERTEX);
        glEnableVertexAttribArray(MESH_NORMAL);
        glEnableVertexAttribArray(MESH_TEXTURE);
 
-       glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
-       glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
-
-       glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
-       glVertexAttribPointer(MESH_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
-
-       glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords);
-       glVertexAttribPointer(MESH_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vec2), 0);
-
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+       glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
 }
 
@@ -162,6 +203,12 @@ void MeshGL::destroy_vbo()
        if(vbo_tex_coords)
                glDeleteBuffers(1, &vbo_tex_coords);
        if(ibo)
-               if(vao)
-                       glDeleteVertexArrays(1, &vao);
+               glDeleteBuffers(1, &ibo);
+       if (vao)
+               glDeleteVertexArrays(1, &vao);
+
+       if(nvbo)
+               glDeleteBuffers(1, &nvbo);
+       if(nvao)
+               glDeleteVertexArrays(1, &nvao);
 }
\ No newline at end of file