diff --git a/examples/osgvertexattributes/osgvertexattributes.cpp b/examples/osgvertexattributes/osgvertexattributes.cpp index a0bb3ce4e..38616aa0e 100644 --- a/examples/osgvertexattributes/osgvertexattributes.cpp +++ b/examples/osgvertexattributes/osgvertexattributes.cpp @@ -31,6 +31,8 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor ConvertToVertexAttibArrays(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { + _manualVertexAliasing = false; + // mappings taken from http://www.opengl.org/registry/specs/NV/vertex_program.txt _vertexAlias = AttributeAlias(0, "osg_Vertex"); _normalAlias = AttributeAlias(2, "osg_Normal"); @@ -57,7 +59,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor if (replace(source, originalStr, alias.second)) { source.insert(0, declarationPrefix + alias.second + std::string(";\n")); - bindAttribute(program, alias); + if (_manualVertexAliasing) bindAttribute(program, alias); } } @@ -76,6 +78,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor // replace ftransform as it only works with built-ins replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex"); +#if 1 replaceAndBindAttrib(program, source, "gl_Normal", _normalAlias, "attribute vec3 "); replaceAndBindAttrib(program, source, "gl_Vertex", _vertexAlias, "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_Color", _colorAlias, "attribute vec4 "); @@ -90,14 +93,9 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor replaceAndBindAttrib(program, source, "gl_MultiTexCoord5", _texCoordAlias[5], "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_MultiTexCoord6", _texCoordAlias[6], "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_MultiTexCoord7", _texCoordAlias[7], "attribute vec4 "); +#endif - -#if 0 - // replace the modelview and project matrices - replace(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix"); - replace(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix"); - replace(source, "gl_ProjectionMatrix", "osg_ProjectionMatrix"); -#else +#if 1 // replace built in uniform replaceBuiltInUniform(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix", "uniform mat4 "); replaceBuiltInUniform(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix", "uniform mat4 "); @@ -186,6 +184,8 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor if (_visited.count(&stateset)!=0) return; _visited.insert(&stateset); + return; + osg::notify(osg::NOTICE)<<"Found stateset "<<&stateset<(stateset.getAttribute(osg::StateAttribute::PROGRAM)); if (program) @@ -203,6 +203,8 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor { geom.setUseDisplayList(false); + if (!_manualVertexAliasing) return; + osg::notify(osg::NOTICE)<<"Found geometry "<<&geom< Visited; Visited _visited; + bool _manualVertexAliasing; AttributeAlias _vertexAlias; AttributeAlias _normalAlias; AttributeAlias _colorAlias; @@ -334,14 +337,19 @@ int main(int argc, char *argv[]) viewer.realize(); - // switch on the uniforms that track the modelview and projection matrices - osgViewer::Viewer::Windows windows; - viewer.getWindows(windows); - for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); - itr != windows.end(); - ++itr) + + if (runConvertToVertexAttributes) { - (*itr)->getState()->setUseModelViewAndProjectionUniforms(true); + // switch on the uniforms that track the modelview and projection matrices + osgViewer::Viewer::Windows windows; + viewer.getWindows(windows); + for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); + itr != windows.end(); + ++itr) + { + (*itr)->getState()->setUseModelViewAndProjectionUniforms(true); + (*itr)->getState()->setUseVertexAttributeAliasing(true); + } } return viewer.run(); diff --git a/include/osg/GLBeginEndAdapter b/include/osg/GLBeginEndAdapter new file mode 100644 index 000000000..27dc1c690 --- /dev/null +++ b/include/osg/GLBeginEndAdapter @@ -0,0 +1,109 @@ +/* -*-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_GLBeginEndAdapter +#define OSG_GLBeginEndAdapter 1 + +#include +#include +#include + +namespace osg { + +// forward declare +class State; + +/** A class adapting OpenGL 1.0 glBegin()/glEnd() style code to vertex array based code */ +class OSG_EXPORT GLBeginEndAdapter +{ + public: + + GLBeginEndAdapter(State* state=0); + + enum MatrixMode + { + APPLY_LOCAL_MATRICES_TO_VERTICES, + APPLY_LOCAL_MATRICES_TO_MODELVIEW + }; + + void setMatrixMode(MatrixMode mode) { _mode = mode; } + MatrixMode setMatrixMode() const { return _mode; } + + void PushMatrix(); + void PopMatrix(); + + void LoadIdentity(); + void LoadMatrixd(const GLdouble* m); + void MultMatrixd(const GLdouble* m); + + void Translated(GLdouble x, GLdouble y, GLdouble z); + void Scaled(GLdouble x, GLdouble y, GLdouble z); + void Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + + void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void Color4fv(const GLfloat* c) { Color4f(c[0], c[1], c[2], c[3]); } + + void Vertex3f(GLfloat x, GLfloat y, GLfloat z); + void Vertex3fv(const GLfloat* v) { Vertex3f(v[0], v[1], v[2]); } + + void Normal3f(GLfloat x, GLfloat y, GLfloat z); + void Normal3fv(const GLfloat* n) { Normal3f(n[0], n[1], n[2]); } + + void TexCoord1f(GLfloat x); + void TexCoord1fv(const GLfloat* tc) { TexCoord1f(tc[0]); } + + void TexCoord2f(GLfloat x, GLfloat y); + void TexCoord2fv(const GLfloat* tc) { TexCoord2f(tc[0],tc[1]); } + + void TexCoord3f(GLfloat x, GLfloat y, GLfloat z); + void TexCoord3fv(const GLfloat* tc) { TexCoord3f(tc[0], tc[1], tc[2]); } + + void TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void TexCoord4fv(const GLfloat* tc) { TexCoord4f(tc[0], tc[1], tc[2], tc[3]); } + + void Begin(GLenum mode); + void End(); + + protected: + + State* _state; + + MatrixMode _mode; + + typedef std::list MatrixStack; + MatrixStack _matrixStack; + + bool _normalSet; + osg::Vec3f _normal; + + bool _colorSet; + osg::Vec4f _color; + + unsigned int _maxNumTexCoordComponents; + osg::Vec4f _texCoord; + + + osg::Vec3f _overallNormal; + osg::Vec4f _overallColor; + + GLenum _primitiveMode; + osg::ref_ptr _vertices; + osg::ref_ptr _normals; + osg::ref_ptr _colors; + osg::ref_ptr _texCoords; +}; + + +} + +#endif diff --git a/include/osg/Program b/include/osg/Program index 38dfaf751..9dcc83e93 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -162,7 +162,7 @@ class OSG_EXPORT Program : public osg::StateAttribute GLuint getHandle() const {return _glProgramHandle;} void requestLink(); - void linkProgram(); + void linkProgram(osg::State& state); bool validateProgram(); bool needsLink() const {return _needsLink;} bool isLinked() const {return _isLinked;} diff --git a/include/osg/Shader b/include/osg/Shader index 8eb719395..d0b48bfaf 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -102,7 +102,7 @@ class OSG_EXPORT Shader : public osg::Object void dirtyShader(); /** If needed, compile the PCS's glShader */ - void compileShader(unsigned int contextID) const; + void compileShader(osg::State& state) const; /** For a given GL context, attach a glShader to a glProgram */ void attachShader(unsigned int contextID, GLuint program) const; @@ -139,7 +139,7 @@ class OSG_EXPORT Shader : public osg::Object GLuint getHandle() const {return _glShaderHandle;} void requestCompile(); - void compileShader(); + void compileShader(osg::State& state); bool needsCompile() const {return _needsCompile;} bool isCompiled() const {return _isCompiled;} bool getInfoLog( std::string& infoLog ) const; diff --git a/include/osg/State b/include/osg/State index d0c562e5a..296e8872f 100644 --- a/include/osg/State +++ b/include/osg/State @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -151,6 +152,7 @@ class OSG_EXPORT State : public Referenced, public Observer /** reset the state object to an empty stack.*/ void reset(); + inline const Viewport* getCurrentViewport() const { return static_cast(getLastAppliedAttribute(osg::StateAttribute::VIEWPORT)); @@ -162,76 +164,36 @@ class OSG_EXPORT State : public Referenced, public Observer inline const osg::Matrix& getInitialViewMatrix() const { return *_initialViewMatrix; } inline const osg::Matrix& getInitialInverseViewMatrix() const { return _initialInverseViewMatrix; } - inline void applyProjectionMatrix(const osg::RefMatrix* matrix) - { - if (_projection!=matrix) - { - if (matrix) - { - _projection=matrix; - } - else - { - _projection=_identity; - } + void applyProjectionMatrix(const osg::RefMatrix* matrix); - if (_useModelViewAndProjectionUniforms) - { - if (_projectionMatrixUniform.valid()) _projectionMatrixUniform->set(*_projection); - if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection)); - } + inline const osg::Matrix& getProjectionMatrix() const { return *_projection; } - glMatrixMode( GL_PROJECTION ); - glLoadMatrix(_projection->ptr()); - glMatrixMode( GL_MODELVIEW ); - } - } + void applyModelViewMatrix(const osg::RefMatrix* matrix); - inline const osg::Matrix& getProjectionMatrix() const - { - return *_projection; - } - - inline void applyModelViewMatrix(const osg::RefMatrix* matrix) - { - if (_modelView!=matrix) - { - if (matrix) - { - _modelView=matrix; - } - else - { - _modelView=_identity; - } - - if (_useModelViewAndProjectionUniforms) - { - if (_modelViewMatrixUniform.valid()) _modelViewMatrixUniform->set(*_modelView); - if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection)); - } - - glLoadMatrix(_modelView->ptr()); - } - } - - const osg::Matrix& getModelViewMatrix() const - { - return *_modelView; - } + const osg::Matrix& getModelViewMatrix() const { return *_modelView; } void setUseModelViewAndProjectionUniforms(bool flag) { _useModelViewAndProjectionUniforms = flag; } bool getUseModelViewAndProjectionUniforms() const { return _useModelViewAndProjectionUniforms; } + void updateModelViewAndProjectionMatrixUniforms(); + void applyModelViewAndProjectionUniformsIfRequired(); osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); } osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); } osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); } + osg::Uniform* getNormalMatrixUniform() { return _normalMatrixUniform.get(); } Polytope getViewFrustum() const; + void setUseVertexAttributeAliasing(bool flag) { _useVertexAttributeAliasing = flag; } + bool getUseVertexAttributeAliasing() const { return _useVertexAttributeAliasing ; } + + const Program::AttribBindingList& getAttributeBindingList() { return _attributeBindingList; } + + bool convertVertexShaderSourceToOsgBuiltIns(std::string& source) const; + /** Apply stateset.*/ void apply(const StateSet* dstate); @@ -496,11 +458,56 @@ class OSG_EXPORT State : public Referenced, public Observer } + inline void Vertex(float x, float y, float z, float w=1.0f) + { + if (_useVertexAttributeAliasing) _glVertexAttrib4f( _vertexAlias._location, x,y,z,w); + else glVertex4f(x,y,z,w); + } + + inline void Color(float r, float g, float b, float a=1.0f) + { + if (_useVertexAttributeAliasing) _glVertexAttrib4f( _colorAlias._location, r,g,b,a); + else glColor4f(r,g,b,a); + } + + void Normal(float x, float y, float z) + { + if (_useVertexAttributeAliasing) _glVertexAttrib4f( _normalAlias._location, x,y,z,0.0); + else glNormal3f(x,y,z); + } + + void TexCoord(float x, float y=0.0f, float z=0.0f, float w=0.0f) + { + if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w); + else glTexCoord4f(x,y,z,w); + } + + void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=0.0f) + { + if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w); + else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w); + } + + void VerteAttrib(unsigned int location, float x, float y=0.0f, float z=0.0f, float w=0.0f) + { + _glVertexAttrib4f( location, x,y,z,w); + } + + + /** Wrapper around glInterleavedArrays(..). * also resets the internal array points and modes within osg::State to keep the other * vertex array operations consistent. */ void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer); + + /** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/ + void lazyDisablingOfVertexAttributes(); + + /** Disable all the vertex attributes that have been marked as to be disabled.*/ + void applyDisablingOfVertexAttributes(); + + /** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/ inline void setVertexPointer(const Array* array) { @@ -518,7 +525,6 @@ class OSG_EXPORT State : public Referenced, public Observer setVertexPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); } } - else disableVertexPointer(); } /** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..); @@ -526,35 +532,58 @@ class OSG_EXPORT State : public Referenced, public Observer inline void setVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { - if (!_vertexArray._enabled || _vertexArray._dirty) + if (_useVertexAttributeAliasing) { - _vertexArray._enabled = true; - glEnableClientState(GL_VERTEX_ARRAY); + setVertexAttribPointer(_vertexAlias._location, size, type, GL_FALSE, stride, ptr); } - //if (_vertexArray._pointer!=ptr || _vertexArray._dirty) + else { - _vertexArray._pointer=ptr; - glVertexPointer( size, type, stride, ptr ); + if (!_vertexArray._enabled || _vertexArray._dirty) + { + _vertexArray._enabled = true; + glEnableClientState(GL_VERTEX_ARRAY); + } + //if (_vertexArray._pointer!=ptr || _vertexArray._dirty) + { + _vertexArray._pointer=ptr; + glVertexPointer( size, type, stride, ptr ); + } + _vertexArray._lazy_disable = false; + _vertexArray._dirty = false; } - _vertexArray._dirty = false; } /** wrapper around glDisableClientState(GL_VERTEX_ARRAY). * note, only updates values that change.*/ inline void disableVertexPointer() { - if (_vertexArray._enabled || _vertexArray._dirty) + if (_useVertexAttributeAliasing) { - _vertexArray._enabled = false; - _vertexArray._dirty = false; - glDisableClientState(GL_VERTEX_ARRAY); + disableVertexAttribPointer(_vertexAlias._location); + } + else + { + if (_vertexArray._enabled || _vertexArray._dirty) + { + _vertexArray._lazy_disable = false; + _vertexArray._enabled = false; + _vertexArray._dirty = false; + glDisableClientState(GL_VERTEX_ARRAY); + } } } inline void dirtyVertexPointer() { - _vertexArray._pointer = 0; - _vertexArray._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_vertexAlias._location); + } + else + { + _vertexArray._pointer = 0; + _vertexArray._dirty = true; + } } @@ -575,7 +604,6 @@ class OSG_EXPORT State : public Referenced, public Observer setNormalPointer(array->getDataType(),0,array->getDataPointer()); } } - else disableNormalPointer(); } /** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..); @@ -583,35 +611,58 @@ class OSG_EXPORT State : public Referenced, public Observer inline void setNormalPointer( GLenum type, GLsizei stride, const GLvoid *ptr ) { - if (!_normalArray._enabled || _normalArray._dirty) + if (_useVertexAttributeAliasing) { - _normalArray._enabled = true; - glEnableClientState(GL_NORMAL_ARRAY); + setVertexAttribPointer(_normalAlias._location, 3, type, GL_FALSE, stride, ptr); } - //if (_normalArray._pointer!=ptr || _normalArray._dirty) + else { - _normalArray._pointer=ptr; - glNormalPointer( type, stride, ptr ); + if (!_normalArray._enabled || _normalArray._dirty) + { + _normalArray._enabled = true; + glEnableClientState(GL_NORMAL_ARRAY); + } + //if (_normalArray._pointer!=ptr || _normalArray._dirty) + { + _normalArray._pointer=ptr; + glNormalPointer( type, stride, ptr ); + } + _normalArray._lazy_disable = false; + _normalArray._dirty = false; } - _normalArray._dirty = false; } /** wrapper around glDisableClientState(GL_NORMAL_ARRAY); * note, only updates values that change.*/ inline void disableNormalPointer() { - if (_normalArray._enabled || _normalArray._dirty) + if (_useVertexAttributeAliasing) { - _normalArray._enabled = false; - _normalArray._dirty = false; - glDisableClientState(GL_NORMAL_ARRAY); + disableVertexAttribPointer(_normalAlias._location); + } + else + { + if (_normalArray._enabled || _normalArray._dirty) + { + _normalArray._lazy_disable = false; + _normalArray._enabled = false; + _normalArray._dirty = false; + glDisableClientState(GL_NORMAL_ARRAY); + } } } inline void dirtyNormalPointer() { - _normalArray._pointer = 0; - _normalArray._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_normalAlias._location); + } + else + { + _normalArray._pointer = 0; + _normalArray._dirty = true; + } } /** Set the color pointer using an osg::Array, and manage any VBO that are required.*/ @@ -631,7 +682,6 @@ class OSG_EXPORT State : public Referenced, public Observer setColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); } } - else disableColorPointer(); } @@ -640,35 +690,58 @@ class OSG_EXPORT State : public Referenced, public Observer inline void setColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { - if (!_colorArray._enabled || _colorArray._dirty) + if (_useVertexAttributeAliasing) { - _colorArray._enabled = true; - glEnableClientState(GL_COLOR_ARRAY); + setVertexAttribPointer(_colorAlias._location, size, type, GL_FALSE, stride, ptr); } - //if (_colorArray._pointer!=ptr || _colorArray._dirty) + else { - _colorArray._pointer=ptr; - glColorPointer( size, type, stride, ptr ); + if (!_colorArray._enabled || _colorArray._dirty) + { + _colorArray._enabled = true; + glEnableClientState(GL_COLOR_ARRAY); + } + //if (_colorArray._pointer!=ptr || _colorArray._dirty) + { + _colorArray._pointer=ptr; + glColorPointer( size, type, stride, ptr ); + } + _colorArray._lazy_disable = false; + _colorArray._dirty = false; } - _colorArray._dirty = false; } /** wrapper around glDisableClientState(GL_COLOR_ARRAY); * note, only updates values that change.*/ inline void disableColorPointer() { - if (_colorArray._enabled || _colorArray._dirty) + if (_useVertexAttributeAliasing) { - _colorArray._enabled = false; - _colorArray._dirty = false; - glDisableClientState(GL_COLOR_ARRAY); + disableVertexAttribPointer(_colorAlias._location); + } + else + { + if (_colorArray._enabled || _colorArray._dirty) + { + _colorArray._lazy_disable = false; + _colorArray._enabled = false; + _colorArray._dirty = false; + glDisableClientState(GL_COLOR_ARRAY); + } } } inline void dirtyColorPointer() { - _colorArray._pointer = 0; - _colorArray._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_colorAlias._location); + } + else + { + _colorArray._pointer = 0; + _colorArray._dirty = true; + } } @@ -692,7 +765,6 @@ class OSG_EXPORT State : public Referenced, public Observer setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); } } - else disableSecondaryColorPointer(); } /** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..); @@ -703,18 +775,33 @@ class OSG_EXPORT State : public Referenced, public Observer * note, only updates values that change.*/ inline void disableSecondaryColorPointer() { - if (_secondaryColorArray._enabled || _secondaryColorArray._dirty) + if (_useVertexAttributeAliasing) { - _secondaryColorArray._enabled = false; - _secondaryColorArray._dirty = false; - if (isSecondaryColorSupported()) glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + disableVertexAttribPointer(_secondaryColorAlias._location); + } + else + { + if (_secondaryColorArray._enabled || _secondaryColorArray._dirty) + { + _secondaryColorArray._lazy_disable = false; + _secondaryColorArray._enabled = false; + _secondaryColorArray._dirty = false; + if (isSecondaryColorSupported()) glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + } } } inline void dirtySecondaryColorPointer() { - _secondaryColorArray._pointer = 0; - _secondaryColorArray._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_secondaryColorAlias._location); + } + else + { + _secondaryColorArray._pointer = 0; + _secondaryColorArray._dirty = true; + } } /** wrapper around glEnableClientState(GL_INDEX_ARRAY);glIndexPointer(..); @@ -774,7 +861,6 @@ class OSG_EXPORT State : public Referenced, public Observer setFogCoordPointer(array->getDataType(),0,array->getDataPointer()); } } - else disableFogCoordPointer(); } @@ -786,18 +872,33 @@ class OSG_EXPORT State : public Referenced, public Observer * note, only updates values that change.*/ inline void disableFogCoordPointer() { - if (_fogArray._enabled || _fogArray._dirty) + if (_useVertexAttributeAliasing) { - _fogArray._enabled = false; - _fogArray._dirty = false; - if (isFogCoordSupported()) glDisableClientState(GL_FOG_COORDINATE_ARRAY); + disableVertexAttribPointer(_fogCoordAlias._location); + } + else + { + if (_fogArray._enabled || _fogArray._dirty) + { + _fogArray._lazy_disable = false; + _fogArray._enabled = false; + _fogArray._dirty = false; + if (isFogCoordSupported()) glDisableClientState(GL_FOG_COORDINATE_ARRAY); + } } } inline void dirtyFogCoordPointer() { - _fogArray._pointer = 0; - _fogArray._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_fogCoordAlias._location); + } + else + { + _fogArray._pointer = 0; + _fogArray._dirty = true; + } } @@ -819,7 +920,6 @@ class OSG_EXPORT State : public Referenced, public Observer setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer()); } } - else disableTexCoordPointer(unit); } /** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..); @@ -828,22 +928,30 @@ class OSG_EXPORT State : public Referenced, public Observer GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { - if (setClientActiveTextureUnit(unit)) + if (_useVertexAttributeAliasing) { - if ( unit >= _texCoordArrayList.size()) _texCoordArrayList.resize(unit+1); - EnabledArrayPair& eap = _texCoordArrayList[unit]; + setVertexAttribPointer(_texCoordAliasList[unit]._location, size, type, GL_FALSE, stride, ptr); + } + else + { + if (setClientActiveTextureUnit(unit)) + { + if ( unit >= _texCoordArrayList.size()) _texCoordArrayList.resize(unit+1); + EnabledArrayPair& eap = _texCoordArrayList[unit]; - if (!eap._enabled || eap._dirty) - { - eap._enabled = true; - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (!eap._enabled || eap._dirty) + { + eap._enabled = true; + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + //if (eap._pointer!=ptr || eap._dirty) + { + glTexCoordPointer( size, type, stride, ptr ); + eap._pointer = ptr; + } + eap._lazy_disable = false; + eap._dirty = false; } - //if (eap._pointer!=ptr || eap._dirty) - { - glTexCoordPointer( size, type, stride, ptr ); - eap._pointer = ptr; - } - eap._dirty = false; } } @@ -851,55 +959,85 @@ class OSG_EXPORT State : public Referenced, public Observer * note, only updates values that change.*/ inline void disableTexCoordPointer( unsigned int unit ) { - if (setClientActiveTextureUnit(unit)) + if (_useVertexAttributeAliasing) { - if ( unit >= _texCoordArrayList.size()) _texCoordArrayList.resize(unit+1); - EnabledArrayPair& eap = _texCoordArrayList[unit]; - - if (eap._enabled || eap._dirty) + disableVertexAttribPointer(_texCoordAliasList[unit]._location); + } + else + { + if (setClientActiveTextureUnit(unit)) { - eap._enabled = false; - eap._dirty = false; - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if ( unit >= _texCoordArrayList.size()) _texCoordArrayList.resize(unit+1); + EnabledArrayPair& eap = _texCoordArrayList[unit]; + + if (eap._enabled || eap._dirty) + { + eap._lazy_disable = false; + eap._enabled = false; + eap._dirty = false; + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } } } } inline void dirtyTexCoordPointer( unsigned int unit ) { - if ( unit >= _texCoordArrayList.size()) return; // _texCoordArrayList.resize(unit+1); - EnabledArrayPair& eap = _texCoordArrayList[unit]; - eap._pointer = 0; - eap._dirty = true; + if (_useVertexAttributeAliasing) + { + dirtyVertexAttribPointer(_texCoordAliasList[unit]._location); + } + else + { + if ( unit >= _texCoordArrayList.size()) return; // _texCoordArrayList.resize(unit+1); + EnabledArrayPair& eap = _texCoordArrayList[unit]; + eap._pointer = 0; + eap._dirty = true; + } } inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit ) { - while (unit<_texCoordArrayList.size()) + if (_useVertexAttributeAliasing) { - EnabledArrayPair& eap = _texCoordArrayList[unit]; - if (eap._enabled || eap._dirty) + disableVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location); + } + else + { + while (unit<_texCoordArrayList.size()) { - if (setClientActiveTextureUnit(unit)) + EnabledArrayPair& eap = _texCoordArrayList[unit]; + if (eap._enabled || eap._dirty) { - eap._enabled = false; - eap._dirty = false; - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (setClientActiveTextureUnit(unit)) + { + eap._lazy_disable = false; + eap._enabled = false; + eap._dirty = false; + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } } + ++unit; } - ++unit; } } inline void dirtyTexCoordPointersAboveAndIncluding( unsigned int unit ) { - while (unit<_texCoordArrayList.size()) + if (_useVertexAttributeAliasing) { - EnabledArrayPair& eap = _texCoordArrayList[unit]; - eap._pointer = 0; - eap._dirty = true; - ++unit; + dirtyVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location); + } + else + { + while (unit<_texCoordArrayList.size()) + { + EnabledArrayPair& eap = _texCoordArrayList[unit]; + eap._pointer = 0; + eap._dirty = true; + ++unit; + } } } @@ -937,7 +1075,6 @@ class OSG_EXPORT State : public Referenced, public Observer setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,array->getDataPointer()); } } - else disableVertexAttribPointer(unit); } /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..); @@ -952,6 +1089,16 @@ class OSG_EXPORT State : public Referenced, public Observer void disableVertexAttribPointersAboveAndIncluding( unsigned int index ); + inline void dirtyVertexAttribPointer( unsigned int index ) + { + if (index<_vertexAttribArrayList.size()) + { + EnabledArrayPair& eap = _vertexAttribArrayList[index]; + eap._pointer = 0; + eap._dirty = true; + } + } + inline void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index ) { while (index<_vertexAttribArrayList.size()) @@ -1096,6 +1243,10 @@ class OSG_EXPORT State : public Referenced, public Observer virtual void objectDeleted(void* object); + /** get the GL adapter object used to map OpenGL 1.0 glBegin/glEnd usage to vertex arrays.*/ + inline GLBeginEndAdapter& getGLBeginEndAdapter() { return _glBeginEndAdapter; } + + protected: virtual ~State(); @@ -1113,6 +1264,7 @@ class OSG_EXPORT State : public Referenced, public Observer ref_ptr _modelViewMatrixUniform; ref_ptr _projectionMatrixUniform; ref_ptr _modelViewProjectionMatrixUniform; + ref_ptr _normalMatrixUniform; Matrix _initialInverseViewMatrix; @@ -1121,6 +1273,38 @@ class OSG_EXPORT State : public Referenced, public Observer bool* _abortRenderingPtr; CheckForGLErrors _checkGLErrors; + struct VertexAttribAlias + { + VertexAttribAlias(): + _location(0) {} + + 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; + }; + + typedef std::vector VertexAttribAliasList; + + bool _useVertexAttributeAliasing; + VertexAttribAlias _vertexAlias; + VertexAttribAlias _normalAlias; + VertexAttribAlias _colorAlias; + VertexAttribAlias _secondaryColorAlias; + VertexAttribAlias _fogCoordAlias; + VertexAttribAliasList _texCoordAliasList; + + Program::AttribBindingList _attributeBindingList; + + void setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration); + + struct ModeStack { typedef std::vector ValueVec; @@ -1260,10 +1444,11 @@ class OSG_EXPORT State : public Referenced, public Observer struct EnabledArrayPair { - EnabledArrayPair():_dirty(true),_enabled(false),_normalized(0),_pointer(0) {} - EnabledArrayPair(const EnabledArrayPair& eap):_dirty(eap._dirty), _enabled(eap._enabled),_normalized(eap._normalized),_pointer(eap._pointer) {} - EnabledArrayPair& operator = (const EnabledArrayPair& eap) { _dirty=eap._dirty; _enabled=eap._enabled; _normalized=eap._normalized;_pointer=eap._pointer; return *this; } + EnabledArrayPair():_lazy_disable(false),_dirty(true),_enabled(false),_normalized(0),_pointer(0) {} + EnabledArrayPair(const EnabledArrayPair& eap):_lazy_disable(eap._lazy_disable),_dirty(eap._dirty), _enabled(eap._enabled),_normalized(eap._normalized),_pointer(eap._pointer) {} + EnabledArrayPair& operator = (const EnabledArrayPair& eap) { _lazy_disable = eap._lazy_disable;_dirty=eap._dirty; _enabled=eap._enabled; _normalized=eap._normalized;_pointer=eap._pointer; return *this; } + bool _lazy_disable; bool _dirty; bool _enabled; GLboolean _normalized; @@ -1341,6 +1526,9 @@ class OSG_EXPORT State : public Referenced, public Observer typedef void (APIENTRY * ActiveTextureProc) (GLenum texture); typedef void (APIENTRY * FogCoordPointerProc) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRY * SecondaryColorPointerProc) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + typedef void (APIENTRY * MultiTexCoord4fProc) (GLenum target, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef void (APIENTRY * VertexAttrib4fProc)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef void (APIENTRY * VertexAttrib4fvProc)(GLuint index, const GLfloat *v); typedef void (APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int); typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int); @@ -1354,6 +1542,9 @@ class OSG_EXPORT State : public Referenced, public Observer GLint _glMaxTextureUnits; ActiveTextureProc _glClientActiveTexture; ActiveTextureProc _glActiveTexture; + MultiTexCoord4fProc _glMultiTexCoord4f; + VertexAttrib4fProc _glVertexAttrib4f; + VertexAttrib4fvProc _glVertexAttrib4fv; FogCoordPointerProc _glFogCoordPointer; SecondaryColorPointerProc _glSecondaryColorPointer; VertexAttribPointerProc _glVertexAttribPointer; @@ -1366,6 +1557,8 @@ class OSG_EXPORT State : public Referenced, public Observer unsigned int _dynamicObjectCount; osg::ref_ptr _completeDynamicObjectRenderingCallback; + GLBeginEndAdapter _glBeginEndAdapter; + }; inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList) diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index 1f90f0fa7..7651aacc1 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -123,7 +123,7 @@ void GLBufferObject::compileBuffer() entry.dataSource != bd || entry.dataSize != bd->getTotalDataSize()) { - GLsizeiptrARB previousEndOfBufferDataMarker = GLsizeiptrARB(entry.offset) + entry.dataSize; + unsigned int previousEndOfBufferDataMarker = entry.offset + entry.dataSize; // osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) updating BufferEntry"< +#include + +#include +#include + +using namespace osg; + +GLBeginEndAdapter::GLBeginEndAdapter(State* state): + _state(state), + _mode(APPLY_LOCAL_MATRICES_TO_VERTICES), + _normalSet(false), + _normal(0.0f,0.0f,1.0f), + _colorSet(false), + _color(1.0f,1.0f,1.0f,1.0f), + _maxNumTexCoordComponents(0), + _texCoord(0.f,0.0f,0.0f,1.0f) +{ +} + +void GLBeginEndAdapter::PushMatrix() +{ + if (_matrixStack.empty()) + { + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) _matrixStack.push_back(Matrixd()); + else _matrixStack.push_back(_state->getModelViewMatrix()); + } + else _matrixStack.push_back(_matrixStack.back()); +} + +void GLBeginEndAdapter::PopMatrix() +{ + if (!_matrixStack.empty()) _matrixStack.pop_back(); +} + + +void GLBeginEndAdapter::LoadIdentity() +{ + if (_matrixStack.empty()) _matrixStack.push_back(Matrixd::identity()); + else _matrixStack.back().makeIdentity(); +} + +void GLBeginEndAdapter::LoadMatrixd(const GLdouble* m) +{ + if (_matrixStack.empty()) _matrixStack.push_back(Matrixd(m)); + else _matrixStack.back().set(m); +} + +void GLBeginEndAdapter::MultMatrixd(const GLdouble* m) +{ + if (_matrixStack.empty()) + { + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) _matrixStack.push_back(Matrixd()); + else _matrixStack.push_back(_state->getModelViewMatrix()); + } + _matrixStack.back().preMult(Matrixd(m)); +} + + +void GLBeginEndAdapter::Translated(GLdouble x, GLdouble y, GLdouble z) +{ + if (_matrixStack.empty()) + { + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) _matrixStack.push_back(Matrixd()); + else _matrixStack.push_back(_state->getModelViewMatrix()); + } + _matrixStack.back().preMultTranslate(Vec3d(x,y,z)); +} + +void GLBeginEndAdapter::Scaled(GLdouble x, GLdouble y, GLdouble z) +{ + if (_matrixStack.empty()) + { + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) _matrixStack.push_back(Matrixd()); + else _matrixStack.push_back(_state->getModelViewMatrix()); + } + _matrixStack.back().preMultScale(Vec3d(x,y,z)); +} + +void GLBeginEndAdapter::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) +{ + if (_matrixStack.empty()) + { + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) _matrixStack.push_back(Matrixd()); + else _matrixStack.push_back(_state->getModelViewMatrix()); + } + _matrixStack.back().preMultRotate(Quat(DegreesToRadians(angle), Vec3d(x,y,z))); +} + +void GLBeginEndAdapter::Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + _normalSet = true; + _color.set(red,green,blue,alpha); +} + +void GLBeginEndAdapter::Normal3f(GLfloat x, GLfloat y, GLfloat z) +{ + _normalSet = true; + _normal.set(x,y,z); +} + +void GLBeginEndAdapter::TexCoord1f(GLfloat x) +{ + _maxNumTexCoordComponents = 1; + _texCoord.set(x,0.0f,0.0f,1.0f); +} + +void GLBeginEndAdapter::TexCoord2f(GLfloat x, GLfloat y) +{ + _maxNumTexCoordComponents = 2; + _texCoord.set(x,y,0.0f,1.0f); +} + +void GLBeginEndAdapter::TexCoord3f(GLfloat x, GLfloat y, GLfloat z) +{ + _maxNumTexCoordComponents = 3; + _texCoord.set(x,y,z,1.0); +} + +void GLBeginEndAdapter::TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + _maxNumTexCoordComponents = 4; + _texCoord.set(x,y,z,w); +} + +void GLBeginEndAdapter::Vertex3f(GLfloat x, GLfloat y, GLfloat z) +{ + osg::Vec3 vertex(x,y,z); + + if (_vertices.valid()) _vertices->push_back(vertex); + if (_normal.valid()) _normals->push_back(_normal); + if (_colors.valid()) _colors->push_back(_color); + if (_texCoords.valid()) _texCoords->push_back(_texCoord); +} + +void GLBeginEndAdapter::Begin(GLenum mode) +{ + _overallNormal = _normal; + _overallColor = _color; + + // reset geometry + _primitiveMode = mode; + if (!_vertices) _vertices = new osg::Vec3Array; + else _vertices->clear(); + + _normalSet = false; + if (!_normals) _normals = new osg::Vec3Array; + else _normals->clear(); + + _colorSet = false; + if (!_colors) _colors = new osg::Vec4Array; + else _colors->clear(); + + _maxNumTexCoordComponents = 0; + if (!_texCoords) _texCoords = new osg::Vec4Array; + else _texCoords->clear(); + +} + +void GLBeginEndAdapter::End() +{ + if (!_vertices || _vertices->empty()) return; + + if (!_matrixStack.empty()) + { + const osg::Matrixd& matrix = _matrixStack.back(); + if (_mode==APPLY_LOCAL_MATRICES_TO_VERTICES) + { + for(Vec3Array::iterator itr = _vertices->begin(); + itr != _vertices->end(); + ++itr) + { + *itr = *itr * matrix; + } + } + else + { + _state->applyModelViewMatrix(new RefMatrix(matrix)); + } + } + + _state->lazyDisablingOfVertexAttributes(); + + _state->setVertexPointer(_vertices.get()); + + if (_colorSet) + { + _state->setColorPointer(_colors.get()); + } + else + { + glColor4fv(_overallColor.ptr()); + } + + if (_normalSet) + { + _state->setNormalPointer(_normals.get()); + } + else + { + glNormal3fv(_overallNormal.ptr()); + } + + if (_maxNumTexCoordComponents!=0) + { + _state->setTexCoordPointer(0, _texCoords.get()); + } + + _state->applyDisablingOfVertexAttributes(); + + glDrawArrays(_primitiveMode, 0, _vertices->size()); +} diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index d9707b983..a60386172 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -1275,6 +1275,7 @@ void Geometry::releaseGLObjects(State* state) const void Geometry::drawImplementation(RenderInfo& renderInfo) const { State& state = *renderInfo.getState(); + bool vertexAttribAlias = state.getUseVertexAttributeAliasing(); // unsigned int contextID = state.getContextID(); @@ -1304,11 +1305,13 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const return; } - DrawNormal drawNormal(_normalData.array.get(),_normalData.indices.get()); - DrawColor drawColor(_colorData.array.get(),_colorData.indices.get()); - DrawSecondaryColor drawSecondaryColor(_secondaryColorData.array.get(),_secondaryColorData.indices.get(),extensions); + AttributeBinding normalBinding = _normalData.binding; + AttributeBinding colorBinding = _colorData.binding; - DrawFogCoord drawFogCoord(_fogCoordData.array.get(),_fogCoordData.indices.get(),extensions); + DrawNormal drawNormal(vertexAttribAlias?0:_normalData.array.get(),vertexAttribAlias?0:_normalData.indices.get()); + DrawColor drawColor(vertexAttribAlias?0:_colorData.array.get(),vertexAttribAlias?0:_colorData.indices.get()); + DrawSecondaryColor drawSecondaryColor(vertexAttribAlias?0:_secondaryColorData.array.get(),vertexAttribAlias?0:_secondaryColorData.indices.get(),extensions); + DrawFogCoord drawFogCoord(vertexAttribAlias?0:_fogCoordData.array.get(),vertexAttribAlias?0:_fogCoordData.indices.get(),extensions); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1334,6 +1337,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const fogCoordBinding = BIND_OFF; } + unsigned int normalIndex = 0; unsigned int colorIndex = 0; unsigned int secondaryColorIndex = 0; @@ -1353,13 +1357,40 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const DrawVertexAttribMap drawVertexAttribMap; bool vertexVertexAttributesSupported = extensions->isVertexProgramSupported(); - bool handleVertexAttributes = (!_vertexAttribList.empty() && vertexVertexAttributesSupported); + bool handleVertexAttributes = (vertexAttribAlias || !_vertexAttribList.empty()) && vertexVertexAttributesSupported; bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); - + + + if (vertexAttribAlias) + { + if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX) + { + osg::notify(osg::NOTICE)<<"normal assign"<getNumElements() > 0 ) - { - drawVertexAttribMap[ab].push_back( - new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); - } - else - { - drawVertexAttribMap[ab].push_back( - new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); - } - } - } - state.disableVertexAttribPointersAboveAndIncluding( index ); - } - else if (vertexVertexAttributesSupported) - { - state.disableVertexAttribPointersAboveAndIncluding( 0 ); - } - - state.setVertexPointer(_vertexData.array.get()); - - - } - else - { - // osg::notify(osg::NOTICE)<<"none VertexBuffer path"<getDataSize(),_vertexData.array->getDataType(),0,_vertexData.array->getDataPointer()); + state.setVertexPointer(_vertexData.array.get()); +#ifndef USE_LAZY_DISABLING else state.disableVertexPointer(); +#endif if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) - state.setNormalPointer(_normalData.array->getDataType(),0,_normalData.array->getDataPointer()); + state.setNormalPointer(_normalData.array.get()); +#ifndef USE_LAZY_DISABLING else state.disableNormalPointer(); +#endif if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) - state.setColorPointer(_colorData.array->getDataSize(),_colorData.array->getDataType(),0,_colorData.array->getDataPointer()); + state.setColorPointer(_colorData.array.get()); +#ifndef USE_LAZY_DISABLING else state.disableColorPointer(); +#endif if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) - state.setSecondaryColorPointer(_secondaryColorData.array->getDataSize(),_secondaryColorData.array->getDataType(),0,_secondaryColorData.array->getDataPointer()); + state.setSecondaryColorPointer(_secondaryColorData.array.get()); +#ifndef USE_LAZY_DISABLING else state.disableSecondaryColorPointer(); +#endif if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid()) - state.setFogCoordPointer(GL_FLOAT,0,_fogCoordData.array->getDataPointer()); + state.setFogCoordPointer(_fogCoordData.array.get()); +#ifndef USE_LAZY_DISABLING else state.disableFogCoordPointer(); +#endif unsigned int unit; for(unit=0;unit<_texCoordList.size();++unit) { const Array* array = _texCoordList[unit].array.get(); if (array) - state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer()); + state.setTexCoordPointer(unit,array); +#ifndef USE_LAZY_DISABLING else state.disableTexCoordPointer(unit); +#endif } +#ifndef USE_LAZY_DISABLING state.disableTexCoordPointersAboveAndIncluding(unit); +#endif if( handleVertexAttributes ) { @@ -1472,7 +1459,110 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const if( ab == BIND_PER_VERTEX && array ) { - state.setVertexAttribPointer( index, array->getDataSize(), array->getDataType(), + state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize ); + } + else + { + if( array ) + { + const IndexArray* indexArray = _vertexAttribList[index].indices.get(); + + if( indexArray && indexArray->getNumElements() > 0 ) + { + drawVertexAttribMap[ab].push_back( + new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); + } + else + { + drawVertexAttribMap[ab].push_back( + new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); + } + } + +#ifndef USE_LAZY_DISABLING + state.disableVertexAttribPointer( index ); +#endif + } + } +#ifndef USE_LAZY_DISABLING + state.disableVertexAttribPointersAboveAndIncluding( index ); +#endif + } +#ifndef USE_LAZY_DISABLING + else if (vertexVertexAttributesSupported) + { + state.disableVertexAttribPointersAboveAndIncluding( 0 ); + } +#endif + } + else + { + // osg::notify(osg::NOTICE)<<"none VertexBuffer path"<getDataSize(),_vertexData.array->getDataType(),0,_vertexData.array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableVertexPointer(); +#endif + + if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) + state.setNormalPointer(_normalData.array->getDataType(),0,_normalData.array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableNormalPointer(); +#endif + + if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) + state.setColorPointer(_colorData.array->getDataSize(),_colorData.array->getDataType(),0,_colorData.array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableColorPointer(); +#endif + + if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) + state.setSecondaryColorPointer(_secondaryColorData.array->getDataSize(),_secondaryColorData.array->getDataType(),0,_secondaryColorData.array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableSecondaryColorPointer(); +#endif + + if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid()) + state.setFogCoordPointer(GL_FLOAT,0,_fogCoordData.array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableFogCoordPointer(); +#endif + + unsigned int unit; + for(unit=0;unit<_texCoordList.size();++unit) + { + const Array* array = _texCoordList[unit].array.get(); + if (array) + state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer()); +#ifndef USE_LAZY_DISABLING + else + state.disableTexCoordPointer(unit); +#endif + } +#ifndef USE_LAZY_DISABLING + state.disableTexCoordPointersAboveAndIncluding(unit); +#endif + + if( handleVertexAttributes ) + { + unsigned int index; + for( index = 0; index < _vertexAttribList.size(); ++index ) + { + const Array* array = _vertexAttribList[index].array.get(); + const AttributeBinding ab = _vertexAttribList[index].binding; + + if( ab == BIND_PER_VERTEX && array ) + { + state.setVertexAttribPointer( index, array->getDataSize(), array->getDataType(), _vertexAttribList[index].normalize, 0, array->getDataPointer() ); } else @@ -1483,34 +1573,44 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const if( indexArray && indexArray->getNumElements() > 0 ) { - drawVertexAttribMap[ab].push_back( + drawVertexAttribMap[ab].push_back( new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); } else { - drawVertexAttribMap[ab].push_back( + drawVertexAttribMap[ab].push_back( new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); } } +#ifndef USE_LAZY_DISABLING state.disableVertexAttribPointer( index ); +#endif } } +#ifndef USE_LAZY_DISABLING state.disableVertexAttribPointersAboveAndIncluding( index ); - +#endif } +#ifndef USE_LAZY_DISABLING else if (vertexVertexAttributesSupported) { state.disableVertexAttribPointersAboveAndIncluding( 0 ); } +#endif } - + +#ifdef USE_LAZY_DISABLING + state.applyDisablingOfVertexAttributes(); +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // pass the overall binding values onto OpenGL. // - if (_normalData.binding==BIND_OVERALL) drawNormal(normalIndex++); - if (_colorData.binding==BIND_OVERALL) drawColor(colorIndex++); + if (normalBinding==BIND_OVERALL) drawNormal(normalIndex++); + if (colorBinding==BIND_OVERALL) drawColor(colorIndex++); if (secondaryColorBinding==BIND_OVERALL) drawSecondaryColor(secondaryColorIndex++); if (fogCoordBinding==BIND_OVERALL) drawFogCoord(fogCoordIndex++); if (handleVertexAttributes) @@ -1532,8 +1632,8 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const ++itr) { - if (_normalData.binding==BIND_PER_PRIMITIVE_SET) drawNormal(normalIndex++); - if (_colorData.binding==BIND_PER_PRIMITIVE_SET) drawColor(colorIndex++); + if (normalBinding==BIND_PER_PRIMITIVE_SET) drawNormal(normalIndex++); + if (colorBinding==BIND_PER_PRIMITIVE_SET) drawColor(colorIndex++); if (secondaryColorBinding==BIND_PER_PRIMITIVE_SET) drawSecondaryColor(secondaryColorIndex++); if (fogCoordBinding==BIND_PER_PRIMITIVE_SET) drawFogCoord(fogCoordIndex++); if (handleVertexAttributes) diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 0bf89d02c..8b7ca7da3 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -181,10 +181,10 @@ void Program::compileGLObjects( osg::State& state ) const for( unsigned int i=0; i < _shaderList.size(); ++i ) { - _shaderList[i]->compileShader( contextID ); + _shaderList[i]->compileShader( state ); } - getPCP( contextID )->linkProgram(); + getPCP( contextID )->linkProgram(state); } void Program::setThreadSafeRefUnref(bool threadSafe) @@ -448,7 +448,7 @@ void Program::PerContextProgram::requestLink() } -void Program::PerContextProgram::linkProgram() +void Program::PerContextProgram::linkProgram(osg::State& state) { if( ! _needsLink ) return; _needsLink = false; @@ -485,13 +485,27 @@ void Program::PerContextProgram::linkProgram() _lastAppliedUniformList.clear(); // set any explicit vertex attribute bindings - const AttribBindingList& bindlist = _program->getAttribBindingList(); - for( AttribBindingList::const_iterator itr = bindlist.begin(); - itr != bindlist.end(); ++itr ) + const AttribBindingList& programBindlist = _program->getAttribBindingList(); + for( AttribBindingList::const_iterator itr = programBindlist.begin(); + itr != programBindlist.end(); ++itr ) { + osg::notify(osg::NOTICE)<<"Program's vertex attrib binding "<second<<", "<first<glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() ); } + // set any explicit vertex attribute bindings that are set up via osg::State, such as the vertex arrays + // that have been aliase to vertex attrib arrays + if (state.getUseVertexAttributeAliasing()) + { + const AttribBindingList& stateBindlist = state.getAttributeBindingList(); + for( AttribBindingList::const_iterator itr = stateBindlist.begin(); + itr != stateBindlist.end(); ++itr ) + { + osg::notify(osg::NOTICE)<<"State's vertex attrib binding "<second<<", "<first<glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() ); + } + } + // set any explicit frag data bindings const FragDataBindingList& fdbindlist = _program->getFragDataBindingList(); for( FragDataBindingList::const_iterator itr = fdbindlist.begin(); diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 3482d333b..5404076d0 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -230,10 +230,10 @@ void Shader::releaseGLObjects(osg::State* state) const } } -void Shader::compileShader( unsigned int contextID ) const +void Shader::compileShader( osg::State& state ) const { - PerContextShader* pcs = getPCS( contextID ); - if( pcs ) pcs->compileShader(); + PerContextShader* pcs = getPCS( state.getContextID() ); + if( pcs ) pcs->compileShader( state ); } @@ -374,12 +374,18 @@ namespace } } -void Shader::PerContextShader::compileShader() +void Shader::PerContextShader::compileShader(osg::State& state) { if( ! _needsCompile ) return; _needsCompile = false; - std::string sourceWithLineNumbers = insertLineNumbers(_shader->getShaderSource()); + std::string source = _shader->getShaderSource(); + if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) + { + state.convertVertexShaderSourceToOsgBuiltIns(source); + } + + std::string sourceWithLineNumbers = insertLineNumbers(source); if (osg::getNotifyLevel()>=osg::INFO) { @@ -389,7 +395,7 @@ void Shader::PerContextShader::compileShader() } GLint compiled = GL_FALSE; - const char* sourceText = _shader->getShaderSource().c_str(); + const char* sourceText = source.c_str(); _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL ); _extensions->glCompileShader( _glShaderHandle ); _extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled ); diff --git a/src/osg/ShapeDrawable.cpp b/src/osg/ShapeDrawable.cpp index 907ae811d..663722393 100644 --- a/src/osg/ShapeDrawable.cpp +++ b/src/osg/ShapeDrawable.cpp @@ -92,7 +92,9 @@ void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius, // The code is mostly duplicated in order to hoist the back/front face // test out of the loop for efficiency - glBegin(GL_QUAD_STRIP); + GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter(); + + gl.Begin(GL_QUAD_STRIP); if (drawFrontFace) { @@ -103,23 +105,23 @@ void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius, float c = cosf(angle); float s = sinf(angle); - glNormal3f(c,s,0.0f); + gl.Normal3f(c,s,0.0f); - glTexCoord2f(texCoord,1.0f); - glVertex3f(c*r,s*r,topz); + gl.TexCoord2f(texCoord,1.0f); + gl.Vertex3f(c*r,s*r,topz); - glTexCoord2f(texCoord,0.0f); - glVertex3f(c*r,s*r,basez); + gl.TexCoord2f(texCoord,0.0f); + gl.Vertex3f(c*r,s*r,basez); } // do last point by hand to ensure no round off errors. - glNormal3f(1.0f,0.0f,0.0f); + gl.Normal3f(1.0f,0.0f,0.0f); - glTexCoord2f(1.0f,1.0f); - glVertex3f(r,0.0f,topz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(r,0.0f,topz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(r,0.0f,basez); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(r,0.0f,basez); } if (drawBackFace) { @@ -130,26 +132,26 @@ void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius, float c = cosf(angle); float s = sinf(angle); - glNormal3f(-c,-s,0.0f); + gl.Normal3f(-c,-s,0.0f); - glTexCoord2f(texCoord,0.0f); - glVertex3f(c*r,s*r,basez); + gl.TexCoord2f(texCoord,0.0f); + gl.Vertex3f(c*r,s*r,basez); - glTexCoord2f(texCoord,1.0f); - glVertex3f(c*r,s*r,topz); + gl.TexCoord2f(texCoord,1.0f); + gl.Vertex3f(c*r,s*r,topz); } // do last point by hand to ensure no round off errors. - glNormal3f(-1.0f,0.0f,0.0f); + gl.Normal3f(-1.0f,0.0f,0.0f); - glTexCoord2f(1.0f,0.0f); - glVertex3f(r,0.0f,basez); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(r,0.0f,basez); - glTexCoord2f(1.0f,1.0f); - glVertex3f(r,0.0f,topz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(r,0.0f,topz); } - glEnd(); + gl.End(); } @@ -176,6 +178,8 @@ void DrawShapeVisitor::drawHalfSphere(unsigned int numSegments, unsigned int num unsigned int rowbegin = top?numRows/2:0; unsigned int rowend = top?numRows:numRows/2; + GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter(); + for(unsigned int rowi=rowbegin; rowigetCreateFrontFace() : true; bool drawBackFace = _hints ? _hints->getCreateBackFace() : false; @@ -302,6 +306,8 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float angleDelta = osg::PI*2.0f/(float)numSegments; float texCoordHorzDelta = 1.0f/(float)numSegments; + gl.Begin(GL_QUAD_STRIP); + if (drawBackFace) { float lBase=-osg::PI*0.5f; @@ -321,7 +327,7 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float nzTop= sinf(lTop); float nRatioTop= cosf(lTop); - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); float angle = 0.0f; float texCoord = 0.0f; @@ -333,32 +339,32 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float c = cosf(angle); float s = sinf(angle); - glNormal3f(-c*nRatioBase,-s*nRatioBase,-nzBase); + gl.Normal3f(-c*nRatioBase,-s*nRatioBase,-nzBase); - glTexCoord2f(texCoord,vBase); - glVertex3f(c*rBase,s*rBase,zBase); + gl.TexCoord2f(texCoord,vBase); + gl.Vertex3f(c*rBase,s*rBase,zBase); - glNormal3f(-c*nRatioTop,-s*nRatioTop,-nzTop); + gl.Normal3f(-c*nRatioTop,-s*nRatioTop,-nzTop); - glTexCoord2f(texCoord,vTop); - glVertex3f(c*rTop,s*rTop,zTop); + gl.TexCoord2f(texCoord,vTop); + gl.Vertex3f(c*rTop,s*rTop,zTop); } // do last point by hand to ensure no round off errors. - glNormal3f(-nRatioBase,0.0f,-nzBase); + gl.Normal3f(-nRatioBase,0.0f,-nzBase); - glTexCoord2f(1.0f,vBase); - glVertex3f(rBase,0.0f,zBase); + gl.TexCoord2f(1.0f,vBase); + gl.Vertex3f(rBase,0.0f,zBase); - glNormal3f(-nRatioTop,0.0f,-nzTop); + gl.Normal3f(-nRatioTop,0.0f,-nzTop); - glTexCoord2f(1.0f,vTop); - glVertex3f(rTop,0.0f,zTop); + gl.TexCoord2f(1.0f,vTop); + gl.Vertex3f(rTop,0.0f,zTop); - glEnd(); + gl.End(); lBase=lTop; @@ -391,7 +397,7 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float nzTop= sinf(lTop); float nRatioTop= cosf(lTop); - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); float angle = 0.0f; float texCoord = 0.0f; @@ -403,30 +409,30 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float c = cosf(angle); float s = sinf(angle); - glNormal3f(c*nRatioTop,s*nRatioTop,nzTop); + gl.Normal3f(c*nRatioTop,s*nRatioTop,nzTop); - glTexCoord2f(texCoord,vTop); - glVertex3f(c*rTop,s*rTop,zTop); + gl.TexCoord2f(texCoord,vTop); + gl.Vertex3f(c*rTop,s*rTop,zTop); - glNormal3f(c*nRatioBase,s*nRatioBase,nzBase); + gl.Normal3f(c*nRatioBase,s*nRatioBase,nzBase); - glTexCoord2f(texCoord,vBase); - glVertex3f(c*rBase,s*rBase,zBase); + gl.TexCoord2f(texCoord,vBase); + gl.Vertex3f(c*rBase,s*rBase,zBase); } // do last point by hand to ensure no round off errors. - glNormal3f(nRatioTop,0.0f,nzTop); + gl.Normal3f(nRatioTop,0.0f,nzTop); - glTexCoord2f(1.0f,vTop); - glVertex3f(rTop,0.0f,zTop); + gl.TexCoord2f(1.0f,vTop); + gl.Vertex3f(rTop,0.0f,zTop); - glNormal3f(nRatioBase,0.0f,nzBase); + gl.Normal3f(nRatioBase,0.0f,nzBase); - glTexCoord2f(1.0f,vBase); - glVertex3f(rBase,0.0f,zBase); + gl.TexCoord2f(1.0f,vBase); + gl.Vertex3f(rBase,0.0f,zBase); - glEnd(); + gl.End(); lBase=lTop; @@ -439,12 +445,13 @@ void DrawShapeVisitor::apply(const Sphere& sphere) } } - - glPopMatrix(); + gl.PopMatrix(); } void DrawShapeVisitor::apply(const Box& box) { + GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter(); + // evaluate hints bool createBody = (_hints ? _hints->getCreateBody() : true); bool createTop = (_hints ? _hints->getCreateTop() : true); @@ -454,130 +461,132 @@ void DrawShapeVisitor::apply(const Box& box) float dy = box.getHalfLengths().y(); float dz = box.getHalfLengths().z(); - glPushMatrix(); + gl.PushMatrix(); - glTranslatef(box.getCenter().x(),box.getCenter().y(),box.getCenter().z()); + gl.Translated(box.getCenter().x(),box.getCenter().y(),box.getCenter().z()); if (!box.zeroRotation()) { - Matrix rotation(box.computeRotationMatrix()); - glMultMatrix(rotation.ptr()); + Matrixd rotation(box.computeRotationMatrix()); + gl.MultMatrixd(rotation.ptr()); } - glBegin(GL_QUADS); + gl.Begin(GL_QUADS); if (createBody) { // -ve y plane - glNormal3f(0.0f,-1.0f,0.0f); + gl.Normal3f(0.0f,-1.0f,0.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(-dx,-dy,dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(-dx,-dy,dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(-dx,-dy,-dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(-dx,-dy,-dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(dx,-dy,-dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(dx,-dy,-dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(dx,-dy,dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(dx,-dy,dz); // +ve y plane - glNormal3f(0.0f,1.0f,0.0f); + gl.Normal3f(0.0f,1.0f,0.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(dx,dy,dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(dx,dy,dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(dx,dy,-dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(dx,dy,-dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(-dx,dy,-dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(-dx,dy,-dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(-dx,dy,dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(-dx,dy,dz); // +ve x plane - glNormal3f(1.0f,0.0f,0.0f); + gl.Normal3f(1.0f,0.0f,0.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(dx,-dy,dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(dx,-dy,dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(dx,-dy,-dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(dx,-dy,-dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(dx,dy,-dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(dx,dy,-dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(dx,dy,dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(dx,dy,dz); // -ve x plane - glNormal3f(-1.0f,0.0f,0.0f); + gl.Normal3f(-1.0f,0.0f,0.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(-dx,dy,dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(-dx,dy,dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(-dx,dy,-dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(-dx,dy,-dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(-dx,-dy,-dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(-dx,-dy,-dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(-dx,-dy,dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(-dx,-dy,dz); } if (createTop) { // +ve z plane - glNormal3f(0.0f,0.0f,1.0f); + gl.Normal3f(0.0f,0.0f,1.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(-dx,dy,dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(-dx,dy,dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(-dx,-dy,dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(-dx,-dy,dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(dx,-dy,dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(dx,-dy,dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(dx,dy,dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(dx,dy,dz); } if (createBottom) { // -ve z plane - glNormal3f(0.0f,0.0f,-1.0f); + gl.Normal3f(0.0f,0.0f,-1.0f); - glTexCoord2f(0.0f,1.0f); - glVertex3f(dx,dy,-dz); + gl.TexCoord2f(0.0f,1.0f); + gl.Vertex3f(dx,dy,-dz); - glTexCoord2f(0.0f,0.0f); - glVertex3f(dx,-dy,-dz); + gl.TexCoord2f(0.0f,0.0f); + gl.Vertex3f(dx,-dy,-dz); - glTexCoord2f(1.0f,0.0f); - glVertex3f(-dx,-dy,-dz); + gl.TexCoord2f(1.0f,0.0f); + gl.Vertex3f(-dx,-dy,-dz); - glTexCoord2f(1.0f,1.0f); - glVertex3f(-dx,dy,-dz); + gl.TexCoord2f(1.0f,1.0f); + gl.Vertex3f(-dx,dy,-dz); } - glEnd(); + gl.End(); - glPopMatrix(); + gl.PopMatrix(); } void DrawShapeVisitor::apply(const Cone& cone) { - glPushMatrix(); + GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter(); - glTranslatef(cone.getCenter().x(),cone.getCenter().y(),cone.getCenter().z()); + gl.PushMatrix(); + + gl.Translated(cone.getCenter().x(),cone.getCenter().y(),cone.getCenter().z()); if (!cone.zeroRotation()) { - Matrix rotation(cone.computeRotationMatrix()); - glMultMatrix(rotation.ptr()); + Matrixd rotation(cone.computeRotationMatrix()); + gl.MultMatrixd(rotation.ptr()); } // evaluate hints @@ -624,7 +633,7 @@ void DrawShapeVisitor::apply(const Cone& cone) // we can't use a fan for the cone top // since we need different normals at the top // for each face.. - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); angle = 0.0f; texCoord = 0.0f; @@ -634,38 +643,38 @@ void DrawShapeVisitor::apply(const Cone& cone) float c = cosf(angle); float s = sinf(angle); - glNormal3f(c*normalRatio,s*normalRatio,normalz); + gl.Normal3f(c*normalRatio,s*normalRatio,normalz); - glTexCoord2f(texCoord,topv); - glVertex3f(c*topr,s*topr,topz); + gl.TexCoord2f(texCoord,topv); + gl.Vertex3f(c*topr,s*topr,topz); - glTexCoord2f(texCoord,basev); - glVertex3f(c*baser,s*baser,basez); + gl.TexCoord2f(texCoord,basev); + gl.Vertex3f(c*baser,s*baser,basez); } // do last point by hand to ensure no round off errors. - glNormal3f(normalRatio,0.0f,normalz); + gl.Normal3f(normalRatio,0.0f,normalz); - glTexCoord2f(1.0f,topv); - glVertex3f(topr,0.0f,topz); + gl.TexCoord2f(1.0f,topv); + gl.Vertex3f(topr,0.0f,topz); - glTexCoord2f(1.0f,basev); - glVertex3f(baser,0.0f,basez); + gl.TexCoord2f(1.0f,basev); + gl.Vertex3f(baser,0.0f,basez); - glEnd(); + gl.End(); } } if (createBottom) { - glBegin(GL_TRIANGLE_FAN); + gl.Begin(GL_TRIANGLE_FAN); angle = osg::PI*2.0f; texCoord = 1.0f; basez = cone.getBaseOffset(); - glNormal3f(0.0f,0.0f,-1.0f); - glTexCoord2f(0.5f,0.5f); - glVertex3f(0.0f,0.0f,basez); + gl.Normal3f(0.0f,0.0f,-1.0f); + gl.TexCoord2f(0.5f,0.5f); + gl.Vertex3f(0.0f,0.0f,basez); for(unsigned int bottomi=0;bottomigetNumElements();i+=3) { @@ -853,15 +868,15 @@ void DrawShapeVisitor::apply(const TriangleMesh& mesh) Vec3 normal = (v2-v1)^(v3-v2); normal.normalize(); - glNormal3fv(normal.ptr()); - glVertex3fv(v1.ptr()); - glVertex3fv(v2.ptr()); - glVertex3fv(v3.ptr()); + gl.Normal3fv(normal.ptr()); + gl.Vertex3fv(v1.ptr()); + gl.Vertex3fv(v2.ptr()); + gl.Vertex3fv(v3.ptr()); } - glEnd(); - } + gl.End(); + } } void DrawShapeVisitor::apply(const ConvexHull& hull) @@ -872,16 +887,18 @@ void DrawShapeVisitor::apply(const ConvexHull& hull) void DrawShapeVisitor::apply(const HeightField& field) { if (field.getNumColumns()==0 || field.getNumRows()==0) return; - - glPushMatrix(); - glTranslatef(field.getOrigin().x(),field.getOrigin().y(),field.getOrigin().z()); + GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter(); + + gl.PushMatrix(); + + gl.Translated(field.getOrigin().x(),field.getOrigin().y(),field.getOrigin().z()); if (!field.zeroRotation()) { - Matrix rotation(field.computeRotationMatrix()); - glMultMatrix(rotation.ptr()); + Matrixd rotation(field.computeRotationMatrix()); + gl.MultMatrixd(rotation.ptr()); } float dx = field.getXInterval(); @@ -900,7 +917,7 @@ void DrawShapeVisitor::apply(const HeightField& field) if (field.getSkirtHeight()!=0.0f) { - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); float u = 0.0f; @@ -913,20 +930,20 @@ void DrawShapeVisitor::apply(const HeightField& field) vertTop.z() = field.getHeight(col,0); normTop.set(field.getNormal(col,0)); - glTexCoord2f(u,0.0f); - glNormal3fv(normTop.ptr()); + gl.TexCoord2f(u,0.0f); + gl.Normal3fv(normTop.ptr()); - glVertex3fv(vertTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); vertTop.z()-=field.getSkirtHeight(); - glVertex3fv(vertTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); } - glEnd(); + gl.End(); // draw top skirt - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); unsigned int row = field.getNumRows()-1; @@ -938,17 +955,17 @@ void DrawShapeVisitor::apply(const HeightField& field) vertTop.z() = field.getHeight(col,row); normTop.set(field.getNormal(col,row)); - glTexCoord2f(u,1.0f); - glNormal3fv(normTop.ptr()); + gl.TexCoord2f(u,1.0f); + gl.Normal3fv(normTop.ptr()); - glVertex3f(vertTop.x(),vertTop.y(),vertTop.z()-field.getSkirtHeight()); + gl.Vertex3f(vertTop.x(),vertTop.y(),vertTop.z()-field.getSkirtHeight()); //vertTop.z()-=field.getSkirtHeight(); - glVertex3fv(vertTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); } - glEnd(); + gl.End(); } @@ -961,7 +978,7 @@ void DrawShapeVisitor::apply(const HeightField& field) float u = 0.0f; - glBegin(GL_QUAD_STRIP); + gl.Begin(GL_QUAD_STRIP); // draw skirt at beginning of this row if required. if (field.getSkirtHeight()!=0.0f) @@ -972,13 +989,13 @@ void DrawShapeVisitor::apply(const HeightField& field) vertBase.set(0.0f,dy*(float)row,field.getHeight(0,row)-field.getSkirtHeight()); normBase.set(field.getNormal(0,row)); - glTexCoord2f(u,vTop); - glNormal3fv(normTop.ptr()); - glVertex3fv(vertTop.ptr()); + gl.TexCoord2f(u,vTop); + gl.Normal3fv(normTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); - glTexCoord2f(u,vBase); - glNormal3fv(normBase.ptr()); - glVertex3fv(vertBase.ptr()); + gl.TexCoord2f(u,vBase); + gl.Normal3fv(normBase.ptr()); + gl.Vertex3fv(vertBase.ptr()); } // draw the actual row @@ -990,13 +1007,13 @@ void DrawShapeVisitor::apply(const HeightField& field) vertBase.set(dx*(float)col,dy*(float)row,field.getHeight(col,row)); normBase.set(field.getNormal(col,row)); - glTexCoord2f(u,vTop); - glNormal3fv(normTop.ptr()); - glVertex3fv(vertTop.ptr()); + gl.TexCoord2f(u,vTop); + gl.Normal3fv(normTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); - glTexCoord2f(u,vBase); - glNormal3fv(normBase.ptr()); - glVertex3fv(vertBase.ptr()); + gl.TexCoord2f(u,vBase); + gl.Normal3fv(normBase.ptr()); + gl.Vertex3fv(vertBase.ptr()); } @@ -1007,20 +1024,20 @@ void DrawShapeVisitor::apply(const HeightField& field) vertBase.z()-=field.getSkirtHeight(); vertTop.z()-=field.getSkirtHeight(); - glTexCoord2f(u,vTop); - glNormal3fv(normTop.ptr()); - glVertex3fv(vertTop.ptr()); + gl.TexCoord2f(u,vTop); + gl.Normal3fv(normTop.ptr()); + gl.Vertex3fv(vertTop.ptr()); - glTexCoord2f(u,vBase); - glNormal3fv(normBase.ptr()); - glVertex3fv(vertBase.ptr()); + gl.TexCoord2f(u,vBase); + gl.Normal3fv(normBase.ptr()); + gl.Vertex3fv(vertBase.ptr()); } - glEnd(); + gl.End(); } - glPopMatrix(); + gl.PopMatrix(); } @@ -1904,6 +1921,7 @@ void PrimitiveShapeVisitor::apply(const CompositeShape& group) ShapeDrawable::ShapeDrawable(): _color(1.0f,1.0f,1.0f,1.0f) { + //setUseDisplayList(false); } ShapeDrawable::ShapeDrawable(Shape* shape,TessellationHints* hints): @@ -1911,6 +1929,7 @@ ShapeDrawable::ShapeDrawable(Shape* shape,TessellationHints* hints): _tessellationHints(hints) { setShape(shape); + //setUseDisplayList(false); } ShapeDrawable::ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop): @@ -1918,6 +1937,7 @@ ShapeDrawable::ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop): _color(pg._color), _tessellationHints(pg._tessellationHints) { + //setUseDisplayList(false); } ShapeDrawable::~ShapeDrawable() @@ -1944,10 +1964,11 @@ void ShapeDrawable::setTessellationHints(TessellationHints* hints) void ShapeDrawable::drawImplementation(RenderInfo& renderInfo) const { osg::State& state = *renderInfo.getState(); + GLBeginEndAdapter& gl = state.getGLBeginEndAdapter(); if (_shape.valid()) { - glColor4fv(_color.ptr()); + gl.Color4fv(_color.ptr()); DrawShapeVisitor dsv(state,_tessellationHints.get()); diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 1a2acb18a..d0bdea730 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -17,6 +17,8 @@ #include #include +#include + #ifndef GL_MAX_TEXTURE_COORDS #define GL_MAX_TEXTURE_COORDS 0x8871 #endif @@ -35,7 +37,8 @@ using namespace osg; static ApplicationUsageProxy State_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_GL_ERROR_CHECKING ","ONCE_PER_ATTRIBUTE | ON | on enables fine grained checking, ONCE_PER_FRAME enables coarse grained checking"); State::State(): - Referenced(true) + Referenced(true), + _glBeginEndAdapter(this) { _graphicsContext = 0; _contextID = 0; @@ -48,6 +51,27 @@ State::State(): _modelViewMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewMatrix"); _projectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ProjectionMatrix"); _modelViewProjectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewProjectionMatrix"); + _normalMatrixUniform = new Uniform(Uniform::FLOAT_MAT3,"osg_NormalMatrix"); + + { + _useVertexAttributeAliasing = false; + setUpVertexAttribAlias(_vertexAlias,0, "gl_Vertex","osg_Vertex","attribute vec4 "); + setUpVertexAttribAlias(_normalAlias, 2, "gl_Normal","osg_Normal","attribute vec3 "); + setUpVertexAttribAlias(_colorAlias, 3, "gl_Color","osg_Color","attribute vec4 "); + setUpVertexAttribAlias(_secondaryColorAlias, 4, "gl_SecondaryColor","osg_SecondaryColor","attribute vec4 "); + setUpVertexAttribAlias(_fogCoordAlias, 5, "gl_FogCoord","osg_FogCoord","attribute float "); + + _texCoordAliasList.resize(8); + for(unsigned int i=0; i<_texCoordAliasList.size(); i++) + { + std::stringstream gl_MultiTexCoord; + std::stringstream osg_MultiTexCoord; + gl_MultiTexCoord<<"gl_MultiTexCoord"<= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); EnabledArrayPair& eap = _vertexAttribArrayList[index]; if (!eap._enabled || eap._dirty) { eap._enabled = true; + // osg::notify(osg::NOTICE)<<" _glEnableVertexAttribArray( "<_lazy_disable = true; + } + } + + for(EnabledVertexAttribArrayList::iterator itr = _vertexAttribArrayList.begin(); + itr != _vertexAttribArrayList.end(); + ++itr) + { + itr->_lazy_disable = true; + } +} + +void State::applyDisablingOfVertexAttributes() +{ + //osg::notify(osg::NOTICE)<<"start of applyDisablingOfVertexAttributes()"<apply(*_modelViewMatrixUniform); if (_projectionMatrixUniform) _lastAppliedProgramObject->apply(*_projectionMatrixUniform); if (_modelViewProjectionMatrixUniform) _lastAppliedProgramObject->apply(*_modelViewProjectionMatrixUniform); + if (_normalMatrixUniform) _lastAppliedProgramObject->apply(*_normalMatrixUniform); +} + +namespace State_Utils +{ + bool replace(std::string& str, const std::string& original_phrase, const std::string& new_phrase) + { + bool replacedStr = false; + std::string::size_type pos = 0; + while((pos=str.find(original_phrase, pos))!=std::string::npos) + { + std::string::size_type endOfPhrasePos = pos+original_phrase.size(); + if (endOfPhrasePos='0' && c<='9') || + (c>='a' && c<='z') || + (c>='A' && c<='Z')) + { + pos = endOfPhrasePos; + continue; + } + } + + replacedStr = true; + str.replace(pos, original_phrase.size(), new_phrase); + } + return replacedStr; + } + + void replaceAndInsertDeclaration(std::string& source, const std::string& originalStr, const std::string& newStr, const std::string& declarationPrefix) + { + if (replace(source, originalStr, newStr)) + { + source.insert(0, declarationPrefix + newStr + std::string(";\n")); + } + } +} + +bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const +{ + osg::notify(osg::NOTICE)<<"State::convertShaderSourceToOsgBuiltIns()"<set(*_projection); + updateModelViewAndProjectionMatrixUniforms(); + } + + glMatrixMode( GL_PROJECTION ); + glLoadMatrix(_projection->ptr()); + glMatrixMode( GL_MODELVIEW ); + } +} + +void State::applyModelViewMatrix(const osg::RefMatrix* matrix) +{ + if (_modelView!=matrix) + { + if (matrix) + { + _modelView=matrix; + } + else + { + _modelView=_identity; + } + + if (_useModelViewAndProjectionUniforms) + { + if (_modelViewMatrixUniform.valid()) _modelViewMatrixUniform->set(*_modelView); + updateModelViewAndProjectionMatrixUniforms(); + } + + glLoadMatrix(_modelView->ptr()); + } +} + +#include + +void State::updateModelViewAndProjectionMatrixUniforms() +{ + if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection)); + if (_normalMatrixUniform.valid()) + { +#if 0 + Matrix mv(*_modelView); + mv.setTrans(0.0, 0.0, 0.0); + + Matrix matrix; + matrix.invert(mv); +#else + Matrix matrix = *_modelView; +#endif + +#if 0 + Matrix3 normalMatrix(matrix(0,0), matrix(1,0), matrix(2,0), + matrix(0,1), matrix(1,1), matrix(2,1), + matrix(0,2), matrix(1,2), matrix(2,2)); +#else + Matrix3 normalMatrix(matrix(0,0), matrix(0,0), matrix(0,0), + matrix(1,0), matrix(1,1), matrix(1,0), + matrix(2,0), matrix(2,0), matrix(2,2)); +#endif + + osg::notify(osg::NOTICE)<<"modelview "<<*_modelView<set(normalMatrix); + } } diff --git a/src/osgUtil/SceneGraphBuilder.cpp b/src/osgUtil/SceneGraphBuilder.cpp index 060c660c3..53274cec2 100644 --- a/src/osgUtil/SceneGraphBuilder.cpp +++ b/src/osgUtil/SceneGraphBuilder.cpp @@ -35,8 +35,11 @@ using namespace osgUtil; SceneGraphBuilder::SceneGraphBuilder(): _statesetAssigned(false), + _normalSet(false), _normal(0.0f,0.0f,1.0f), + _colorSet(false), _color(1.0f,1.0f,1.0f,1.0f), + _maxNumTexCoordComponents(0), _texCoord(0.f,0.0f,0.0f,1.0f) { }