1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2013 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, carsten_neumann@gmx.net *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include <boost/bind.hpp>
48 #include "OSGConfig.h"
53 #include "OSGWindow.h"
55 #include "OSGGLFuncProtos.h"
57 #include "OSGDrawEnv.h"
59 #include "OSGUniformBufferObjStd140Chunk.h"
63 // Documentation for this class is emitted in the
64 // OSGUniformBufferObjStd140ChunkBase.cpp file.
65 // To modify it, please change the .fcd file (OSGUniformBufferObjStd140Chunk.fcd) and
66 // regenerate the base file.
68 /***************************************************************************\
70 \***************************************************************************/
72 typedef OSG::Window Win
;
74 UInt32
UniformBufferObjStd140Chunk::_extUniformBufferObject
= Win::invalidExtensionID
;
75 UInt32
UniformBufferObjStd140Chunk::_extVertexBufferObject
= Win::invalidExtensionID
;
77 UInt32
UniformBufferObjStd140Chunk::_funcBindBuffer
= Win::invalidFunctionID
;
78 UInt32
UniformBufferObjStd140Chunk::_funcMapBuffer
= Win::invalidFunctionID
;
79 UInt32
UniformBufferObjStd140Chunk::_funcUnmapBuffer
= Win::invalidFunctionID
;
80 UInt32
UniformBufferObjStd140Chunk::_funcBufferData
= Win::invalidFunctionID
;
81 UInt32
UniformBufferObjStd140Chunk::_funcBufferSubData
= Win::invalidFunctionID
;
82 UInt32
UniformBufferObjStd140Chunk::_funcGenBuffers
= Win::invalidFunctionID
;
83 UInt32
UniformBufferObjStd140Chunk::_funcDeleteBuffers
= Win::invalidFunctionID
;
84 UInt32
UniformBufferObjStd140Chunk::_funcBindBufferBase
= Win::invalidFunctionID
;
85 UInt32
UniformBufferObjStd140Chunk::_funcGetBufferParameteriv
= Win::invalidFunctionID
;
87 /***************************************************************************\
89 \***************************************************************************/
91 void UniformBufferObjStd140Chunk::initMethod(InitPhase ePhase
)
93 Inherited::initMethod(ePhase
);
95 if(ePhase
== TypeObject::SystemPost
)
97 _extVertexBufferObject
=
98 Window::registerExtension("GL_ARB_vertex_buffer_object");
100 _funcBindBuffer
= Window::registerFunction(
101 OSG_DLSYM_UNDERSCORE
"glBindBufferARB",
102 _extVertexBufferObject
);
104 _funcMapBuffer
= Window::registerFunction(
105 OSG_DLSYM_UNDERSCORE
"glMapBufferARB",
106 _extVertexBufferObject
);
108 _funcUnmapBuffer
= Window::registerFunction(
109 OSG_DLSYM_UNDERSCORE
"glUnmapBufferARB",
110 _extVertexBufferObject
);
112 _funcBufferData
= Window::registerFunction(
113 OSG_DLSYM_UNDERSCORE
"glBufferDataARB",
114 _extVertexBufferObject
);
116 _funcBufferSubData
= Window::registerFunction(
117 OSG_DLSYM_UNDERSCORE
"glBufferSubDataARB",
118 _extVertexBufferObject
);
120 _funcDeleteBuffers
= Window::registerFunction(
121 OSG_DLSYM_UNDERSCORE
"glDeleteBuffersARB",
122 _extVertexBufferObject
);
124 _funcGenBuffers
= Window::registerFunction(
125 OSG_DLSYM_UNDERSCORE
"glGenBuffersARB",
126 _extVertexBufferObject
);
128 _funcGetBufferParameteriv
= Window::registerFunction(
129 OSG_DLSYM_UNDERSCORE
"glGetBufferParameterivARB",
130 _extVertexBufferObject
);
133 _extUniformBufferObject
=
134 Window::registerExtension("GL_ARB_uniform_buffer_object" );
136 _funcBindBufferBase
= Window::registerFunction(
137 OSG_DLSYM_UNDERSCORE
"glBindBufferBase",
138 _extUniformBufferObject
);
143 /***************************************************************************\
145 \***************************************************************************/
147 /*-------------------------------------------------------------------------*\
149 \*-------------------------------------------------------------------------*/
151 /*----------------------- constructors & destructors ----------------------*/
153 UniformBufferObjStd140Chunk::UniformBufferObjStd140Chunk(void) :
158 UniformBufferObjStd140Chunk::UniformBufferObjStd140Chunk(const UniformBufferObjStd140Chunk
&source
) :
163 UniformBufferObjStd140Chunk::~UniformBufferObjStd140Chunk(void)
167 /*----------------------------- class specific ----------------------------*/
169 void UniformBufferObjStd140Chunk::changed(ConstFieldMaskArg whichField
,
173 GLenum id
= _sfGLId
.getValue();
175 if((whichField
& (UsageFieldMask
| BufferFieldMask
)) != 0)
177 Window::reinitializeGLObject(id
);
180 Inherited::changed(whichField
, origin
, details
);
183 /*----------------------------- onCreate --------------------------------*/
185 void UniformBufferObjStd140Chunk::onCreate(const UniformBufferObjStd140Chunk
*source
)
187 Inherited::onCreate(source
);
189 if(GlobalSystemState
== Startup
)
192 setGLId(Window::registerGLObject(
193 boost::bind(&UniformBufferObjStd140Chunk::handleGL
,
194 UniformBufferObjStd140ChunkMTUncountedPtr(this),
196 &UniformBufferObjStd140Chunk::handleDestroyGL
));
199 void UniformBufferObjStd140Chunk::onCreateAspect(const UniformBufferObjStd140Chunk
*createAspect
,
200 const UniformBufferObjStd140Chunk
*source
)
202 Inherited::onCreateAspect(createAspect
, source
);
205 void UniformBufferObjStd140Chunk::onDestroy(UInt32 uiContainerId
)
208 Window::destroyGLObject(getGLId(), 1);
210 Inherited::onDestroy(uiContainerId
);
213 /*------------------------------ Output ----------------------------------*/
215 void UniformBufferObjStd140Chunk::dump( UInt32 uiIndent
,
216 const BitVector bvFlags
) const
218 Inherited::dump(uiIndent
, bvFlags
);
220 if((bvFlags
& UsageFieldMask
) != 0)
222 indentLog(uiIndent
, PLOG
);
223 PLOG
<< "usage " << _sfUsage
.getValue() << "\n";
225 if((bvFlags
& BufferFieldMask
) != 0)
227 indentLog(uiIndent
, PLOG
);
228 PLOG
<< "buffer " << "content changed" << "\n";// _mfBuffer.getValue() << "\n";
232 /*------------------------------ GL -----------------------------------------*/
234 /*! GL object handler */
235 UInt32
UniformBufferObjStd140Chunk::handleGL(DrawEnv
*pEnv
,
237 Window::GLObjectStatusE mode
,
240 Window
*pWin
= pEnv
->getWindow();
241 GLuint id
= pWin
->getGLObjectId(osgid
);
243 bool hasVBO
= pWin
->hasExtOrVersion(_extVertexBufferObject
, 0x0105, 0x0200);
247 ("UniformBufferObjStd140Chunk::handleGL: vertex buffer objects not "
248 "supported for this window!\n"));
252 bool hasUBO
= pWin
->hasExtOrVersion(_extUniformBufferObject
, 0x0300);
256 ("UniformBufferObjStd140Chunk::handleGL: uniform buffer objects not "
257 "supported for this window!\n"));
263 case Window::initialize
:
265 OSGGETGLFUNCBYID_GL3_ES( glGenBuffers
,
270 OSGGETGLFUNCBYID_GL3_ES( glBindBuffer
,
275 OSGGETGLFUNCBYID_GL3_ES( glBufferData
,
280 OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase
,
285 osgGlGenBuffers(1, &id
);
286 pWin
->setGLObjectId(osgid
, id
);
288 std::size_t sz
= _mfBuffer
.size();
291 osgGlBindBuffer (GL_UNIFORM_BUFFER
, id
);
292 osgGlBufferData (GL_UNIFORM_BUFFER
, sz
, &_mfBuffer
[0], _sfUsage
.getValue());
293 osgGlBindBuffer (GL_UNIFORM_BUFFER
, 0);
296 glErr("UniformBufferObjStd140Chunk::handleGL initialize");
299 case Window::reinitialize
:
301 std::size_t sz
= _mfBuffer
.size();
304 OSGGETGLFUNCBYID_GL3_ES( glBindBuffer
,
309 OSGGETGLFUNCBYID_GL3_ES( glGetBufferParameteriv
,
310 osgGlGetBufferParameteriv
,
311 _funcGetBufferParameteriv
,
314 OSGGETGLFUNCBYID_GL3_ES( glBufferData
,
319 OSGGETGLFUNCBYID_GL3_ES( glMapBuffer
,
324 OSGGETGLFUNCBYID_GL3_ES( glUnmapBuffer
,
329 OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase
,
334 osgGlBindBuffer(GL_UNIFORM_BUFFER
, id
);
337 osgGlGetBufferParameteriv( GL_UNIFORM_BUFFER
,
342 osgGlGetBufferParameteriv( GL_UNIFORM_BUFFER
,
346 if ( sz
!= SizeT (curr_size
) ||
347 _sfUsage
.getValue() != GLenum(curr_usage
) )
349 osgGlBufferData( GL_UNIFORM_BUFFER
,
352 _sfUsage
.getValue());
356 GLubyte
* pBuffer
= static_cast<GLubyte
*>(
357 osgGlMapBuffer(GL_UNIFORM_BUFFER
,
360 UInt8
* p
= &_mfBuffer
[0];
361 memcpy(pBuffer
, p
, sizeof(UInt8
) * _mfBuffer
.size());
363 osgGlUnmapBuffer(GL_UNIFORM_BUFFER
);
366 osgGlBindBuffer (GL_UNIFORM_BUFFER
, 0);
368 glErr("UniformBufferObjStd140Chunk::handleGL reinitialize");
372 case Window::needrefresh
:
374 OSGGETGLFUNCBYID_GL3_ES( glBindBuffer
,
379 OSGGETGLFUNCBYID_GL3_ES( glMapBuffer
,
384 OSGGETGLFUNCBYID_GL3_ES( glUnmapBuffer
,
389 osgGlBindBuffer(GL_UNIFORM_BUFFER
, id
);
390 GLubyte
* pBuffer
= static_cast<GLubyte
*>(
391 osgGlMapBuffer(GL_UNIFORM_BUFFER
, GL_WRITE_ONLY_ARB
));
393 UChar8
* p
= &_mfBuffer
[0];
394 memcpy(pBuffer
, p
, sizeof(UChar8
) * _mfBuffer
.size());
396 osgGlUnmapBuffer(GL_UNIFORM_BUFFER
);
397 osgGlBindBuffer (GL_UNIFORM_BUFFER
, 0);
399 glErr("UniformBufferObjStd140Chunk::handleGL needrefresh");
404 SWARNING
<< "UniformBufferObjStd140Chunk(" << this << "::handleGL: Illegal mode: "
405 << mode
<< " for id " << id
<< std::endl
;
412 /*! GL object handler
415 void UniformBufferObjStd140Chunk::handleDestroyGL(DrawEnv
*pEnv
,
417 Window::GLObjectStatusE mode
)
419 Window
*pWin
= pEnv
->getWindow();
420 GLuint id
= pWin
->getGLObjectId(osgid
);
422 if(mode
== Window::destroy
)
424 OSGGETGLFUNCBYID_GL3_ES( glDeleteBuffers
,
429 osgGlDeleteBuffers(1, &id
);
430 pWin
->setGLObjectId(osgid
, 0);
432 glErr("UniformBufferObjStd140Chunk::handleDestroyGL");
434 else if(mode
== Window::finaldestroy
)
436 //SWARNING << "Last buffer user destroyed" << std::endl;
440 SWARNING
<< "UniformBufferObjStd140Chunk::handleDestroyGL: Illegal mode: "
441 << mode
<< " for id " << id
<< std::endl
;
446 /*------------------------------ tools --------------------------------------*/
448 void UniformBufferObjStd140Chunk::validate(DrawEnv
*pEnv
)
450 pEnv
->getWindow()->validateGLObject(this->getGLId(),
454 Int32
UniformBufferObjStd140Chunk::getOpenGLId(DrawEnv
*pEnv
)
456 return pEnv
->getWindow()->getGLObjectId(this->getGLId());
459 /*------------------------------ activate -----------------------------------*/
461 void UniformBufferObjStd140Chunk::activate(DrawEnv
*pEnv
, UInt32 idx
)
463 Window
*pWin
= pEnv
->getWindow();
465 pWin
->validateGLObject(getGLId(), pEnv
);
467 GLuint id
= pWin
->getGLObjectId(getGLId());
469 OSGGETGLFUNCBYID_GL3_ES( glBindBuffer
,
474 OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase
,
479 osgGlBindBuffer (GL_UNIFORM_BUFFER
, id
);
480 osgGlBindBufferBase(GL_UNIFORM_BUFFER
, idx
, id
);
482 glErr("UniformBufferObjStd140Chunk::activate");
485 /*------------------------------ deactivate ---------------------------------*/
487 void UniformBufferObjStd140Chunk::deactivate(DrawEnv
*pEnv
, UInt32 idx
)
489 Window
*pWin
= pEnv
->getWindow();
491 OSGGETGLFUNCBYID_GL3_ES( glBindBuffer
,
496 OSGGETGLFUNCBYID_GL3_ES( glBindBufferBase
,
501 osgGlBindBufferBase(GL_UNIFORM_BUFFER
, idx
, 0);
502 osgGlBindBuffer (GL_UNIFORM_BUFFER
, 0);
504 glErr("UniformBufferObjStd140Chunk::deactivate");
507 /*------------------------------ changeFrom ---------------------------------*/
509 void UniformBufferObjStd140Chunk::changeFrom(DrawEnv
*pEnv
,
513 // change from me to me?
514 // this assumes I haven't changed in the meantime.
515 // is that a valid assumption?
519 old
->deactivate(pEnv
, idx
);
520 this->activate(pEnv
, idx
);