c3gl: Implemented buffer objects and vertex array objects
authorMichel Pollet <buserror@gmail.com>
Wed, 13 Jun 2012 17:17:12 +0000 (18:17 +0100)
committerMichel Pollet <buserror@gmail.com>
Wed, 13 Jun 2012 17:17:12 +0000 (18:17 +0100)
Supports vertex objects. Still need support for updating them

Signed-off-by: Michel Pollet <buserror@gmail.com>
examples/board_reprap/src/reprap_gl.c
examples/shared/libc3/srcgl/c3gl.c

index 2ed140c..f9b5750 100644 (file)
@@ -279,9 +279,10 @@ _gl_display_cb(void)               /* function called whenever redisplay needed */
 
        glMatrixMode(GL_PROJECTION); // Select projection matrix
        glLoadIdentity(); // Start with an identity matrix
-       glOrtho(0, _w, 0, _h, 0, 10);
-       glScalef(1, -1, 1);
-       glTranslatef(0, -1 * _h, 0);
+
+       c3mat4 pro = screen_ortho3D(0, _w, 0, _h, 0, 10);
+       glLoadMatrixf(pro.n);
+
        glMatrixMode(GL_MODELVIEW); // Select modelview matrix
 
        if (hud)
@@ -397,12 +398,7 @@ gl_init(
 
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
-       /*
-       glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
-       glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
-       glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-       glEnable(GL_LINE_SMOOTH);
-        */
+
        // enable color tracking
        glEnable(GL_COLOR_MATERIAL);
        // set material properties which will be assigned by glColor
@@ -430,7 +426,7 @@ gl_init(
        }
 
        /*
-        * Extract the GLSL version as a nuneric value for later
+        * Extract the GLSL version as a numeric value for later
         */
        const char * glsl = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
        {
index 513a79b..e9cbc7a 100644 (file)
@@ -197,6 +197,108 @@ _c3_load_pixels(
        }
 }
 
+static void _c3_create_buffer(
+               GLuint name,
+        GLuint bufferType,
+        void * data,
+        size_t dataSize,
+        GLuint * out)
+{
+       GLuint bid;
+       glGenBuffers(1, &bid);
+
+       GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, bid));
+       GLCHECK(glBufferData(GL_ARRAY_BUFFER,
+                       dataSize,
+               data,
+               bufferType));
+       GLCHECK(glEnableClientState(name));
+}
+
+static void
+_c3_load_vbo(
+               c3geometry_p g)
+{
+       if (!g->bid) {
+               GLuint  vao;
+               glGenVertexArrays(1, &vao);
+               g->bid = (c3apiobject_t)vao;
+       }
+       glBindVertexArray((GLuint)g->bid);
+
+       /*
+        * Use 'realloc' on the array as it frees the data, but leaves 'count'
+        * unchanged. We neec that for the vertices and the indexes, the others
+        * can have a straight free()
+        */
+       if (!g->vertice.buffer.bid && g->vertice.count) {
+               GLuint bid;
+
+               _c3_create_buffer(GL_VERTEX_ARRAY,
+                               g->vertice.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
+                               g->vertice.e, g->vertice.count * sizeof(g->vertice.e[0]),
+                               &bid);
+               glVertexPointer(3, GL_FLOAT, 0, (void*)0);
+               g->vertice.buffer.bid = (c3apiobject_t)bid;
+               if (!g->vertice.buffer.mutable)
+                       c3vertex_array_realloc(&g->vertice, 0);
+               g->vertice.buffer.dirty = 0;
+       }
+       if (!g->textures.buffer.bid && g->textures.count) {
+               GLuint bid;
+
+               _c3_create_buffer(GL_TEXTURE_COORD_ARRAY,
+                               g->textures.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
+                               g->textures.e, g->textures.count * sizeof(g->textures.e[0]),
+                               &bid);
+               glTexCoordPointer(2, GL_FLOAT, 0, (void*)0);
+               g->textures.buffer.bid = (c3apiobject_t)bid;
+               if (!g->textures.buffer.mutable)
+                       c3tex_array_free(&g->textures);
+               g->textures.buffer.dirty = 0;
+       }
+       if (!g->normals.buffer.bid && g->normals.count) {
+               GLuint bid;
+
+               _c3_create_buffer(GL_NORMAL_ARRAY,
+                               g->normals.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
+                               g->normals.e, g->normals.count * sizeof(g->normals.e[0]),
+                               &bid);
+               glNormalPointer(GL_FLOAT, 0, (void*) 0);
+               g->normals.buffer.bid = (c3apiobject_t)bid;
+               if (!g->normals.buffer.mutable)
+                       c3vertex_array_free(&g->normals);
+               g->normals.buffer.dirty = 0;
+       }
+       if (!g->colorf.buffer.bid && g->colorf.count) {
+               GLuint bid;
+
+               _c3_create_buffer(GL_COLOR_ARRAY,
+                               g->colorf.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
+                               g->colorf.e, g->colorf.count * sizeof(g->colorf.e[0]),
+                               &bid);
+               glColorPointer(4, GL_FLOAT, 0, (void*) 0);
+               g->colorf.buffer.bid = (c3apiobject_t)bid;
+               if (!g->colorf.buffer.mutable)
+                       c3colorf_array_free(&g->colorf);
+               g->colorf.buffer.dirty = 0;
+       }
+       if (!g->indices.buffer.bid && g->indices.count) {
+               GLuint bid;
+               glGenBuffers(1, &bid);
+
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bid);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+                       g->indices.count * sizeof(g->indices.e[0]),
+                       g->indices.e,
+                       g->indices.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+               g->indices.buffer.bid = (c3apiobject_t)bid;
+               if (!g->indices.buffer.mutable)
+                       c3indices_array_realloc(&g->indices, 0);
+               g->indices.buffer.dirty = 0;
+       }
+}
+
 static void
 _c3_geometry_project(
                c3context_p c,
@@ -222,6 +324,11 @@ _c3_geometry_project(
                default:
                    break;
        }
+
+       _c3_load_vbo(g);
+//     _c3_update_vbo(g);
+
+       glBindVertexArray(0);
 }
 
 /*
@@ -237,15 +344,14 @@ _c3_geometry_draw(
        glColor4fv(g->mat.color.n);
        dumpError("glColor");
 //     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->mat.color.n);
-       glVertexPointer(3, GL_FLOAT, 0, g->vertice.e);
-       glEnableClientState(GL_VERTEX_ARRAY);
-       dumpError("GL_VERTEX_ARRAY");
 
        c3mat4 eye = c3mat4_mul(
                        &g->object->world,
                        &c3context_view_get(g->object->context)->cam.mtx);
        glLoadMatrixf(eye.n);
 
+       GLCHECK(glBindVertexArray((GLuint)g->bid));
+
        glDisable(GL_TEXTURE_2D);
        if (g->mat.texture) {
                GLuint mode = g->mat.texture->normalize ?
@@ -258,27 +364,19 @@ _c3_geometry_draw(
                dumpError("glEnable texture");
                glBindTexture(mode, (GLuint)g->mat.texture->texture);
                dumpError("glBindTexture");
-               glTexCoordPointer(2, GL_FLOAT, 0, g->textures.e);
-               glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-               dumpError("GL_TEXTURE_COORD_ARRAY");
        }
-       if (g->mat.program) {
+       if (g->mat.program)
                GLCHECK(glUseProgram((GLuint)g->mat.program->pid));
-       }
-       if (g->normals.count) {
-               GLCHECK(glNormalPointer(GL_FLOAT, 0, g->normals.e));
-               glEnableClientState(GL_NORMAL_ARRAY);
-       }
-       if (g->indices.count) {
+
+       if (g->indices.buffer.bid) {
                GLCHECK(glDrawElements((GLuint)g->type.subtype,
                                g->indices.count, GL_UNSIGNED_SHORT,
-                               g->indices.e));
+                               (void*)NULL /*g->indices.e*/));
        } else {
                glDrawArrays((GLuint)g->type.subtype, 0, g->vertice.count);
        }
-       glDisableClientState(GL_VERTEX_ARRAY);
-       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-       glDisableClientState(GL_NORMAL_ARRAY);
+       glBindVertexArray(0);
+
        if (g->mat.texture)
                glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
        if (g->mat.program)