From ed0727a606ebd6d244f2331fd91cc7f8764acd93 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 6 Mar 2017 18:36:11 +0100 Subject: [PATCH] move VBO rendering code into its own method --- src/Mod/Part/Gui/SoBrepFaceSet.cpp | 647 ++++++++++++++++------------- 1 file changed, 350 insertions(+), 297 deletions(-) diff --git a/src/Mod/Part/Gui/SoBrepFaceSet.cpp b/src/Mod/Part/Gui/SoBrepFaceSet.cpp index 596599aa7..8494a3ca4 100644 --- a/src/Mod/Part/Gui/SoBrepFaceSet.cpp +++ b/src/Mod/Part/Gui/SoBrepFaceSet.cpp @@ -129,6 +129,22 @@ public: } } + void render(SoGLRenderAction * action, + const SoGLCoordinateElement * const vertexlist, + const int32_t *vertexindices, + int num_vertexindices, + const int32_t *partindices, + int num_partindices, + const SbVec3f *normals, + const int32_t *normindices, + SoMaterialBundle *const materials, + const int32_t *matindices, + SoTextureCoordinateBundle * const texcoords, + const int32_t *texindices, + const int nbind, + const int mbind, + const int texture); + static void context_destruction_cb(uint32_t context, void * userdata) { Buffer buffer; @@ -942,8 +958,7 @@ void SoBrepFaceSet::renderSelection(SoGLRenderAction *action) this->readUnlockNormalCache(); } -void SoBrepFaceSet::renderShape(SoGLRenderAction * action, - SbBool hasVBO, +void SoBrepFaceSet::VBO::render(SoGLRenderAction * action, const SoGLCoordinateElement * const vertexlist, const int32_t *vertexindices, int num_indices, @@ -959,11 +974,8 @@ void SoBrepFaceSet::renderShape(SoGLRenderAction * action, const int mbind, const int texture) { - int texidx = 0; - const SbVec3f * coords3d = NULL; SbVec3f * cur_coords3d = NULL; - SbColor mycolor1,mycolor2,mycolor3; coords3d = vertexlist->getArrayPtr3(); cur_coords3d = ( SbVec3f *)coords3d; @@ -981,309 +993,350 @@ void SoBrepFaceSet::renderShape(SoGLRenderAction * action, int matnr = 0; int trinr = 0; - // Can we use vertex buffer objects? - if (hasVBO) { - float * vertex_array = NULL; - GLuint * index_array = NULL; - SbVec3f *mynormal1,*mynormal2,*mynormal3; - int indice=0; - uint32_t RGBA,R,G,B,A; - float Rf,Gf,Bf,Af; + float * vertex_array = NULL; + GLuint * index_array = NULL; + SbColor mycolor1,mycolor2,mycolor3; + SbVec3f *mynormal1,*mynormal2,*mynormal3; + int indice=0; + uint32_t RGBA,R,G,B,A; + float Rf,Gf,Bf,Af; - VBO::Buffer buf; - uint32_t contextId = action->getCacheContext(); - std::map::iterator it = PRIVATE(this)->vbomap.find(contextId); - if (it == PRIVATE(this)->vbomap.end()) { -#ifdef FC_OS_WIN32 - const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); - PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)cc_glglue_getprocaddress(glue, "glGenBuffersARB"); -#endif - glGenBuffersARB(2, buf.myvbo); - PRIVATE(this)->vbomap[contextId] = buf; - } - else { - buf = it->second; - } - - // vbo loaded is defining if we must pre-load data into the VBO. When the variable is set to 0 - // it means that the VBO has not been initialized - // updateVbo is tracking the need to update the content of the VBO which act as a buffer within - // the graphic card - // TODO FINISHING THE COLOR SUPPORT ! - - if (!PRIVATE(this)->vboLoaded || PRIVATE(this)->updateVbo) { -#ifdef FC_OS_WIN32 - const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); -#endif - if (PRIVATE(this)->updateVbo && PRIVATE(this)->vboLoaded) { - // TODO - // We must remember the buffer size ... If it has to be extended we must - // take care of that -#ifdef FC_OS_WIN32 - PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC) cc_glglue_getprocaddress(glue, "glBindBufferARB"); - PFNGLMAPBUFFERARBPROC glMapBufferARB = (PFNGLMAPBUFFERARBPROC) cc_glglue_getprocaddress(glue, "glMapBufferARB"); -#endif - glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); - - vertex_array=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - index_array=(GLuint *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - PRIVATE(this)->indice_array=0; - } - else { - // We are allocating local buffer to transfer initial VBO content - vertex_array = ( float * ) malloc ( sizeof(float) * num_indices *10 ); - index_array = ( GLuint *) malloc ( sizeof(GLuint) * num_indices *3 ); - } - - // Get the initial colors - SoState * state = action->getState(); - mycolor1=SoLazyElement::getDiffuse(state,0); - mycolor2=SoLazyElement::getDiffuse(state,0); - mycolor3=SoLazyElement::getDiffuse(state,0); - - pi = piptr < piendptr ? *piptr++ : -1; - while (pi == 0) { - // It may happen that a part has no triangles - pi = piptr < piendptr ? *piptr++ : -1; - if (mbind == PER_PART) - matnr++; - else if (mbind == PER_PART_INDEXED) - matindices++; - } - - while (viptr + 2 < viendptr) { - v1 = *viptr++; - v2 = *viptr++; - v3 = *viptr++; - // This test is for robustness upon buggy data sets - if (v1 < 0 || v2 < 0 || v3 < 0 || - v1 >= numverts || v2 >= numverts || v3 >= numverts) { - break; - } - v4 = viptr < viendptr ? *viptr++ : -1; - (void)v4; - - if (mbind == PER_PART) { - if (trinr == 0) { - materials->send(matnr++, true); - mycolor1=SoLazyElement::getDiffuse(state,matnr-1); - mycolor2=mycolor1; - mycolor3=mycolor1; - } - } - else if (mbind == PER_PART_INDEXED) { - if (trinr == 0) - materials->send(*matindices++, true); - } - else if (mbind == PER_VERTEX || mbind == PER_FACE) { - materials->send(matnr++, true); - } - else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { - materials->send(*matindices++, true); - } - - if (normals) { - if (nbind == PER_VERTEX || nbind == PER_FACE) { - currnormal = normals++; - mynormal1=(SbVec3f *)currnormal; - } - else if (nbind == PER_VERTEX_INDEXED || nbind == PER_FACE_INDEXED) { - currnormal = &normals[*normalindices++]; - mynormal1 =(SbVec3f *) currnormal; - } - } - if (mbind == PER_VERTEX) - materials->send(matnr++, true); - else if (mbind == PER_VERTEX_INDEXED) - materials->send(*matindices++, true); - - if (normals) { - if (nbind == PER_VERTEX) { - currnormal = normals++; - mynormal2 = (SbVec3f *)currnormal; - } - else if (nbind == PER_VERTEX_INDEXED) { - currnormal = &normals[*normalindices++]; - mynormal2 = (SbVec3f *)currnormal; - } - } - - if (mbind == PER_VERTEX) - materials->send(matnr++, true); - else if (mbind == PER_VERTEX_INDEXED) - materials->send(*matindices++, true); - if (normals) { - if (nbind == PER_VERTEX) { - currnormal = normals++; - mynormal3 =(SbVec3f *)currnormal; - } - else if (nbind == PER_VERTEX_INDEXED) { - currnormal = &normals[*normalindices++]; - mynormal3 = (SbVec3f *)currnormal; - } - } - if (nbind == PER_VERTEX_INDEXED) - normalindices++; - - /* We building the Vertex dataset there and push it to a VBO */ - /* The Vertex array shall contain per element vertex_coordinates[3], - normal_coordinates[3], color_value[3] (RGBA format) */ - - index_array[PRIVATE(this)->indice_array] = PRIVATE(this)->indice_array; - index_array[PRIVATE(this)->indice_array+1] = PRIVATE(this)->indice_array + 1; - index_array[PRIVATE(this)->indice_array+2] = PRIVATE(this)->indice_array + 2; - PRIVATE(this)->indice_array += 3; - - - ((SbVec3f *)(cur_coords3d+v1 ))->getValue(vertex_array[indice+0], - vertex_array[indice+1], - vertex_array[indice+2]); - - ((SbVec3f *)(mynormal1))->getValue(vertex_array[indice+3], - vertex_array[indice+4], - vertex_array[indice+5]); - - /* We decode the Vertex1 color */ - RGBA = mycolor1.getPackedValue(); - R = ( RGBA & 0xFF000000 ) >> 24 ; - G = ( RGBA & 0xFF0000 ) >> 16; - B = ( RGBA & 0xFF00 ) >> 8; - A = ( RGBA & 0xFF ); - - Rf = (((float )R) / 255.0); - Gf = (((float )G) / 255.0); - Bf = (((float )B) / 255.0); - Af = (((float )A) / 255.0); - - vertex_array[indice+6] = Rf; - vertex_array[indice+7] = Gf; - vertex_array[indice+8] = Bf; - vertex_array[indice+9] = Af; - indice+=10; - - ((SbVec3f *)(cur_coords3d+v2))->getValue(vertex_array[indice+0], - vertex_array[indice+1], - vertex_array[indice+2]); - ((SbVec3f *)(mynormal2))->getValue(vertex_array[indice+3], - vertex_array[indice+4], - vertex_array[indice+5]); - - RGBA = mycolor2.getPackedValue(); - R = ( RGBA & 0xFF000000 ) >> 24 ; - G = ( RGBA & 0xFF0000 ) >> 16; - B = ( RGBA & 0xFF00 ) >> 8; - A = ( RGBA & 0xFF ); - - Rf = (((float )R) / 255.0); - Gf = (((float )G) / 255.0); - Bf = (((float )B) / 255.0); - Af = (((float )A) / 255.0); - - vertex_array[indice+6] = Rf; - vertex_array[indice+7] = Gf; - vertex_array[indice+8] = Bf; - vertex_array[indice+9] = Af; - indice+=10; - - ((SbVec3f *)(cur_coords3d+v3))->getValue(vertex_array[indice+0], - vertex_array[indice+1], - vertex_array[indice+2]); - ((SbVec3f *)(mynormal3))->getValue(vertex_array[indice+3], - vertex_array[indice+4], - vertex_array[indice+5]); - - RGBA = mycolor3.getPackedValue(); - R = ( RGBA & 0xFF000000 ) >> 24 ; - G = ( RGBA & 0xFF0000 ) >> 16; - B = ( RGBA & 0xFF00 ) >> 8; - A = ( RGBA & 0xFF ); - - Rf = (((float )R) / 255.0); - Gf = (((float )G) / 255.0); - Bf = (((float )B) / 255.0); - Af = (((float )A) / 255.0); - - vertex_array[indice+6] = Rf; - vertex_array[indice+7] = Gf; - vertex_array[indice+8] = Bf; - vertex_array[indice+9] = Af; - indice+=10; - - /* ============================================================ */ - trinr++; - if (pi == trinr) { - pi = piptr < piendptr ? *piptr++ : -1; - while (pi == 0) { - // It may happen that a part has no triangles - pi = piptr < piendptr ? *piptr++ : -1; - if (mbind == PER_PART) - matnr++; - else if (mbind == PER_PART_INDEXED) - matindices++; - } - trinr = 0; - } - } - - if (!PRIVATE(this)->updateVbo || !PRIVATE(this)->vboLoaded) { - // Push the content to the VBO -#ifdef FC_OS_WIN32 - PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); - PFNGLBUFFERDATAARBPROC glBufferDataARB = (PFNGLBUFFERDATAARBPROC)cc_glglue_getprocaddress(glue, "glBufferDataARB"); -#endif - - glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float) * indice , vertex_array, GL_DYNAMIC_DRAW_ARB); - - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLuint) * PRIVATE(this)->indice_array , &index_array[0], GL_DYNAMIC_DRAW_ARB); - - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - - PRIVATE(this)->vboLoaded = true; - PRIVATE(this)->updateVbo = false; - free(vertex_array); - free(index_array); - } - else { -#ifdef FC_OS_WIN32 - PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glUnmapBufferARB"); -#endif - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); - glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); - PRIVATE(this)->updateVbo = false; - } - } - - // This is the VBO rendering code + VBO::Buffer buf; + uint32_t contextId = action->getCacheContext(); + std::map::iterator it = this->vbomap.find(contextId); + if (it == this->vbomap.end()) { #ifdef FC_OS_WIN32 const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); - PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); + PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)cc_glglue_getprocaddress(glue, "glGenBuffersARB"); +#endif + glGenBuffersARB(2, buf.myvbo); + this->vbomap[contextId] = buf; + } + else { + buf = it->second; + } + + // vbo loaded is defining if we must pre-load data into the VBO. When the variable is set to 0 + // it means that the VBO has not been initialized + // updateVbo is tracking the need to update the content of the VBO which act as a buffer within + // the graphic card + // TODO FINISHING THE COLOR SUPPORT ! + + if (!this->vboLoaded || this->updateVbo) { +#ifdef FC_OS_WIN32 + const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); +#endif + if (this->updateVbo && this->vboLoaded) { + // TODO + // We must remember the buffer size ... If it has to be extended we must + // take care of that +#ifdef FC_OS_WIN32 + PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC) cc_glglue_getprocaddress(glue, "glBindBufferARB"); + PFNGLMAPBUFFERARBPROC glMapBufferARB = (PFNGLMAPBUFFERARBPROC) cc_glglue_getprocaddress(glue, "glMapBufferARB"); +#endif + glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); + + vertex_array=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + index_array=(GLuint *)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + this->indice_array=0; + } + else { + // We are allocating local buffer to transfer initial VBO content + vertex_array = ( float * ) malloc ( sizeof(float) * num_indices *10 ); + index_array = ( GLuint *) malloc ( sizeof(GLuint) * num_indices *3 ); + } + + // Get the initial colors + SoState * state = action->getState(); + mycolor1=SoLazyElement::getDiffuse(state,0); + mycolor2=SoLazyElement::getDiffuse(state,0); + mycolor3=SoLazyElement::getDiffuse(state,0); + + pi = piptr < piendptr ? *piptr++ : -1; + while (pi == 0) { + // It may happen that a part has no triangles + pi = piptr < piendptr ? *piptr++ : -1; + if (mbind == PER_PART) + matnr++; + else if (mbind == PER_PART_INDEXED) + matindices++; + } + + while (viptr + 2 < viendptr) { + v1 = *viptr++; + v2 = *viptr++; + v3 = *viptr++; + // This test is for robustness upon buggy data sets + if (v1 < 0 || v2 < 0 || v3 < 0 || + v1 >= numverts || v2 >= numverts || v3 >= numverts) { + break; + } + v4 = viptr < viendptr ? *viptr++ : -1; + (void)v4; + + if (mbind == PER_PART) { + if (trinr == 0) { + materials->send(matnr++, true); + mycolor1=SoLazyElement::getDiffuse(state,matnr-1); + mycolor2=mycolor1; + mycolor3=mycolor1; + } + } + else if (mbind == PER_PART_INDEXED) { + if (trinr == 0) + materials->send(*matindices++, true); + } + else if (mbind == PER_VERTEX || mbind == PER_FACE) { + materials->send(matnr++, true); + } + else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { + materials->send(*matindices++, true); + } + + if (normals) { + if (nbind == PER_VERTEX || nbind == PER_FACE) { + currnormal = normals++; + mynormal1=(SbVec3f *)currnormal; + } + else if (nbind == PER_VERTEX_INDEXED || nbind == PER_FACE_INDEXED) { + currnormal = &normals[*normalindices++]; + mynormal1 =(SbVec3f *) currnormal; + } + } + if (mbind == PER_VERTEX) + materials->send(matnr++, true); + else if (mbind == PER_VERTEX_INDEXED) + materials->send(*matindices++, true); + + if (normals) { + if (nbind == PER_VERTEX) { + currnormal = normals++; + mynormal2 = (SbVec3f *)currnormal; + } + else if (nbind == PER_VERTEX_INDEXED) { + currnormal = &normals[*normalindices++]; + mynormal2 = (SbVec3f *)currnormal; + } + } + + if (mbind == PER_VERTEX) + materials->send(matnr++, true); + else if (mbind == PER_VERTEX_INDEXED) + materials->send(*matindices++, true); + if (normals) { + if (nbind == PER_VERTEX) { + currnormal = normals++; + mynormal3 =(SbVec3f *)currnormal; + } + else if (nbind == PER_VERTEX_INDEXED) { + currnormal = &normals[*normalindices++]; + mynormal3 = (SbVec3f *)currnormal; + } + } + if (nbind == PER_VERTEX_INDEXED) + normalindices++; + + /* We building the Vertex dataset there and push it to a VBO */ + /* The Vertex array shall contain per element vertex_coordinates[3], + normal_coordinates[3], color_value[3] (RGBA format) */ + + index_array[this->indice_array] = this->indice_array; + index_array[this->indice_array+1] = this->indice_array + 1; + index_array[this->indice_array+2] = this->indice_array + 2; + this->indice_array += 3; + + + ((SbVec3f *)(cur_coords3d+v1 ))->getValue(vertex_array[indice+0], + vertex_array[indice+1], + vertex_array[indice+2]); + + ((SbVec3f *)(mynormal1))->getValue(vertex_array[indice+3], + vertex_array[indice+4], + vertex_array[indice+5]); + + /* We decode the Vertex1 color */ + RGBA = mycolor1.getPackedValue(); + R = ( RGBA & 0xFF000000 ) >> 24 ; + G = ( RGBA & 0xFF0000 ) >> 16; + B = ( RGBA & 0xFF00 ) >> 8; + A = ( RGBA & 0xFF ); + + Rf = (((float )R) / 255.0); + Gf = (((float )G) / 255.0); + Bf = (((float )B) / 255.0); + Af = (((float )A) / 255.0); + + vertex_array[indice+6] = Rf; + vertex_array[indice+7] = Gf; + vertex_array[indice+8] = Bf; + vertex_array[indice+9] = Af; + indice+=10; + + ((SbVec3f *)(cur_coords3d+v2))->getValue(vertex_array[indice+0], + vertex_array[indice+1], + vertex_array[indice+2]); + ((SbVec3f *)(mynormal2))->getValue(vertex_array[indice+3], + vertex_array[indice+4], + vertex_array[indice+5]); + + RGBA = mycolor2.getPackedValue(); + R = ( RGBA & 0xFF000000 ) >> 24 ; + G = ( RGBA & 0xFF0000 ) >> 16; + B = ( RGBA & 0xFF00 ) >> 8; + A = ( RGBA & 0xFF ); + + Rf = (((float )R) / 255.0); + Gf = (((float )G) / 255.0); + Bf = (((float )B) / 255.0); + Af = (((float )A) / 255.0); + + vertex_array[indice+6] = Rf; + vertex_array[indice+7] = Gf; + vertex_array[indice+8] = Bf; + vertex_array[indice+9] = Af; + indice+=10; + + ((SbVec3f *)(cur_coords3d+v3))->getValue(vertex_array[indice+0], + vertex_array[indice+1], + vertex_array[indice+2]); + ((SbVec3f *)(mynormal3))->getValue(vertex_array[indice+3], + vertex_array[indice+4], + vertex_array[indice+5]); + + RGBA = mycolor3.getPackedValue(); + R = ( RGBA & 0xFF000000 ) >> 24 ; + G = ( RGBA & 0xFF0000 ) >> 16; + B = ( RGBA & 0xFF00 ) >> 8; + A = ( RGBA & 0xFF ); + + Rf = (((float )R) / 255.0); + Gf = (((float )G) / 255.0); + Bf = (((float )B) / 255.0); + Af = (((float )A) / 255.0); + + vertex_array[indice+6] = Rf; + vertex_array[indice+7] = Gf; + vertex_array[indice+8] = Bf; + vertex_array[indice+9] = Af; + indice+=10; + + /* ============================================================ */ + trinr++; + if (pi == trinr) { + pi = piptr < piendptr ? *piptr++ : -1; + while (pi == 0) { + // It may happen that a part has no triangles + pi = piptr < piendptr ? *piptr++ : -1; + if (mbind == PER_PART) + matnr++; + else if (mbind == PER_PART_INDEXED) + matindices++; + } + trinr = 0; + } + } + + if (!this->updateVbo || !this->vboLoaded) { + // Push the content to the VBO +#ifdef FC_OS_WIN32 + PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); + PFNGLBUFFERDATAARBPROC glBufferDataARB = (PFNGLBUFFERDATAARBPROC)cc_glglue_getprocaddress(glue, "glBufferDataARB"); #endif - glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float) * indice , vertex_array, GL_DYNAMIC_DRAW_ARB); - glVertexPointer(3,GL_FLOAT,10*sizeof(GLfloat),0); - glNormalPointer(GL_FLOAT,10*sizeof(GLfloat),(GLvoid *)(3*sizeof(GLfloat))); - glColorPointer(4,GL_FLOAT,10*sizeof(GLfloat),(GLvoid *)(6*sizeof(GLfloat))); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLuint) * this->indice_array , &index_array[0], GL_DYNAMIC_DRAW_ARB); - glDrawElements(GL_TRIANGLES, PRIVATE(this)->indice_array, GL_UNSIGNED_INT, (void *)0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - // The data is within the VBO we can clear it at application level + this->vboLoaded = true; + this->updateVbo = false; + free(vertex_array); + free(index_array); + } + else { +#ifdef FC_OS_WIN32 + PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glUnmapBufferARB"); +#endif + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); + this->updateVbo = false; + } + } + + // This is the VBO rendering code +#ifdef FC_OS_WIN32 + const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); + PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); +#endif + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf.myvbo[0]); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buf.myvbo[1]); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + glVertexPointer(3,GL_FLOAT,10*sizeof(GLfloat),0); + glNormalPointer(GL_FLOAT,10*sizeof(GLfloat),(GLvoid *)(3*sizeof(GLfloat))); + glColorPointer(4,GL_FLOAT,10*sizeof(GLfloat),(GLvoid *)(6*sizeof(GLfloat))); + + glDrawElements(GL_TRIANGLES, this->indice_array, GL_UNSIGNED_INT, (void *)0); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + // The data is within the VBO we can clear it at application level +} + +void SoBrepFaceSet::renderShape(SoGLRenderAction * action, + SbBool hasVBO, + const SoGLCoordinateElement * const vertexlist, + const int32_t *vertexindices, + int num_indices, + const int32_t *partindices, + int num_partindices, + const SbVec3f *normals, + const int32_t *normalindices, + SoMaterialBundle *const materials, + const int32_t *matindices, + SoTextureCoordinateBundle * const texcoords, + const int32_t *texindices, + const int nbind, + const int mbind, + const int texture) +{ + // Can we use vertex buffer objects? + if (hasVBO) { + PRIVATE(this)->render(action, vertexlist, vertexindices, num_indices, partindices, num_partindices, normals, + normalindices, materials, matindices, texcoords, texindices, nbind, mbind, texture); return; } + int texidx = 0; + + const SbVec3f * coords3d = NULL; + coords3d = vertexlist->getArrayPtr3(); + + const int32_t *viptr = vertexindices; + const int32_t *viendptr = viptr + num_indices; + const int32_t *piptr = partindices; + const int32_t *piendptr = piptr + num_partindices; + int32_t v1, v2, v3, v4, pi; + SbVec3f dummynormal(0,0,1); + int numverts = vertexlist->getNum(); + + const SbVec3f *currnormal = &dummynormal; + if (normals) currnormal = normals; + + int matnr = 0; + int trinr = 0; + // Legacy code without VBO support pi = piptr < piendptr ? *piptr++ : -1; while (pi == 0) {