diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index a37188eefa..d5e0264ffe 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -47,6 +47,12 @@ include_directories( ${3DCONNEXION_INCLUDE_DIR} ) +if(MSVC) + include_directories( + ${CMAKE_SOURCE_DIR}/src/3rdParty/OpenGL/api + ) +endif(MSVC) + if(MSVC) set(FreeCADGui_LIBS FreeCADApp @@ -807,6 +813,7 @@ SOURCE_GROUP("Widget\\QSintActionPanel\\Mocs" FILES ${qsint_MOC_SRCS}) # The 3d view SET(View3D_CPP_SRCS Flag.cpp + GLBuffer.cpp GLPainter.cpp MouseSelection.cpp NavigationStyle.cpp @@ -832,6 +839,7 @@ SET(View3D_CPP_SRCS SET(View3D_SRCS ${View3D_CPP_SRCS} Flag.h + GLBuffer.h GLPainter.h MouseSelection.h NavigationStyle.h diff --git a/src/Gui/GLBuffer.cpp b/src/Gui/GLBuffer.cpp new file mode 100644 index 0000000000..5b86a04d95 --- /dev/null +++ b/src/Gui/GLBuffer.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (c) 2018 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef FC_OS_WIN32 +#define GL_GLEXT_PROTOTYPES +#endif + +#ifndef _PreComp_ +# ifdef FC_OS_MACOSX +# include +# include +# include +# else +# include +# include +# include +# endif +#endif + +#include +#include +#include + +#include "GLBuffer.h" + +using namespace Gui; + + +OpenGLBuffer::OpenGLBuffer(GLenum type) + : target(type) + , bufferId(0) + , context(-1) + , currentContext(-1) + , glue(0) +{ + SoContextHandler::addContextDestructionCallback(context_destruction_cb, this); +} + +OpenGLBuffer::~OpenGLBuffer() +{ + SoContextHandler::removeContextDestructionCallback(context_destruction_cb, this); + + destroy(); +} + +void OpenGLBuffer::setCurrentContext(uint32_t ctx) +{ + currentContext = ctx; + glue = cc_glglue_instance(currentContext); +} + +bool OpenGLBuffer::create() +{ + if (bufferId > 0) + return true; +#ifdef FC_OS_WIN32 + PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)cc_glglue_getprocaddress(glue, "glGenBuffersARB"); +#endif + glGenBuffersARB(1, &bufferId); + context = currentContext; + return true; +} + +bool OpenGLBuffer::isCreated() const +{ + return (bufferId > 0); +} + +void OpenGLBuffer::destroy() +{ + // schedule delete for all allocated GL resources + if (bufferId > 0) { + void * ptr0 = (void*) ((uintptr_t) bufferId); + SoGLCacheContextElement::scheduleDeleteCallback(context, buffer_delete, ptr0); + bufferId = 0; + } +} + +void OpenGLBuffer::allocate(const void *data, int count) +{ + if (bufferId > 0) { +#ifdef FC_OS_WIN32 + PFNGLBUFFERDATAPROC glBufferDataARB = (PFNGLBUFFERDATAPROC)cc_glglue_getprocaddress(glue, "glBufferDataARB"); +#endif + glBufferDataARB(target, count, data, GL_STATIC_DRAW); + } +} + +bool OpenGLBuffer::bind() +{ + if (bufferId) { + if (context != currentContext) { + SoDebugError::postWarning("OpenGLBuffer::bind", + "buffer not created"); + return false; + } +#ifdef FC_OS_WIN32 + PFNGLBINDBUFFERPROC glBindBufferARB = (PFNGLBINDBUFFERPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); +#endif + glBindBufferARB(target, bufferId); + return true; + } + return false; +} + +void OpenGLBuffer::release() +{ + if (bufferId) { +#ifdef FC_OS_WIN32 + PFNGLBINDBUFFERPROC glBindBufferARB = (PFNGLBINDBUFFERPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); +#endif + glBindBufferARB(target, 0); + } +} + +GLuint OpenGLBuffer::getBufferId() const +{ + return bufferId; +} + +uint32_t OpenGLBuffer::getBoundContext() const +{ + return context; +} + +int OpenGLBuffer::size() const +{ + GLint value = -1; + if (bufferId > 0) { +#ifdef FC_OS_WIN32 + PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)cc_glglue_getprocaddress(glue, "glGetBufferParameterivARB"); +#endif + glGetBufferParameteriv(target, GL_BUFFER_SIZE, &value); + } + return value; +} + +void OpenGLBuffer::context_destruction_cb(uint32_t context, void * userdata) +{ + OpenGLBuffer * self = static_cast(userdata); + + if (self->context == context && self->bufferId) { +#ifdef FC_OS_WIN32 + const cc_glglue * glue = cc_glglue_instance((int) context); + PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)cc_glglue_getprocaddress(glue, "glDeleteBuffersARB"); +#endif + + GLuint buffer = self->bufferId; + glDeleteBuffersARB(1, &buffer); + self->context = -1; + self->bufferId = 0; + } +} + +void OpenGLBuffer::buffer_delete(void * closure, uint32_t contextid) +{ + const cc_glglue * glue = cc_glglue_instance((int) contextid); + GLuint id = (GLuint) ((uintptr_t) closure); + cc_glglue_glDeleteBuffers(glue, 1, &id); +} diff --git a/src/Gui/GLBuffer.h b/src/Gui/GLBuffer.h new file mode 100644 index 0000000000..7aa1ace66f --- /dev/null +++ b/src/Gui/GLBuffer.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (c) 2018 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_GLBUFFER_H +#define GUI_GLBUFFER_H + +#include + +namespace Gui { + +class GuiExport OpenGLBuffer +{ +public: + OpenGLBuffer(GLenum type); + ~OpenGLBuffer(); + + void setCurrentContext(uint32_t ctx); + bool create(); + bool isCreated() const; + + void destroy(); + void allocate(const void *data, int count); + bool bind(); + void release(); + GLuint getBufferId() const; + uint32_t getBoundContext() const; + int size() const; + +private: + static void context_destruction_cb(uint32_t context, void * userdata); + static void buffer_delete(void * closure, uint32_t contextid); + + GLenum target; + GLuint bufferId; + uint32_t context; + uint32_t currentContext; + const cc_glglue* glue; +}; + +} // namespace Gui + +#endif // GUI_GLBUFFER_H diff --git a/src/Mod/Mesh/Gui/SoFCIndexedFaceSet.cpp b/src/Mod/Mesh/Gui/SoFCIndexedFaceSet.cpp index e32cd2e79b..c41a381b4d 100644 --- a/src/Mod/Mesh/Gui/SoFCIndexedFaceSet.cpp +++ b/src/Mod/Mesh/Gui/SoFCIndexedFaceSet.cpp @@ -55,6 +55,7 @@ #include #include +#include #include "SoFCIndexedFaceSet.h" #define RENDER_GL_VAO @@ -66,141 +67,10 @@ using namespace MeshGui; #if defined RENDER_GL_VAO -class CoinOpenGLBuffer { -public: - CoinOpenGLBuffer(GLenum type) - : target(type) - , bufferId(0) - , context(-1) - , currentContext(-1) - , glue(0) - { - SoContextHandler::addContextDestructionCallback(context_destruction_cb, this); - } - ~CoinOpenGLBuffer() - { - SoContextHandler::removeContextDestructionCallback(context_destruction_cb, this); - - destroy(); - } - void setCurrentContext(uint32_t ctx) - { - currentContext = ctx; - glue = cc_glglue_instance(currentContext); - } - bool create() - { - if (bufferId > 0) - return true; -#ifdef FC_OS_WIN32 - PFNGLGENBUFFERSPROC glGenBuffersARB = (PFNGLGENBUFFERSPROC)cc_glglue_getprocaddress(glue, "glGenBuffersARB"); -#endif - glGenBuffersARB(1, &bufferId); - context = currentContext; - return true; - } - bool isCreated() const - { - return (bufferId > 0); - } - void destroy() - { - // schedule delete for all allocated GL resources - if (bufferId > 0) { - void * ptr0 = (void*) ((uintptr_t) bufferId); - SoGLCacheContextElement::scheduleDeleteCallback(context, buffer_delete, ptr0); - bufferId = 0; - } - } - void allocate(const void *data, int count) - { - if (bufferId > 0) { -#ifdef FC_OS_WIN32 - PFNGLBUFFERDATAPROC glBufferDataARB = (PFNGLBUFFERDATAPROC)cc_glglue_getprocaddress(glue, "glBufferDataARB"); -#endif - glBufferDataARB(target, count, data, GL_STATIC_DRAW); - } - } - bool bind() - { - if (bufferId) { - if (context != currentContext) { - SoDebugError::postWarning("CoinOpenGLBuffer::bind", - "buffer not created"); - return false; - } -#ifdef FC_OS_WIN32 - PFNGLBINDBUFFERPROC glBindBufferARB = (PFNGLBINDBUFFERPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); -#endif - glBindBufferARB(target, bufferId); - return true; - } - return false; - } - void release() - { - if (bufferId) { -#ifdef FC_OS_WIN32 - PFNGLBINDBUFFERPROC glBindBufferARB = (PFNGLBINDBUFFERPROC)cc_glglue_getprocaddress(glue, "glBindBufferARB"); -#endif - glBindBufferARB(target, 0); - } - } - GLuint getBufferId() const - { - return bufferId; - } - uint32_t getBoundContext() const - { - return context; - } - int size() const - { - GLint value = -1; - if (bufferId > 0) { -#ifdef FC_OS_WIN32 - PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)cc_glglue_getprocaddress(glue, "glGetBufferParameterivARB"); -#endif - glGetBufferParameteriv(target, GL_BUFFER_SIZE, &value); - } - return value; - } - -private: - static void context_destruction_cb(uint32_t context, void * userdata) - { - CoinOpenGLBuffer * self = static_cast(userdata); - - if (self->context == context && self->bufferId) { -#ifdef FC_OS_WIN32 - const cc_glglue * glue = cc_glglue_instance((int) context); - PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)cc_glglue_getprocaddress(glue, "glDeleteBuffersARB"); -#endif - - GLuint buffer = self->bufferId; - glDeleteBuffersARB(1, &buffer); - self->context = -1; - self->bufferId = 0; - } - } - static void buffer_delete(void * closure, uint32_t contextid) - { - const cc_glglue * glue = cc_glglue_instance((int) contextid); - GLuint id = (GLuint) ((uintptr_t) closure); - cc_glglue_glDeleteBuffers(glue, 1, &id); - } - - GLenum target; - GLuint bufferId; - uint32_t context; - uint32_t currentContext; - const cc_glglue* glue; -}; - class MeshRenderer::Private { public: - CoinOpenGLBuffer vertices; - CoinOpenGLBuffer indices; + Gui::OpenGLBuffer vertices; + Gui::OpenGLBuffer indices; const SbColor * pcolors; SoMaterialBindingElement::Binding matbinding; bool initialized;