move OpenGLBuffer class to core system

This commit is contained in:
wmayer
2018-08-16 01:30:23 +02:00
parent 59b8f21585
commit 266f82bca4
4 changed files with 255 additions and 133 deletions

View File

@@ -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

182
src/Gui/GLBuffer.cpp Normal file
View File

@@ -0,0 +1,182 @@
/***************************************************************************
* Copyright (c) 2018 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 <OpenGL/gl.h>
# include <OpenGL/glu.h>
# include <OpenGL/glext.h>
# else
# include <GL/gl.h>
# include <GL/glu.h>
# include <GL/glext.h>
# endif
#endif
#include <Inventor/elements/SoGLCacheContextElement.h>
#include <Inventor/errors/SoDebugError.h>
#include <Inventor/misc/SoContextHandler.h>
#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<OpenGLBuffer*>(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);
}

62
src/Gui/GLBuffer.h Normal file
View File

@@ -0,0 +1,62 @@
/***************************************************************************
* Copyright (c) 2018 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 <Inventor/C/glue/gl.h>
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

View File

@@ -55,6 +55,7 @@
#include <Gui/SoFCInteractiveElement.h>
#include <Gui/SoFCSelectionAction.h>
#include <Gui/GLBuffer.h>
#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<CoinOpenGLBuffer*>(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;