+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;
+ }
+}
+