diff --git a/src/Gui/DlgSettings3DView.ui b/src/Gui/DlgSettings3DView.ui index cdd34646e..56faa96d8 100644 --- a/src/Gui/DlgSettings3DView.ui +++ b/src/Gui/DlgSettings3DView.ui @@ -55,7 +55,7 @@ Use OpenGL Vertex Buffer Object (experimental) - useVBO + UseVBO View diff --git a/src/Gui/SplitView3DInventor.cpp b/src/Gui/SplitView3DInventor.cpp index b564c01b2..edbf9e4f4 100644 --- a/src/Gui/SplitView3DInventor.cpp +++ b/src/Gui/SplitView3DInventor.cpp @@ -89,7 +89,7 @@ void AbstractSplitView::setupSettings() OnChange(*hGrp,"UseBackgroundColorMid"); OnChange(*hGrp,"UseAntialiasing"); OnChange(*hGrp,"ShowFPS"); - OnChange(*hGrp,"useVBO"); + OnChange(*hGrp,"UseVBO"); OnChange(*hGrp,"Orthographic"); OnChange(*hGrp,"HeadlightColor"); OnChange(*hGrp,"HeadlightDirection"); @@ -227,11 +227,10 @@ void AbstractSplitView::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp else if (strcmp(Reason,"ShowFPS") == 0) { for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) (*it)->setEnabledFPSCounter(rGrp.GetBool("ShowFPS",false)); - puts("updating FPS 1"); } - else if (strcmp(Reason,"useVBO") == 0) { + else if (strcmp(Reason,"UseVBO") == 0) { for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) - (*it)->setEnableduseVBO(rGrp.GetBool("useVBO",false)); + (*it)->setEnabledVBO(rGrp.GetBool("UseVBO",false)); } else if (strcmp(Reason,"Orthographic") == 0) { diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index f00597c9d..751798705 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -177,7 +177,7 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, OnChange(*hGrp,"BackgroundColor4"); OnChange(*hGrp,"UseBackgroundColorMid"); OnChange(*hGrp,"ShowFPS"); - OnChange(*hGrp,"useVBO"); + OnChange(*hGrp,"UseVBO"); OnChange(*hGrp,"Orthographic"); OnChange(*hGrp,"HeadlightColor"); OnChange(*hGrp,"HeadlightDirection"); @@ -369,8 +369,8 @@ void View3DInventor::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M else if (strcmp(Reason,"ShowFPS") == 0) { _viewer->setEnabledFPSCounter(rGrp.GetBool("ShowFPS",false)); } - else if (strcmp(Reason,"useVBO") == 0) { - _viewer->setEnableduseVBO(rGrp.GetBool("useVBO",false)); + else if (strcmp(Reason,"UseVBO") == 0) { + _viewer->setEnabledVBO(rGrp.GetBool("UseVBO",false)); } else if (strcmp(Reason,"Orthographic") == 0) { // check whether a perspective or orthogrphic camera should be set diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 6aec28da4..5767e215d 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -351,6 +351,9 @@ View3DInventorViewer::View3DInventorViewer(const QGLFormat& format, QWidget* par void View3DInventorViewer::init() { + fpsEnabled = false; + vboEnabled = false; + Gui::Selection().Attach(this); // Coin should not clear the pixel-buffer, so the background image @@ -787,11 +790,16 @@ void View3DInventorViewer::setEnabledFPSCounter(bool on) fpsEnabled = on; } -void View3DInventorViewer::setEnableduseVBO(bool on) +void View3DInventorViewer::setEnabledVBO(bool on) { vboEnabled = on; } +bool View3DInventorViewer::isEnabledVBO() const +{ + return vboEnabled; +} + void View3DInventorViewer::setAxisCross(bool on) { SoNode* scene = getSceneGraph(); @@ -1344,10 +1352,7 @@ void View3DInventorViewer::actualRedraw() break; } } -bool View3DInventorViewer::get_vbo_state() -{ - return vboEnabled; -} + void View3DInventorViewer::renderFramebuffer() { const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion(); @@ -1450,7 +1455,6 @@ void View3DInventorViewer::renderScene(void) SoGLRenderActionElement::set(glra->getState(), glra); glra->apply(this->backgroundroot); - navigation->updateAnimation(); try { diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 1a59eacab..a2e76a71c 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -93,10 +93,9 @@ public: ShowCoord=1, /**< Enables the Coordinate system in the corner. */ ShowFPS =2, /**< Enables the Frams per Second counter. */ SimpleBackground=4,/**< switch to a simple background. */ - DisallowRotation=8,/**< switch of the rotation. */ - DisallowPanning=16,/**< switch of the panning. */ - DisallowZooming=32,/**< switch of the zooming. */ - useVBO=64,/**< switch of the OpenGL VBO usage. */ + DisallowRotation=8,/**< switch off the rotation. */ + DisallowPanning=16,/**< switch off the panning. */ + DisallowZooming=32,/**< switch off the zooming. */ }; //@} @@ -340,7 +339,8 @@ public: bool hasAxisCross(void); void setEnabledFPSCounter(bool b); - void setEnableduseVBO(bool b); + void setEnabledVBO(bool b); + bool isEnabledVBO() const; NavigationStyle* navigationStyle() const; @@ -348,8 +348,6 @@ public: Gui::Document* getDocument(); virtual PyObject *getPyObject(void); - bool vboEnabled; - bool get_vbo_state(); protected: void renderScene(); @@ -423,7 +421,7 @@ private: //stuff needed to draw the fps counter bool fpsEnabled; - SoSeparator* fpsRoot; + bool vboEnabled; SbBool editing; QCursor editCursor, zoomCursor, panCursor, spinCursor; diff --git a/src/Mod/Part/Gui/SoBrepFaceSet.cpp b/src/Mod/Part/Gui/SoBrepFaceSet.cpp index c6d175da4..dcdf15a4d 100644 --- a/src/Mod/Part/Gui/SoBrepFaceSet.cpp +++ b/src/Mod/Part/Gui/SoBrepFaceSet.cpp @@ -108,64 +108,30 @@ SoBrepFaceSet::SoBrepFaceSet() SO_NODE_ADD_FIELD(highlightIndex, (-1)); SO_NODE_ADD_FIELD(selectionIndex, (-1)); -// We are creating the VBO - vbo_available=0; -#ifdef GL_NUM_EXTENSIONS -// We are running OpenGL version higher than 3.0 -/* GLint n,i; - glGetIntegerv(GL_NUM_EXTENSIONS, &n); - for ( i = 0 ; i < n ; i++ ) - { - if ( strstr(glGetStringi(GL_EXTENSIONS, i),"GL_ARB_vertex_buffer_object") != NULL ) - vbo_available=1; + static bool init = false; + static bool vertex_buffer_object = false; + if (!init) { + std::string ext = (const char*)(glGetString(GL_EXTENSIONS)); + vertex_buffer_object = (ext.find("GL_ARB_vertex_buffer_object") != std::string::npos); + init = true; } -*/ -// we are assuming that the VBO extension is available ! - vbo_available=1; -#else -// We are probably running an old OpenGL version -// Must check into the GL_EXTENSIONS string instead - GL_extension=(char *)glGetString(GL_EXTENSIONS); - if ( strstr((char *)GL_extension,(char *)"GL_ARB_vertex_buffer_object") != NULL ) - vbo_available=1; -#endif + vboAvailable = vertex_buffer_object; -#ifdef FC_OS_WIN32 - /* Windows OpenGL implementation is very basic (aka 1.4) */ -/* if ( myglGenBuffers == NULL ) - { - myglGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffersARB"); - myglDeleteBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glDeleteBuffersARB"); - myglBindBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glBindBuffersARB"); - myglBufferData = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glBufferDataARB"); - myglMapBufferARB = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glMapBufferARB"); - myglunMapBufferARB = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glunMapBufferARB"); - myglEnableClientState = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glEnableClientState"); - myglDisableClientState = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glDisableClientState"); - myglVertexPointer = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glVertexPointer"); - myglNormalPointer = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glNormalPointer"); - myglColorPointer = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glColorPointer"); - myglDrawElements = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glDrawElements"); - } -*/ -#endif #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 - const QGLContext* gl = QGLContext::currentContext(); + const QGLContext* gl = QGLContext::currentContext(); #else - QOpenGLContext* gl = QOpenGLContext::currentContext(); + QOpenGLContext* gl = QOpenGLContext::currentContext(); #endif - PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)gl->getProcAddress(_PROC("glGenBuffersARB")); + PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)gl->getProcAddress(_PROC("glGenBuffersARB")); #endif - vbo_available=1; - update_vbo=0; - if ( vbo_available ) - { - glGenBuffersARB(2, &myvbo[0]); - vbo_loaded=0; - indice_array=0; + updateVbo = false; + if (vboAvailable) { + glGenBuffersARB(2, &myvbo[0]); + vboLoaded = false; + indice_array = 0; } selectionIndex.setNum(0); } @@ -174,7 +140,7 @@ SoBrepFaceSet::~SoBrepFaceSet() { #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 - const QGLContext* gl = QGLContext::currentContext(); + const QGLContext* gl = QGLContext::currentContext(); #else QOpenGLContext* gl = QOpenGLContext::currentContext(); #endif @@ -182,7 +148,7 @@ SoBrepFaceSet::~SoBrepFaceSet() return; PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)gl->getProcAddress(_PROC("glDeleteBuffersARB")); #endif - glDeleteBuffersARB(2, &myvbo[0]); + glDeleteBuffersARB(2, &myvbo[0]); } void SoBrepFaceSet::doAction(SoAction* action) @@ -295,6 +261,7 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action) SoTextureCoordinateBundle tb(action, true, false); SbBool doTextures = tb.needCoordinates(); + int32_t hl_idx = this->highlightIndex.getValue(); int32_t num_selected = this->selectionIndex.getNum(); @@ -351,11 +318,13 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action) if (!nindices) nindices = cindices; pindices = this->partIndex.getValues(0); numparts = this->partIndex.getNum(); - renderShape(static_cast(coords), cindices, numindices, + + renderShape(state, static_cast(coords), cindices, numindices, pindices, numparts, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0); // Disable caching for this node SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); + // Workaround for #0000433 //#if !defined(FC_OS_WIN32) if (hl_idx >= 0) @@ -380,6 +349,7 @@ void SoBrepFaceSet::renderSimpleArray() glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); + #if 0 glInterleavedArrays(GL_N3F_V3F, 0, vertex_array.data()); glDrawElements(GL_TRIANGLES, cnt, GL_UNSIGNED_INT, index_array.data()); @@ -443,8 +413,6 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action) return; SoState * state = action->getState(); - current_state=state; - Binding mbind = this->findMaterialBinding(state); Binding nbind = this->findNormalBinding(state); @@ -460,8 +428,6 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action) int numparts; SbBool doTextures; SbBool normalCacheUsed; - SbColor mycolor1; - SoMaterialBundle mb(action); @@ -475,20 +441,18 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action) mb.sendFirst(); // make sure we have the correct material - - // just in case someone forgot if (!mindices) mindices = cindices; if (!nindices) nindices = cindices; pindices = this->partIndex.getValues(0); numparts = this->partIndex.getNum(); - renderShape(static_cast(coords), cindices, numindices, + renderShape(state, static_cast(coords), cindices, numindices, pindices, numparts, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0); -// update_vbo=1; + // Disable caching for this node SoGLCacheContextElement::shouldAutoCache(state, SoGLCacheContextElement::DONT_AUTO_CACHE); - if(normalCacheUsed) + if (normalCacheUsed) this->readUnlockNormalCache(); // Workaround for #0000433 @@ -842,15 +806,16 @@ void SoBrepFaceSet::renderHighlight(SoGLRenderAction *action) // materials mbind = OVERALL; doTextures = false; - vbo_available=0; - // update_vbo=1; - renderShape(static_cast(coords), &(cindices[start]), length, + + SbBool tmp = vboAvailable; + vboAvailable = false; + renderShape(state, static_cast(coords), &(cindices[start]), length, &(pindices[id]), 1, normals, nindices, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0); - vbo_available=1; + vboAvailable = tmp; } state->pop(); - if(normalCacheUsed) + if (normalCacheUsed) this->readUnlockNormalCache(); } @@ -928,18 +893,21 @@ void SoBrepFaceSet::renderSelection(SoGLRenderAction *action) normals_s = &(normals[start]); else nbind = OVERALL; - vbo_available=0; - renderShape(static_cast(coords), &(cindices[start]), length, + + SbBool tmp = vboAvailable; + vboAvailable = false; + renderShape(state, static_cast(coords), &(cindices[start]), length, &(pindices[id]), 1, normals_s, nindices_s, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0); - vbo_available=1; + vboAvailable = tmp; } state->pop(); - if(normalCacheUsed) + if (normalCacheUsed) this->readUnlockNormalCache(); } -void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, +void SoBrepFaceSet::renderShape(SoState * state, + const SoGLCoordinateElement * const vertexlist, const int32_t *vertexindices, int num_indices, const int32_t *partindices, @@ -976,51 +944,43 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, int matnr = 0; int trinr = 0; - - /* This code detect if the user activated VBO through the preference menu */ Gui::Document* doc = Gui::Application::Instance->activeDocument(); Gui::View3DInventor* view; - if ( doc != NULL ) - view = static_cast(doc->getActiveView()); + if (doc != NULL) + view = static_cast(doc->getActiveView()); else - view = NULL; - bool ViewerVBO=false; - if ( view != NULL ) - { - Gui::View3DInventorViewer* viewer = view->getViewer(); - ViewerVBO=viewer->get_vbo_state(); + view = NULL; + bool ViewerVBO = false; + if (view != NULL) { + Gui::View3DInventorViewer* viewer = view->getViewer(); + ViewerVBO = viewer->isEnabledVBO(); } /* - vbo_available is used to determine if vbo is an avilable extension on the system . - This is not because end user wants VBO that it is available. - + vboAvailable is used to determine if vbo is an avilable extension on the system . + This is not because end user wants VBO that it is available. */ - if (( vbo_available ) && ViewerVBO ) - { - 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; + if (vboAvailable && ViewerVBO) { + 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; - // 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 - // update_vbo 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 ! + // 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 (( vbo_loaded == 0 ) || update_vbo ) - { - if ( ( update_vbo ) && vbo_loaded ) - { - // TODO - // We must remember the buffer size ... If it has to be extended we must - // take care of that - + if (!vboLoaded || updateVbo) { + if (updateVbo && vboLoaded) { + // TODO + // We must remember the buffer size ... If it has to be extended we must + // take care of that #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 const QGLContext* gl = QGLContext::currentContext(); @@ -1031,278 +991,277 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, PFNGLMAPBUFFERARBPROC glMapBufferARB = (PFNGLMAPBUFFERARBPROC) gl->getProcAddress(_PROC("glMapBufferARB")); #endif glBindBufferARB(GL_ARRAY_BUFFER_ARB, myvbo[0]); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 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); - 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 - mycolor1=SoLazyElement::getDiffuse(current_state,0); - mycolor2=SoLazyElement::getDiffuse(current_state,0); - mycolor3=SoLazyElement::getDiffuse(current_state,0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, myvbo[1]); - 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; + 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); + 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 ); + } - if (mbind == PER_PART) { - if (trinr == 0) - { - materials->send(matnr++, true); - mycolor1=SoLazyElement::getDiffuse(current_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++; + // Get the initial colors + mycolor1=SoLazyElement::getDiffuse(state,0); + mycolor2=SoLazyElement::getDiffuse(state,0); + mycolor3=SoLazyElement::getDiffuse(state,0); - /* 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) */ + 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++; + } - index_array[indice_array] = indice_array; - index_array[indice_array+1] = indice_array+1; - index_array[indice_array+2] = indice_array+2; - indice_array+=3; + 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[indice_array] = indice_array; + index_array[indice_array+1] = indice_array+1; + index_array[indice_array+2] = indice_array+2; + 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 ); + ((SbVec3f *)(cur_coords3d+v1 ))->getValue(vertex_array[indice+0], + vertex_array[indice+1], + vertex_array[indice+2]); - 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 *)(mynormal1))->getValue(vertex_array[indice+3], + vertex_array[indice+4], + vertex_array[indice+5]); - ((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]); + /* We decode the Vertex1 color */ + RGBA = mycolor1.getPackedValue(); + R = ( RGBA & 0xFF000000 ) >> 24 ; + G = ( RGBA & 0xFF0000 ) >> 16; + B = ( RGBA & 0xFF00 ) >> 8; + A = ( RGBA & 0xFF ); - 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; - Rf = (((float )R) / 255.0); - Gf = (((float )G) / 255.0); - Bf = (((float )B) / 255.0); - Af = (((float )A) / 255.0); + ((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 ); - vertex_array[indice+6] = Rf; - vertex_array[indice+7] = Gf; - vertex_array[indice+8] = Bf; - vertex_array[indice+9] = Af; - indice+=10; + Rf = (((float )R) / 255.0); + Gf = (((float )G) / 255.0); + Bf = (((float )B) / 255.0); + Af = (((float )A) / 255.0); - ((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]); + vertex_array[indice+6] = Rf; + vertex_array[indice+7] = Gf; + vertex_array[indice+8] = Bf; + vertex_array[indice+9] = Af; + indice+=10; - RGBA = mycolor3.getPackedValue(); - R = ( RGBA & 0xFF000000 ) >> 24 ; - G = ( RGBA & 0xFF0000 ) >> 16; - B = ( RGBA & 0xFF00 ) >> 8; - A = ( RGBA & 0xFF ); + ((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]); - Rf = (((float )R) / 255.0); - Gf = (((float )G) / 255.0); - Bf = (((float )B) / 255.0); - Af = (((float )A) / 255.0); + RGBA = mycolor3.getPackedValue(); + R = ( RGBA & 0xFF000000 ) >> 24 ; + G = ( RGBA & 0xFF0000 ) >> 16; + B = ( RGBA & 0xFF00 ) >> 8; + A = ( RGBA & 0xFF ); - vertex_array[indice+6] = Rf; - vertex_array[indice+7] = Gf; - vertex_array[indice+8] = Bf; - vertex_array[indice+9] = Af; - indice+=10; + Rf = (((float )R) / 255.0); + Gf = (((float )G) / 255.0); + Bf = (((float )B) / 255.0); + Af = (((float )A) / 255.0); - /* ============================================================ */ - 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; - } + vertex_array[indice+6] = Rf; + vertex_array[indice+7] = Gf; + vertex_array[indice+8] = Bf; + vertex_array[indice+9] = Af; + indice+=10; - } - if (( ! update_vbo ) || (!vbo_loaded) ) - { - // Push the content to the VBO + /* ============================================================ */ + 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 (!updateVbo || !vboLoaded) { + // Push the content to the VBO #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 - const QGLContext* gl = QGLContext::currentContext(); + const QGLContext* gl = QGLContext::currentContext(); #else - QOpenGLContext* gl = QOpenGLContext::currentContext(); + QOpenGLContext* gl = QOpenGLContext::currentContext(); #endif - PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)gl->getProcAddress(_PROC("glBindBufferARB")); - PFNGLBUFFERDATAARBPROC glBufferDataARB = (PFNGLBUFFERDATAARBPROC)gl->getProcAddress(_PROC("glBufferDataARB")); + PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)gl->getProcAddress(_PROC("glBindBufferARB")); + PFNGLBUFFERDATAARBPROC glBufferDataARB = (PFNGLBUFFERDATAARBPROC)gl->getProcAddress(_PROC("glBufferDataARB")); #endif - glBindBufferARB(GL_ARRAY_BUFFER_ARB, myvbo[0]); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float) * indice , vertex_array, GL_DYNAMIC_DRAW_ARB); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, myvbo[0]); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float) * indice , vertex_array, GL_DYNAMIC_DRAW_ARB); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, myvbo[1]); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLuint) * indice_array , &index_array[0], GL_DYNAMIC_DRAW_ARB); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, myvbo[1]); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLuint) * indice_array , &index_array[0], GL_DYNAMIC_DRAW_ARB); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - vbo_loaded=1; - update_vbo=0; - free(vertex_array); - free(index_array); - } - else - { + vboLoaded = true; + updateVbo = false; + free(vertex_array); + free(index_array); + } + else { #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 - const QGLContext* gl = QGLContext::currentContext(); + const QGLContext* gl = QGLContext::currentContext(); #else - QOpenGLContext* gl = QOpenGLContext::currentContext(); + QOpenGLContext* gl = QOpenGLContext::currentContext(); #endif - PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)gl->getProcAddress(_PROC("glUnmapBufferARB")); + PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)gl->getProcAddress(_PROC("glUnmapBufferARB")); #endif - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); - glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); - update_vbo=0; - } - } + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); + updateVbo = false; + } + } - // This is the VBO rendering code + // This is the VBO rendering code #ifdef FC_OS_WIN32 #if QT_VERSION < 0x50000 const QGLContext* gl = QGLContext::currentContext(); #else QOpenGLContext* gl = QOpenGLContext::currentContext(); #endif - PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)gl->getProcAddress(_PROC("glBindBufferARB")); + PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)gl->getProcAddress(_PROC("glBindBufferARB")); #endif - glBindBufferARB(GL_ARRAY_BUFFER_ARB, myvbo[0]); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, myvbo[1]); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, myvbo[0]); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 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))); - 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, indice_array, GL_UNSIGNED_INT, (void *)0); - glDrawElements(GL_TRIANGLES, 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 - return; + 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 + return; } // Legacy code without VBO support @@ -1321,7 +1280,7 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, v1 = *viptr++; v2 = *viptr++; v3 = *viptr++; - if (v1 < 0 || v2 < 0 || v3 < 0 || + if (v1 < 0 || v2 < 0 || v3 < 0 || v1 >= numverts || v2 >= numverts || v3 >= numverts) { break; } @@ -1330,15 +1289,11 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, /* vertex 1 *********************************************************/ if (mbind == PER_PART) { if (trinr == 0) - { materials->send(matnr++, true); - } } 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); @@ -1367,13 +1322,9 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, /* vertex 2 *********************************************************/ if (mbind == PER_VERTEX) - { materials->send(matnr++, true); - } else if (mbind == PER_VERTEX_INDEXED) - { materials->send(*matindices++, true); - } if (normals) { if (nbind == PER_VERTEX) { @@ -1396,13 +1347,9 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, /* vertex 3 *********************************************************/ if (mbind == PER_VERTEX) - { materials->send(matnr++, true); - } else if (mbind == PER_VERTEX_INDEXED) - { materials->send(*matindices++, true); - } if (normals) { if (nbind == PER_VERTEX) { @@ -1420,6 +1367,7 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, vertexlist->get3(v3), *currnormal); } + glVertex3fv((const GLfloat*) (coords3d + v3)); if (mbind == PER_VERTEX_INDEXED) diff --git a/src/Mod/Part/Gui/SoBrepFaceSet.h b/src/Mod/Part/Gui/SoBrepFaceSet.h index d116ac5fd..abfd13969 100644 --- a/src/Mod/Part/Gui/SoBrepFaceSet.h +++ b/src/Mod/Part/Gui/SoBrepFaceSet.h @@ -32,6 +32,7 @@ #include #include #include + class SoGLCoordinateElement; class SoTextureCoordinateBundle; @@ -84,7 +85,6 @@ public: SoMFInt32 partIndex; SoSFInt32 highlightIndex; SoMFInt32 selectionIndex; - int vbo_available,update_vbo; protected: virtual ~SoBrepFaceSet(); @@ -112,7 +112,8 @@ private: }; Binding findMaterialBinding(SoState * const state) const; Binding findNormalBinding(SoState * const state) const; - void renderShape(const SoGLCoordinateElement * const vertexlist, + void renderShape(SoState * state, + const SoGLCoordinateElement * const vertexlist, const int32_t *vertexindices, int num_vertexindices, const int32_t *partindices, @@ -140,13 +141,14 @@ private: std::vector vertex_array; #endif -// Define some VBO pointer for the current mesh - uint32_t myvbo[2]; - int vbo_loaded; - uint32_t indice_array; - const char *GL_extension; - SoState * current_state; - + // Define some VBO pointer for the current mesh + SbBool vboAvailable; +public: + SbBool updateVbo; +private: + uint32_t myvbo[2]; + SbBool vboLoaded; + uint32_t indice_array; SbColor selectionColor; SbColor highlightColor; diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp index 9e217be9c..fde56ebd8 100644 --- a/src/Mod/Part/Gui/ViewProviderExt.cpp +++ b/src/Mod/Part/Gui/ViewProviderExt.cpp @@ -799,9 +799,10 @@ void ViewProviderPartExt::reload() void ViewProviderPartExt::updateData(const App::Property* prop) { - // vejmarie: Force VBO update of the part - this->faceset->update_vbo=1; if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) { + // vejmarie: Force VBO update of the part + this->faceset->updateVbo = true; + // get the shape to show const TopoDS_Shape &cShape = static_cast(prop)->getValue();