Experimental support for OpenGL Vertex Array Object
This commit is contained in:
@@ -164,6 +164,7 @@ class OSG_EXPORT Array : public BufferData
|
||||
|
||||
virtual unsigned int getElementSize() const = 0;
|
||||
virtual const GLvoid* getDataPointer() const = 0;
|
||||
virtual const GLvoid* getDataPointer(unsigned int index) const = 0;
|
||||
virtual unsigned int getTotalDataSize() const = 0;
|
||||
virtual unsigned int getNumElements() const = 0;
|
||||
virtual void reserveArray(unsigned int num) = 0;
|
||||
@@ -285,8 +286,9 @@ class TemplateArray : public Array, public MixinVector<T>
|
||||
MixinVector<T>( *this ).swap( *this );
|
||||
}
|
||||
|
||||
virtual unsigned int getElementSize() const { return sizeof(ElementDataType); }
|
||||
virtual unsigned int getElementSize() const { return sizeof(ElementDataType); }
|
||||
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
|
||||
virtual const GLvoid* getDataPointer(unsigned int index) const { if (!this->empty()) return &((*this)[index]); else return 0; }
|
||||
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(ElementDataType)); }
|
||||
virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); }
|
||||
virtual void reserveArray(unsigned int num) { this->reserve(num); }
|
||||
@@ -376,6 +378,7 @@ class TemplateIndexArray : public IndexArray, public MixinVector<T>
|
||||
|
||||
virtual unsigned int getElementSize() const { return sizeof(ElementDataType); }
|
||||
virtual const GLvoid* getDataPointer() const { if (!this->empty()) return &this->front(); else return 0; }
|
||||
virtual const GLvoid* getDataPointer(unsigned int index) const { if (!this->empty()) return &((*this)[index]); else return 0; }
|
||||
virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(this->size()*sizeof(T)); }
|
||||
virtual unsigned int getNumElements() const { return static_cast<unsigned int>(this->size()); }
|
||||
virtual void reserveArray(unsigned int num) { this->reserve(num); }
|
||||
|
||||
@@ -299,6 +299,17 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
int getNvOptimusEnablement() const;
|
||||
|
||||
|
||||
enum GeometryImplementation
|
||||
{
|
||||
OLD_GEOMETRY_IMPLEMENTATION,
|
||||
NEW_GEOMETRY_IMPLEMENTATION,
|
||||
VERTEX_ARRAY_OBJECT
|
||||
};
|
||||
|
||||
void setGeometryImplementation(GeometryImplementation gi) { _geometryImplementation = gi; }
|
||||
GeometryImplementation getGeometryImplementation() const { return _geometryImplementation; }
|
||||
|
||||
|
||||
void setKeystoneHint(bool enabled) { _keystoneHint = enabled; }
|
||||
bool getKeystoneHint() const { return _keystoneHint; }
|
||||
|
||||
@@ -388,6 +399,8 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
SwapMethod _swapMethod;
|
||||
unsigned int _syncSwapBuffers;
|
||||
|
||||
GeometryImplementation _geometryImplementation;
|
||||
|
||||
bool _keystoneHint;
|
||||
FileNames _keystoneFileNames;
|
||||
Objects _keystones;
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** Return floating-point OpenGL version number.
|
||||
/** Return floating-point OpenGL/GLES version number.
|
||||
* Note: Must only be called within a valid OpenGL context,
|
||||
* undefined behavior may occur otherwise.
|
||||
*/
|
||||
@@ -34,19 +36,25 @@ extern OSG_EXPORT float getGLVersionNumber();
|
||||
*/
|
||||
extern OSG_EXPORT bool isExtensionInExtensionString(const char *extension, const char *extensionString);
|
||||
|
||||
/** Return true if OpenGL "extension" is supported.
|
||||
/** Return true if OpenGL/GLES "extension" is supported.
|
||||
* Note: Must only be called within a valid OpenGL context,
|
||||
* undefined behavior may occur otherwise.
|
||||
*/
|
||||
extern OSG_EXPORT bool isGLExtensionSupported(unsigned int contextID, const char *extension);
|
||||
|
||||
/** Return true if OpenGL "extension" or minimum OpenGL version number is supported.
|
||||
/** Return true if either OpenGL/GLES "extension1" or "extension2" is supported.
|
||||
* Note: Must only be called within a valid OpenGL context,
|
||||
* undefined behavior may occur otherwise.
|
||||
*/
|
||||
extern OSG_EXPORT bool isGLExtensionSupported(unsigned int contextID, const char *extension1, const char *extension2);
|
||||
|
||||
/** Return true if OpenGL/GLES "extension" or minimum OpenGL version number is supported.
|
||||
* Note: Must only be called within a valid OpenGL context,
|
||||
* undefined behavior may occur otherwise.
|
||||
*/
|
||||
extern OSG_EXPORT bool isGLExtensionOrVersionSupported(unsigned int contextID, const char *extension, float requiredGlVersion);
|
||||
|
||||
/** Return the address of the specified OpenGL function.
|
||||
/** Return the address of the specified OpenGL/GLES function.
|
||||
* Return NULL if function not supported by OpenGL library.
|
||||
* Note, glGLExtensionFuncPtr is declared inline so that the code
|
||||
* is compiled locally to the calling code. This should get by Windows'
|
||||
@@ -123,11 +131,35 @@ bool setGLExtensionFuncPtr(T& t, const char* str1, const char* str2, const char*
|
||||
return convertPointer(t, validContext ? osg::getGLExtensionFuncPtr(str1, str2, str3) : 0);
|
||||
}
|
||||
|
||||
class VertexAttribAlias
|
||||
{
|
||||
public:
|
||||
VertexAttribAlias():
|
||||
_location(0) {}
|
||||
|
||||
VertexAttribAlias(const VertexAttribAlias& rhs):
|
||||
_location(rhs._location),
|
||||
_glName(rhs._glName),
|
||||
_osgName(rhs._osgName),
|
||||
_declaration(rhs._declaration) {}
|
||||
|
||||
VertexAttribAlias(GLuint location, const std::string glName, const std::string osgName, const std::string& declaration):
|
||||
_location(location),
|
||||
_glName(glName),
|
||||
_osgName(osgName),
|
||||
_declaration(declaration) {}
|
||||
|
||||
GLuint _location;
|
||||
std::string _glName;
|
||||
std::string _osgName;
|
||||
std::string _declaration;
|
||||
};
|
||||
|
||||
/** Main GLExtensions class for managing OpenGL extensions per graphics context.*/
|
||||
class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
GLExtensions(unsigned int contextID);
|
||||
GLExtensions(unsigned int in_contextID);
|
||||
|
||||
/** Function to call to get the extension of a specified context.
|
||||
* If the Exentsion object for that context has not yet been created then
|
||||
@@ -135,12 +167,12 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
* If 'createIfNotInitalized' is true then the Extensions object is
|
||||
* automatically created. However, in this case the extension object
|
||||
* only be created with the graphics context associated with ContextID..*/
|
||||
static GLExtensions* Get(unsigned int contextID,bool createIfNotInitalized);
|
||||
static GLExtensions* Get(unsigned int in_contextID,bool createIfNotInitalized);
|
||||
|
||||
/** allows users to override the extensions across graphics contexts.
|
||||
* typically used when you have different extensions supported across graphics pipes
|
||||
* but need to ensure that they all use the same low common denominator extensions.*/
|
||||
static void Set(unsigned int contextID, GLExtensions* extensions);
|
||||
static void Set(unsigned int in_contextID, GLExtensions* extensions);
|
||||
|
||||
// C++-friendly convenience wrapper methods
|
||||
GLuint getCurrentProgram() const;
|
||||
@@ -149,6 +181,7 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
bool getAttribLocation( const char* attribName, GLuint& slot ) const;
|
||||
bool getFragDataLocation( const char* fragDataName, GLuint& slot) const;
|
||||
|
||||
unsigned int contextID;
|
||||
|
||||
float glVersion;
|
||||
float glslLanguageVersion;
|
||||
@@ -260,8 +293,11 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
void (GL_APIENTRY * glVertexAttrib4ubv)(GLuint index, const GLubyte *v);
|
||||
void (GL_APIENTRY * glVertexAttrib4uiv)(GLuint index, const GLuint *v);
|
||||
void (GL_APIENTRY * glVertexAttrib4usv)(GLuint index, const GLushort *v);
|
||||
void (GL_APIENTRY * glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
|
||||
void (GL_APIENTRY * glVertexAttribPointer) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
|
||||
void (GL_APIENTRY * glVertexAttribIPointer) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
|
||||
void (GL_APIENTRY * glVertexAttribLPointer) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
|
||||
void (GL_APIENTRY * glVertexAttribDivisor)(GLuint index, GLuint divisor);
|
||||
|
||||
void (GL_APIENTRY * glUniformMatrix2x3fv)( GLint location, GLsizei count, GLboolean transpose, const GLfloat* value );
|
||||
void (GL_APIENTRY * glUniformMatrix3x2fv)( GLint location, GLsizei count, GLboolean transpose, const GLfloat* value );
|
||||
void (GL_APIENTRY * glUniformMatrix2x4fv)( GLint location, GLsizei count, GLboolean transpose, const GLfloat* value );
|
||||
@@ -313,8 +349,10 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
void (GL_APIENTRY * glGetActiveAtomicCounterBufferiv)( GLuint program, GLuint bufferIndex, GLenum pname, GLint* params );
|
||||
void (GL_APIENTRY * glDispatchCompute)( GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ );
|
||||
|
||||
|
||||
// Buffer Object extensions
|
||||
bool isBufferObjectSupported;
|
||||
bool isVBOSupported;
|
||||
bool isPBOSupported;
|
||||
bool isTBOSupported;
|
||||
bool isVAOSupported;
|
||||
@@ -355,12 +393,19 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
bool isTimerQuerySupported;
|
||||
bool isARBTimerQuerySupported;
|
||||
|
||||
|
||||
|
||||
void (GL_APIENTRY * glDrawArraysInstanced)( GLenum mode, GLint first, GLsizei count, GLsizei primcount );
|
||||
void (GL_APIENTRY * glDrawElementsInstanced)( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount );
|
||||
|
||||
void (GL_APIENTRY * glSecondaryColor3ubv) (const GLubyte* coord);
|
||||
void (GL_APIENTRY * glSecondaryColor3fv) (const GLfloat* coord);
|
||||
|
||||
void (GL_APIENTRY * glFogCoordfv) (const GLfloat* coord);
|
||||
|
||||
void (GL_APIENTRY * glMultiTexCoord1f) (GLenum target,GLfloat coord);
|
||||
void (GL_APIENTRY * glMultiTexCoord4f) (GLenum target, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
|
||||
void (GL_APIENTRY * glMultiTexCoord1fv) (GLenum target,const GLfloat* coord);
|
||||
void (GL_APIENTRY * glMultiTexCoord2fv) (GLenum target,const GLfloat* coord);
|
||||
void (GL_APIENTRY * glMultiTexCoord3fv) (GLenum target,const GLfloat* coord);
|
||||
@@ -645,6 +690,67 @@ class OSG_EXPORT GLExtensions : public osg::Referenced
|
||||
void (GL_APIENTRY * glEnableIndexedEXT) (GLenum target, GLuint index);
|
||||
void (GL_APIENTRY * glDisableIndexedEXT) (GLenum target, GLuint index);
|
||||
GLboolean (GL_APIENTRY * glIsEnabledIndexedEXT) (GLenum target, GLuint index);
|
||||
|
||||
void (GL_APIENTRY * glClientActiveTexture) (GLenum texture);
|
||||
void (GL_APIENTRY * glActiveTexture) (GLenum texture);
|
||||
void (GL_APIENTRY * glFogCoordPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void (GL_APIENTRY * glSecondaryColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
|
||||
GLint glMaxTextureCoords;
|
||||
GLint glMaxTextureUnits;
|
||||
public:
|
||||
|
||||
|
||||
void setUseVertexAttributeAliasing(bool flag) { _useVertexAttributeAliasing = flag; }
|
||||
bool getUseVertexAttributeAliasing() const { return _useVertexAttributeAliasing ; }
|
||||
|
||||
typedef std::vector<VertexAttribAlias> VertexAttribAliasList;
|
||||
typedef std::map<std::string,GLuint> AttribBindingList;
|
||||
|
||||
void setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration);
|
||||
|
||||
/** Reset the vertex attribute aliasing to osg's default. This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void resetVertexAttributeAlias(bool compactAliasing=true, unsigned int numTextureUnits=8);
|
||||
|
||||
/** Set the vertex attribute aliasing for "vertex". This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setVertexAlias(const VertexAttribAlias& alias) { _vertexAlias = alias; }
|
||||
const VertexAttribAlias& getVertexAlias() { return _vertexAlias; }
|
||||
|
||||
/** Set the vertex attribute aliasing for "normal". This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setNormalAlias(const VertexAttribAlias& alias) { _normalAlias = alias; }
|
||||
const VertexAttribAlias& getNormalAlias() { return _normalAlias; }
|
||||
|
||||
/** Set the vertex attribute aliasing for "color". This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setColorAlias(const VertexAttribAlias& alias) { _colorAlias = alias; }
|
||||
const VertexAttribAlias& getColorAlias() { return _colorAlias; }
|
||||
|
||||
/** Set the vertex attribute aliasing for "secondary color". This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setSecondaryColorAlias(const VertexAttribAlias& alias) { _secondaryColorAlias = alias; }
|
||||
const VertexAttribAlias& getSecondaryColorAlias() { return _secondaryColorAlias; }
|
||||
|
||||
/** Set the vertex attribute aliasing for "fog coord". This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setFogCoordAlias(const VertexAttribAlias& alias) { _fogCoordAlias = alias; }
|
||||
const VertexAttribAlias& getFogCoordAlias() { return _fogCoordAlias; }
|
||||
|
||||
/** Set the vertex attribute aliasing list for texture coordinates. This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setTexCoordAliasList(const VertexAttribAliasList& aliasList) { _texCoordAliasList = aliasList; }
|
||||
const VertexAttribAliasList& getTexCoordAliasList() { return _texCoordAliasList; }
|
||||
|
||||
/** Set the vertex attribute binding list. This method needs to be called before render anything unless you really know what you're doing !*/
|
||||
void setAttributeBindingList(const AttribBindingList& attribBindingList) { _attributeBindingList = attribBindingList; }
|
||||
const AttribBindingList& getAttributeBindingList() { return _attributeBindingList; }
|
||||
|
||||
|
||||
bool _useVertexAttributeAliasing;
|
||||
VertexAttribAlias _vertexAlias;
|
||||
VertexAttribAlias _normalAlias;
|
||||
VertexAttribAlias _colorAlias;
|
||||
VertexAttribAlias _secondaryColorAlias;
|
||||
VertexAttribAlias _fogCoordAlias;
|
||||
VertexAttribAliasList _texCoordAliasList;
|
||||
|
||||
AttribBindingList _attributeBindingList;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -176,11 +176,17 @@ class OSG_EXPORT Geometry : public Drawable
|
||||
*/
|
||||
virtual void drawImplementation(RenderInfo& renderInfo) const;
|
||||
|
||||
|
||||
/** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/
|
||||
void drawVertexArraysImplementation(RenderInfo& renderInfo) const;
|
||||
void old_drawVertexArraysImplementation(RenderInfo& renderInfo) const;
|
||||
|
||||
/** dispatch the primitives to OpenGL, called by drawImplemtation() after calling drawVertexArraysImplementation().*/
|
||||
void drawPrimitivesImplementation(RenderInfo& renderInfo) const;
|
||||
void old_drawPrimitivesImplementation(RenderInfo& renderInfo) const;
|
||||
|
||||
|
||||
/** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/
|
||||
void new_drawImplementation(RenderInfo& renderInfo) const;
|
||||
|
||||
|
||||
/** Return true, osg::Geometry does support accept(Drawable::AttributeFunctor&). */
|
||||
virtual bool supports(const Drawable::AttributeFunctor&) const { return true; }
|
||||
@@ -217,6 +223,9 @@ class OSG_EXPORT Geometry : public Drawable
|
||||
void addVertexBufferObjectIfRequired(osg::Array* array);
|
||||
void addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet);
|
||||
|
||||
typedef buffered_object< osg::ref_ptr<VertexArrayState> > VertexArrayStateList;
|
||||
mutable VertexArrayStateList _vertexArrayStateList;
|
||||
|
||||
|
||||
PrimitiveSetList _primitives;
|
||||
osg::ref_ptr<Array> _vertexArray;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/Observer>
|
||||
#include <osg/Timer>
|
||||
#include <osg/VertexArrayState>
|
||||
|
||||
#include <osg/ShaderComposer>
|
||||
#include <osg/FrameStamp>
|
||||
@@ -72,31 +73,20 @@ namespace osg {
|
||||
// forward declare GraphicsContext, View and State
|
||||
class GraphicsContext;
|
||||
|
||||
class VertexAttribAlias
|
||||
struct EnabledArrayPair
|
||||
{
|
||||
public:
|
||||
VertexAttribAlias():
|
||||
_location(0) {}
|
||||
EnabledArrayPair():_arrayType(0), _lazy_disable(false),_dirty(true),_enabled(false),_normalized(0),_pointer(0) {}
|
||||
EnabledArrayPair(const EnabledArrayPair& eap):_arrayType(0), _lazy_disable(eap._lazy_disable),_dirty(eap._dirty), _enabled(eap._enabled),_normalized(eap._normalized),_pointer(eap._pointer) {}
|
||||
EnabledArrayPair& operator = (const EnabledArrayPair& eap) { _arrayType = eap._arrayType; _lazy_disable = eap._lazy_disable;_dirty=eap._dirty; _enabled=eap._enabled; _normalized=eap._normalized;_pointer=eap._pointer; return *this; }
|
||||
|
||||
VertexAttribAlias(const VertexAttribAlias& rhs):
|
||||
_location(rhs._location),
|
||||
_glName(rhs._glName),
|
||||
_osgName(rhs._osgName),
|
||||
_declaration(rhs._declaration) {}
|
||||
|
||||
VertexAttribAlias(GLuint location, const std::string glName, const std::string osgName, const std::string& declaration):
|
||||
_location(location),
|
||||
_glName(glName),
|
||||
_osgName(osgName),
|
||||
_declaration(declaration) {}
|
||||
|
||||
GLuint _location;
|
||||
std::string _glName;
|
||||
std::string _osgName;
|
||||
std::string _declaration;
|
||||
GLenum _arrayType;
|
||||
bool _lazy_disable;
|
||||
bool _dirty;
|
||||
bool _enabled;
|
||||
GLboolean _normalized;
|
||||
const GLvoid* _pointer;
|
||||
};
|
||||
|
||||
|
||||
/** Encapsulates the current applied OpenGL modes, attributes and vertex arrays settings,
|
||||
* implements lazy state updating and provides accessors for querying the current state.
|
||||
* The venerable Red Book says that "OpenGL is a state machine", and this class
|
||||
@@ -500,12 +490,24 @@ class OSG_EXPORT State : public Referenced
|
||||
const StateAttribute* getLastAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0) const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Dirty the modes previously applied in osg::State.*/
|
||||
void dirtyAllModes();
|
||||
|
||||
/** Dirty the modes attributes previously applied in osg::State.*/
|
||||
void dirtyAllAttributes();
|
||||
|
||||
|
||||
|
||||
/** Set the CurrentVetexArrayState object that take which vertex arrays are bound.*/
|
||||
void setCurrentVertexArrayState(VertexArrayState* vas) { _currentVertexArrayState = vas; }
|
||||
|
||||
/** Get the CurrentVetexArrayState object that take which vertex arrays are bound.*/
|
||||
VertexArrayState* getCurrentVertexArrayState() const { return _currentVertexArrayState.get(); }
|
||||
|
||||
|
||||
/** disable the vertex, normal, color, tex coords, secondary color, fog coord and index arrays.*/
|
||||
void disableAllVertexArrays();
|
||||
|
||||
@@ -513,6 +515,8 @@ class OSG_EXPORT State : public Referenced
|
||||
void dirtyAllVertexArrays();
|
||||
|
||||
|
||||
|
||||
|
||||
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
|
||||
const GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
|
||||
inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
|
||||
@@ -551,7 +555,7 @@ class OSG_EXPORT State : public Referenced
|
||||
|
||||
inline void unbindElementBufferObject()
|
||||
{
|
||||
if (!_currentEBO) return;
|
||||
//if (!_currentEBO) return;
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
|
||||
_currentEBO = 0;
|
||||
}
|
||||
@@ -1667,6 +1671,8 @@ class OSG_EXPORT State : public Referenced
|
||||
GraphicsContext* _graphicsContext;
|
||||
unsigned int _contextID;
|
||||
|
||||
osg::ref_ptr<VertexArrayState> _currentVertexArrayState;
|
||||
|
||||
bool _shaderCompositionEnabled;
|
||||
bool _shaderCompositionDirty;
|
||||
osg::ref_ptr<ShaderComposer> _shaderComposer;
|
||||
@@ -1706,6 +1712,7 @@ class OSG_EXPORT State : public Referenced
|
||||
Program::AttribBindingList _attributeBindingList;
|
||||
|
||||
void setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration);
|
||||
|
||||
/** Apply an OpenGL mode if required, passing in mode, enable flag and
|
||||
* appropriate mode stack. This is a wrapper around \c glEnable() and
|
||||
* \c glDisable(), that just actually calls these functions if the
|
||||
|
||||
222
include/osg/VertexArrayState
Normal file
222
include/osg/VertexArrayState
Normal file
@@ -0,0 +1,222 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSG_VertexArrayState
|
||||
#define OSG_VertexArrayState 1
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Array>
|
||||
#include <osg/ArrayDispatchers>
|
||||
|
||||
namespace osg {
|
||||
|
||||
|
||||
|
||||
class VertexArrayState : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
VertexArrayState(osg::GLExtensions* ext);
|
||||
|
||||
struct ArrayDispatch : public osg::Referenced
|
||||
{
|
||||
ArrayDispatch(Array* in_array):
|
||||
array(in_array),
|
||||
modifiedCount(0xffffffff) {}
|
||||
|
||||
inline void dispatchIfDirty(osg::State& state, unsigned int index=0)
|
||||
{
|
||||
if (modifiedCount!=array->getModifiedCount()) dispatch(state, index);
|
||||
}
|
||||
|
||||
virtual void dispatch(osg::State& state, unsigned int index=0) = 0;
|
||||
|
||||
virtual void dispatchDeprecated(osg::State& state, unsigned int index=0);
|
||||
|
||||
osg::Array* array;
|
||||
unsigned int modifiedCount;
|
||||
};
|
||||
|
||||
typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
|
||||
|
||||
ArrayDispatchList& getArrayDispatchList(Array::Binding binding)
|
||||
{
|
||||
switch(binding)
|
||||
{
|
||||
case(osg::Array::BIND_PER_VERTEX): return _dispatchArrays;
|
||||
case(osg::Array::BIND_PER_PRIMITIVE_SET): return _dispatchPerPrimitiveSet;
|
||||
default: return _dispatchOverall;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum VertexArrayIdentifier
|
||||
{
|
||||
VERTEX_ARRAY,
|
||||
NORMAL_ARRAY,
|
||||
COLOR_ARRAY,
|
||||
SECONDARY_COLOR_ARRAY,
|
||||
FOG_COORD_ARRAY,
|
||||
TEX_COORD_ARRAY,
|
||||
VERTEX_ATTRIB_ARRAY=TEX_COORD_ARRAY+32
|
||||
};
|
||||
|
||||
|
||||
void assignVertexArray(osg::Array* array);
|
||||
void assignColorArray(osg::Array* array);
|
||||
void assignNormalArray(osg::Array* array);
|
||||
|
||||
void assignSecondaryColorArray(osg::Array* array);
|
||||
void assignFogCoordArray(osg::Array* array);
|
||||
|
||||
void assignTexCoordArray(unsigned int unit, osg::Array* array);
|
||||
void assignVertexAttribArray(unsigned int unit, osg::Array* array);
|
||||
|
||||
inline void dispatchOverall(osg::State& state)
|
||||
{
|
||||
for(ArrayDispatchList::iterator itr = _dispatchOverall.begin();
|
||||
itr != _dispatchOverall.end();
|
||||
++itr)
|
||||
{
|
||||
(*(*itr)).dispatch(state);
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchPerPrimitveSet(osg::State& state, unsigned int index)
|
||||
{
|
||||
for(ArrayDispatchList::iterator itr = _dispatchPerPrimitiveSet.begin();
|
||||
itr != _dispatchPerPrimitiveSet.end();
|
||||
++itr)
|
||||
{
|
||||
(*(*itr)).dispatch(state, index);
|
||||
}
|
||||
}
|
||||
|
||||
inline void dispatchArrays(osg::State& state)
|
||||
{
|
||||
// need to check previous enabled/disabled mode
|
||||
|
||||
if (_vertexArrayObject)
|
||||
{
|
||||
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
|
||||
itr != _dispatchArrays.end();
|
||||
++itr)
|
||||
{
|
||||
(*(*itr)).dispatch(state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
|
||||
itr != _dispatchArrays.end();
|
||||
++itr)
|
||||
{
|
||||
(*(*itr)).dispatchDeprecated(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void dispatchArraysIfDirty(osg::State& state)
|
||||
{
|
||||
// need to check previous enabled/disabled mode
|
||||
|
||||
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
|
||||
itr != _dispatchArrays.end();
|
||||
++itr)
|
||||
{
|
||||
(*(*itr)).dispatchIfDirty(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Verex Array Object methods.
|
||||
void generateVretexArrayObject();
|
||||
|
||||
void bindVertexArrayObject() const;
|
||||
|
||||
void unbindVertexArrayObject() const;
|
||||
|
||||
GLint getVertexArrayObject() const { return _vertexArrayObject; }
|
||||
|
||||
void releaseGLObjects();
|
||||
|
||||
|
||||
|
||||
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
|
||||
const GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
|
||||
inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
|
||||
{
|
||||
if (vbo)
|
||||
{
|
||||
if (vbo == _currentVBO) return;
|
||||
if (vbo->isDirty()) vbo->compileBuffer();
|
||||
else vbo->bindBuffer();
|
||||
_currentVBO = vbo;
|
||||
}
|
||||
else unbindVertexBufferObject();
|
||||
}
|
||||
|
||||
inline void unbindVertexBufferObject()
|
||||
{
|
||||
if (!_currentVBO) return;
|
||||
_ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
|
||||
_currentVBO = 0;
|
||||
}
|
||||
|
||||
|
||||
void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
|
||||
const GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
|
||||
|
||||
inline void bindElementBufferObject(osg::GLBufferObject* ebo)
|
||||
{
|
||||
if (ebo)
|
||||
{
|
||||
if (ebo == _currentEBO) return;
|
||||
if (ebo->isDirty()) ebo->compileBuffer();
|
||||
else ebo->bindBuffer();
|
||||
_currentEBO = ebo;
|
||||
}
|
||||
else unbindElementBufferObject();
|
||||
}
|
||||
|
||||
inline void unbindElementBufferObject()
|
||||
{
|
||||
if (!_currentEBO) return;
|
||||
_ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
|
||||
_currentEBO = 0;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
osg::GLBufferObject* getGLBufferObject(osg::Array* array);
|
||||
|
||||
osg::ref_ptr<osg::GLExtensions> _ext;
|
||||
|
||||
GLuint _vertexArrayObject;
|
||||
|
||||
GLBufferObject* _currentVBO;
|
||||
GLBufferObject* _currentEBO;
|
||||
|
||||
ArrayDispatchList _dispatchOverall;
|
||||
ArrayDispatchList _dispatchPerPrimitiveSet;
|
||||
ArrayDispatchList _dispatchArrays;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user