Ported osg::Geometry across to supporting the aliasing of vertex, color and normal etc. calls to Vertex Attributes.

Added support for automatic aliasing of vertex, normal, color etc. arrays to Vertex Attribute equivelants.

Added new osg::GLBeginEndAdapter class for runtime conversion from glBegin/glEnd codes to vertex arrray equivelants.

Added automatic shader source conversion from gl_ to osg_ builtins.
This commit is contained in:
Robert Osfield 2009-10-16 16:26:27 +00:00
parent 9e2567cb88
commit aefd1513f4
14 changed files with 1479 additions and 537 deletions

View File

@ -31,6 +31,8 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
ConvertToVertexAttibArrays(): ConvertToVertexAttibArrays():
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{ {
_manualVertexAliasing = false;
// mappings taken from http://www.opengl.org/registry/specs/NV/vertex_program.txt // mappings taken from http://www.opengl.org/registry/specs/NV/vertex_program.txt
_vertexAlias = AttributeAlias(0, "osg_Vertex"); _vertexAlias = AttributeAlias(0, "osg_Vertex");
_normalAlias = AttributeAlias(2, "osg_Normal"); _normalAlias = AttributeAlias(2, "osg_Normal");
@ -57,7 +59,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
if (replace(source, originalStr, alias.second)) if (replace(source, originalStr, alias.second))
{ {
source.insert(0, declarationPrefix + alias.second + std::string(";\n")); 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 ftransform as it only works with built-ins
replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex"); replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex");
#if 1
replaceAndBindAttrib(program, source, "gl_Normal", _normalAlias, "attribute vec3 "); replaceAndBindAttrib(program, source, "gl_Normal", _normalAlias, "attribute vec3 ");
replaceAndBindAttrib(program, source, "gl_Vertex", _vertexAlias, "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_Vertex", _vertexAlias, "attribute vec4 ");
replaceAndBindAttrib(program, source, "gl_Color", _colorAlias, "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_MultiTexCoord5", _texCoordAlias[5], "attribute vec4 ");
replaceAndBindAttrib(program, source, "gl_MultiTexCoord6", _texCoordAlias[6], "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_MultiTexCoord6", _texCoordAlias[6], "attribute vec4 ");
replaceAndBindAttrib(program, source, "gl_MultiTexCoord7", _texCoordAlias[7], "attribute vec4 "); replaceAndBindAttrib(program, source, "gl_MultiTexCoord7", _texCoordAlias[7], "attribute vec4 ");
#endif
#if 1
#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
// replace built in uniform // replace built in uniform
replaceBuiltInUniform(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix", "uniform mat4 "); replaceBuiltInUniform(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix", "uniform mat4 ");
replaceBuiltInUniform(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix", "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; if (_visited.count(&stateset)!=0) return;
_visited.insert(&stateset); _visited.insert(&stateset);
return;
osg::notify(osg::NOTICE)<<"Found stateset "<<&stateset<<std::endl; osg::notify(osg::NOTICE)<<"Found stateset "<<&stateset<<std::endl;
osg::Program* program = dynamic_cast<osg::Program*>(stateset.getAttribute(osg::StateAttribute::PROGRAM)); osg::Program* program = dynamic_cast<osg::Program*>(stateset.getAttribute(osg::StateAttribute::PROGRAM));
if (program) if (program)
@ -203,6 +203,8 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
{ {
geom.setUseDisplayList(false); geom.setUseDisplayList(false);
if (!_manualVertexAliasing) return;
osg::notify(osg::NOTICE)<<"Found geometry "<<&geom<<std::endl; osg::notify(osg::NOTICE)<<"Found geometry "<<&geom<<std::endl;
if (geom.getVertexArray()) if (geom.getVertexArray())
{ {
@ -212,7 +214,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
if (geom.getNormalArray()) if (geom.getNormalArray())
{ {
setVertexAttrib(geom, _normalAlias, geom.getNormalArray(), false, geom.getNormalBinding()); setVertexAttrib(geom, _normalAlias, geom.getNormalArray(), true, geom.getNormalBinding());
geom.setNormalArray(0); geom.setNormalArray(0);
} }
@ -231,7 +233,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
if (geom.getFogCoordArray()) if (geom.getFogCoordArray())
{ {
// should we normalize the FogCoord array? Don't think so... // should we normalize the FogCoord array? Don't think so...
setVertexAttrib(geom, _fogCoordAlias, geom.getFogCoordArray(), false, geom.getSecondaryColorBinding()); setVertexAttrib(geom, _fogCoordAlias, geom.getFogCoordArray(), false, geom.getFogCoordBinding());
geom.setFogCoordArray(0); geom.setFogCoordArray(0);
} }
@ -271,6 +273,7 @@ class ConvertToVertexAttibArrays : public osg::NodeVisitor
typedef std::set<osg::Object*> Visited; typedef std::set<osg::Object*> Visited;
Visited _visited; Visited _visited;
bool _manualVertexAliasing;
AttributeAlias _vertexAlias; AttributeAlias _vertexAlias;
AttributeAlias _normalAlias; AttributeAlias _normalAlias;
AttributeAlias _colorAlias; AttributeAlias _colorAlias;
@ -334,6 +337,9 @@ int main(int argc, char *argv[])
viewer.realize(); viewer.realize();
if (runConvertToVertexAttributes)
{
// switch on the uniforms that track the modelview and projection matrices // switch on the uniforms that track the modelview and projection matrices
osgViewer::Viewer::Windows windows; osgViewer::Viewer::Windows windows;
viewer.getWindows(windows); viewer.getWindows(windows);
@ -342,6 +348,8 @@ int main(int argc, char *argv[])
++itr) ++itr)
{ {
(*itr)->getState()->setUseModelViewAndProjectionUniforms(true); (*itr)->getState()->setUseModelViewAndProjectionUniforms(true);
(*itr)->getState()->setUseVertexAttributeAliasing(true);
}
} }
return viewer.run(); return viewer.run();

View File

@ -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 <osg/ref_ptr>
#include <osg/Array>
#include <osg/Matrixd>
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<Matrixd> 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<osg::Vec3Array> _vertices;
osg::ref_ptr<osg::Vec3Array> _normals;
osg::ref_ptr<osg::Vec4Array> _colors;
osg::ref_ptr<osg::Vec4Array> _texCoords;
};
}
#endif

View File

@ -162,7 +162,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
GLuint getHandle() const {return _glProgramHandle;} GLuint getHandle() const {return _glProgramHandle;}
void requestLink(); void requestLink();
void linkProgram(); void linkProgram(osg::State& state);
bool validateProgram(); bool validateProgram();
bool needsLink() const {return _needsLink;} bool needsLink() const {return _needsLink;}
bool isLinked() const {return _isLinked;} bool isLinked() const {return _isLinked;}

View File

@ -102,7 +102,7 @@ class OSG_EXPORT Shader : public osg::Object
void dirtyShader(); void dirtyShader();
/** If needed, compile the PCS's glShader */ /** 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 */ /** For a given GL context, attach a glShader to a glProgram */
void attachShader(unsigned int contextID, GLuint program) const; void attachShader(unsigned int contextID, GLuint program) const;
@ -139,7 +139,7 @@ class OSG_EXPORT Shader : public osg::Object
GLuint getHandle() const {return _glShaderHandle;} GLuint getHandle() const {return _glShaderHandle;}
void requestCompile(); void requestCompile();
void compileShader(); void compileShader(osg::State& state);
bool needsCompile() const {return _needsCompile;} bool needsCompile() const {return _needsCompile;}
bool isCompiled() const {return _isCompiled;} bool isCompiled() const {return _isCompiled;}
bool getInfoLog( std::string& infoLog ) const; bool getInfoLog( std::string& infoLog ) const;

View File

@ -25,6 +25,7 @@
#include <osg/DisplaySettings> #include <osg/DisplaySettings>
#include <osg/Polytope> #include <osg/Polytope>
#include <osg/Viewport> #include <osg/Viewport>
#include <osg/GLBeginEndAdapter>
#include <vector> #include <vector>
#include <map> #include <map>
@ -151,6 +152,7 @@ class OSG_EXPORT State : public Referenced, public Observer
/** reset the state object to an empty stack.*/ /** reset the state object to an empty stack.*/
void reset(); void reset();
inline const Viewport* getCurrentViewport() const inline const Viewport* getCurrentViewport() const
{ {
return static_cast<const Viewport*>(getLastAppliedAttribute(osg::StateAttribute::VIEWPORT)); return static_cast<const Viewport*>(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& getInitialViewMatrix() const { return *_initialViewMatrix; }
inline const osg::Matrix& getInitialInverseViewMatrix() const { return _initialInverseViewMatrix; } inline const osg::Matrix& getInitialInverseViewMatrix() const { return _initialInverseViewMatrix; }
inline void applyProjectionMatrix(const osg::RefMatrix* matrix) void applyProjectionMatrix(const osg::RefMatrix* matrix);
{
if (_projection!=matrix)
{
if (matrix)
{
_projection=matrix;
}
else
{
_projection=_identity;
}
if (_useModelViewAndProjectionUniforms) inline const osg::Matrix& getProjectionMatrix() const { return *_projection; }
{
if (_projectionMatrixUniform.valid()) _projectionMatrixUniform->set(*_projection);
if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection));
}
glMatrixMode( GL_PROJECTION ); void applyModelViewMatrix(const osg::RefMatrix* matrix);
glLoadMatrix(_projection->ptr());
glMatrixMode( GL_MODELVIEW );
}
}
inline const osg::Matrix& getProjectionMatrix() const const osg::Matrix& getModelViewMatrix() const { return *_modelView; }
{
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;
}
void setUseModelViewAndProjectionUniforms(bool flag) { _useModelViewAndProjectionUniforms = flag; } void setUseModelViewAndProjectionUniforms(bool flag) { _useModelViewAndProjectionUniforms = flag; }
bool getUseModelViewAndProjectionUniforms() const { return _useModelViewAndProjectionUniforms; } bool getUseModelViewAndProjectionUniforms() const { return _useModelViewAndProjectionUniforms; }
void updateModelViewAndProjectionMatrixUniforms();
void applyModelViewAndProjectionUniformsIfRequired(); void applyModelViewAndProjectionUniformsIfRequired();
osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); } osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); }
osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); } osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); }
osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); } osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); }
osg::Uniform* getNormalMatrixUniform() { return _normalMatrixUniform.get(); }
Polytope getViewFrustum() const; 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.*/ /** Apply stateset.*/
void apply(const StateSet* dstate); 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(..). /** Wrapper around glInterleavedArrays(..).
* also resets the internal array points and modes within osg::State to keep the other * also resets the internal array points and modes within osg::State to keep the other
* vertex array operations consistent. */ * vertex array operations consistent. */
void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer); 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.*/ /** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
inline void setVertexPointer(const Array* array) inline void setVertexPointer(const Array* array)
{ {
@ -518,13 +525,18 @@ class OSG_EXPORT State : public Referenced, public Observer
setVertexPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); setVertexPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
} }
} }
else disableVertexPointer();
} }
/** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..); /** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void setVertexPointer( GLint size, GLenum type, inline void setVertexPointer( GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr ) GLsizei stride, const GLvoid *ptr )
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_vertexAlias._location, size, type, GL_FALSE, stride, ptr);
}
else
{ {
if (!_vertexArray._enabled || _vertexArray._dirty) if (!_vertexArray._enabled || _vertexArray._dirty)
{ {
@ -536,26 +548,43 @@ class OSG_EXPORT State : public Referenced, public Observer
_vertexArray._pointer=ptr; _vertexArray._pointer=ptr;
glVertexPointer( size, type, stride, ptr ); glVertexPointer( size, type, stride, ptr );
} }
_vertexArray._lazy_disable = false;
_vertexArray._dirty = false; _vertexArray._dirty = false;
} }
}
/** wrapper around glDisableClientState(GL_VERTEX_ARRAY). /** wrapper around glDisableClientState(GL_VERTEX_ARRAY).
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableVertexPointer() inline void disableVertexPointer()
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_vertexAlias._location);
}
else
{ {
if (_vertexArray._enabled || _vertexArray._dirty) if (_vertexArray._enabled || _vertexArray._dirty)
{ {
_vertexArray._lazy_disable = false;
_vertexArray._enabled = false; _vertexArray._enabled = false;
_vertexArray._dirty = false; _vertexArray._dirty = false;
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
} }
} }
}
inline void dirtyVertexPointer() inline void dirtyVertexPointer()
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_vertexAlias._location);
}
else
{ {
_vertexArray._pointer = 0; _vertexArray._pointer = 0;
_vertexArray._dirty = true; _vertexArray._dirty = true;
} }
}
/** Set the normal pointer using an osg::Array, and manage any VBO that are required.*/ /** Set the normal pointer using an osg::Array, and manage any VBO that are required.*/
@ -575,13 +604,18 @@ class OSG_EXPORT State : public Referenced, public Observer
setNormalPointer(array->getDataType(),0,array->getDataPointer()); setNormalPointer(array->getDataType(),0,array->getDataPointer());
} }
} }
else disableNormalPointer();
} }
/** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..); /** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void setNormalPointer( GLenum type, GLsizei stride, inline void setNormalPointer( GLenum type, GLsizei stride,
const GLvoid *ptr ) const GLvoid *ptr )
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_normalAlias._location, 3, type, GL_FALSE, stride, ptr);
}
else
{ {
if (!_normalArray._enabled || _normalArray._dirty) if (!_normalArray._enabled || _normalArray._dirty)
{ {
@ -593,26 +627,43 @@ class OSG_EXPORT State : public Referenced, public Observer
_normalArray._pointer=ptr; _normalArray._pointer=ptr;
glNormalPointer( type, stride, ptr ); glNormalPointer( type, stride, ptr );
} }
_normalArray._lazy_disable = false;
_normalArray._dirty = false; _normalArray._dirty = false;
} }
}
/** wrapper around glDisableClientState(GL_NORMAL_ARRAY); /** wrapper around glDisableClientState(GL_NORMAL_ARRAY);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableNormalPointer() inline void disableNormalPointer()
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_normalAlias._location);
}
else
{ {
if (_normalArray._enabled || _normalArray._dirty) if (_normalArray._enabled || _normalArray._dirty)
{ {
_normalArray._lazy_disable = false;
_normalArray._enabled = false; _normalArray._enabled = false;
_normalArray._dirty = false; _normalArray._dirty = false;
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
} }
} }
}
inline void dirtyNormalPointer() inline void dirtyNormalPointer()
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_normalAlias._location);
}
else
{ {
_normalArray._pointer = 0; _normalArray._pointer = 0;
_normalArray._dirty = true; _normalArray._dirty = true;
} }
}
/** Set the color pointer using an osg::Array, and manage any VBO that are required.*/ /** Set the color pointer using an osg::Array, and manage any VBO that are required.*/
inline void setColorPointer(const Array* array) inline void setColorPointer(const Array* array)
@ -631,7 +682,6 @@ class OSG_EXPORT State : public Referenced, public Observer
setColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); setColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
} }
} }
else disableColorPointer();
} }
@ -639,6 +689,12 @@ class OSG_EXPORT State : public Referenced, public Observer
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void setColorPointer( GLint size, GLenum type, inline void setColorPointer( GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr ) GLsizei stride, const GLvoid *ptr )
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_colorAlias._location, size, type, GL_FALSE, stride, ptr);
}
else
{ {
if (!_colorArray._enabled || _colorArray._dirty) if (!_colorArray._enabled || _colorArray._dirty)
{ {
@ -650,26 +706,43 @@ class OSG_EXPORT State : public Referenced, public Observer
_colorArray._pointer=ptr; _colorArray._pointer=ptr;
glColorPointer( size, type, stride, ptr ); glColorPointer( size, type, stride, ptr );
} }
_colorArray._lazy_disable = false;
_colorArray._dirty = false; _colorArray._dirty = false;
} }
}
/** wrapper around glDisableClientState(GL_COLOR_ARRAY); /** wrapper around glDisableClientState(GL_COLOR_ARRAY);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableColorPointer() inline void disableColorPointer()
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_colorAlias._location);
}
else
{ {
if (_colorArray._enabled || _colorArray._dirty) if (_colorArray._enabled || _colorArray._dirty)
{ {
_colorArray._lazy_disable = false;
_colorArray._enabled = false; _colorArray._enabled = false;
_colorArray._dirty = false; _colorArray._dirty = false;
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
} }
} }
}
inline void dirtyColorPointer() inline void dirtyColorPointer()
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_colorAlias._location);
}
else
{ {
_colorArray._pointer = 0; _colorArray._pointer = 0;
_colorArray._dirty = true; _colorArray._dirty = true;
} }
}
inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupportResolved?_isSecondaryColorSupported:computeSecondaryColorSupported(); } inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupportResolved?_isSecondaryColorSupported:computeSecondaryColorSupported(); }
@ -692,7 +765,6 @@ class OSG_EXPORT State : public Referenced, public Observer
setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer()); setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
} }
} }
else disableSecondaryColorPointer();
} }
/** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..); /** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..);
@ -702,20 +774,35 @@ class OSG_EXPORT State : public Referenced, public Observer
/** wrapper around glDisableClientState(GL_SECONDARY_COLOR_ARRAY); /** wrapper around glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableSecondaryColorPointer() inline void disableSecondaryColorPointer()
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_secondaryColorAlias._location);
}
else
{ {
if (_secondaryColorArray._enabled || _secondaryColorArray._dirty) if (_secondaryColorArray._enabled || _secondaryColorArray._dirty)
{ {
_secondaryColorArray._lazy_disable = false;
_secondaryColorArray._enabled = false; _secondaryColorArray._enabled = false;
_secondaryColorArray._dirty = false; _secondaryColorArray._dirty = false;
if (isSecondaryColorSupported()) glDisableClientState(GL_SECONDARY_COLOR_ARRAY); if (isSecondaryColorSupported()) glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
} }
} }
}
inline void dirtySecondaryColorPointer() inline void dirtySecondaryColorPointer()
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_secondaryColorAlias._location);
}
else
{ {
_secondaryColorArray._pointer = 0; _secondaryColorArray._pointer = 0;
_secondaryColorArray._dirty = true; _secondaryColorArray._dirty = true;
} }
}
/** wrapper around glEnableClientState(GL_INDEX_ARRAY);glIndexPointer(..); /** wrapper around glEnableClientState(GL_INDEX_ARRAY);glIndexPointer(..);
* note, only updates values that change.*/ * note, only updates values that change.*/
@ -774,7 +861,6 @@ class OSG_EXPORT State : public Referenced, public Observer
setFogCoordPointer(array->getDataType(),0,array->getDataPointer()); setFogCoordPointer(array->getDataType(),0,array->getDataPointer());
} }
} }
else disableFogCoordPointer();
} }
@ -785,20 +871,35 @@ class OSG_EXPORT State : public Referenced, public Observer
/** wrapper around glDisableClientState(GL_FOG_COORDINATE_ARRAY); /** wrapper around glDisableClientState(GL_FOG_COORDINATE_ARRAY);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableFogCoordPointer() inline void disableFogCoordPointer()
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_fogCoordAlias._location);
}
else
{ {
if (_fogArray._enabled || _fogArray._dirty) if (_fogArray._enabled || _fogArray._dirty)
{ {
_fogArray._lazy_disable = false;
_fogArray._enabled = false; _fogArray._enabled = false;
_fogArray._dirty = false; _fogArray._dirty = false;
if (isFogCoordSupported()) glDisableClientState(GL_FOG_COORDINATE_ARRAY); if (isFogCoordSupported()) glDisableClientState(GL_FOG_COORDINATE_ARRAY);
} }
} }
}
inline void dirtyFogCoordPointer() inline void dirtyFogCoordPointer()
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_fogCoordAlias._location);
}
else
{ {
_fogArray._pointer = 0; _fogArray._pointer = 0;
_fogArray._dirty = true; _fogArray._dirty = true;
} }
}
@ -819,7 +920,6 @@ class OSG_EXPORT State : public Referenced, public Observer
setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer()); setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer());
} }
} }
else disableTexCoordPointer(unit);
} }
/** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..); /** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..);
@ -827,6 +927,12 @@ class OSG_EXPORT State : public Referenced, public Observer
inline void setTexCoordPointer( unsigned int unit, inline void setTexCoordPointer( unsigned int unit,
GLint size, GLenum type, GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr ) GLsizei stride, const GLvoid *ptr )
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_texCoordAliasList[unit]._location, size, type, GL_FALSE, stride, ptr);
}
else
{ {
if (setClientActiveTextureUnit(unit)) if (setClientActiveTextureUnit(unit))
{ {
@ -843,13 +949,21 @@ class OSG_EXPORT State : public Referenced, public Observer
glTexCoordPointer( size, type, stride, ptr ); glTexCoordPointer( size, type, stride, ptr );
eap._pointer = ptr; eap._pointer = ptr;
} }
eap._lazy_disable = false;
eap._dirty = false; eap._dirty = false;
} }
} }
}
/** wrapper around glDisableClientState(GL_TEXTURE_COORD_ARRAY); /** wrapper around glDisableClientState(GL_TEXTURE_COORD_ARRAY);
* note, only updates values that change.*/ * note, only updates values that change.*/
inline void disableTexCoordPointer( unsigned int unit ) inline void disableTexCoordPointer( unsigned int unit )
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointer(_texCoordAliasList[unit]._location);
}
else
{ {
if (setClientActiveTextureUnit(unit)) if (setClientActiveTextureUnit(unit))
{ {
@ -858,23 +972,38 @@ class OSG_EXPORT State : public Referenced, public Observer
if (eap._enabled || eap._dirty) if (eap._enabled || eap._dirty)
{ {
eap._lazy_disable = false;
eap._enabled = false; eap._enabled = false;
eap._dirty = false; eap._dirty = false;
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
} }
} }
}
inline void dirtyTexCoordPointer( unsigned int unit ) inline void dirtyTexCoordPointer( unsigned int unit )
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointer(_texCoordAliasList[unit]._location);
}
else
{ {
if ( unit >= _texCoordArrayList.size()) return; // _texCoordArrayList.resize(unit+1); if ( unit >= _texCoordArrayList.size()) return; // _texCoordArrayList.resize(unit+1);
EnabledArrayPair& eap = _texCoordArrayList[unit]; EnabledArrayPair& eap = _texCoordArrayList[unit];
eap._pointer = 0; eap._pointer = 0;
eap._dirty = true; eap._dirty = true;
} }
}
inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit ) inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit )
{
if (_useVertexAttributeAliasing)
{
disableVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location);
}
else
{ {
while (unit<_texCoordArrayList.size()) while (unit<_texCoordArrayList.size())
{ {
@ -883,6 +1012,7 @@ class OSG_EXPORT State : public Referenced, public Observer
{ {
if (setClientActiveTextureUnit(unit)) if (setClientActiveTextureUnit(unit))
{ {
eap._lazy_disable = false;
eap._enabled = false; eap._enabled = false;
eap._dirty = false; eap._dirty = false;
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@ -891,8 +1021,15 @@ class OSG_EXPORT State : public Referenced, public Observer
++unit; ++unit;
} }
} }
}
inline void dirtyTexCoordPointersAboveAndIncluding( unsigned int unit ) inline void dirtyTexCoordPointersAboveAndIncluding( unsigned int unit )
{
if (_useVertexAttributeAliasing)
{
dirtyVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location);
}
else
{ {
while (unit<_texCoordArrayList.size()) while (unit<_texCoordArrayList.size())
{ {
@ -902,6 +1039,7 @@ class OSG_EXPORT State : public Referenced, public Observer
++unit; ++unit;
} }
} }
}
/** Set the current texture unit, return true if selected, /** Set the current texture unit, return true if selected,
@ -937,7 +1075,6 @@ class OSG_EXPORT State : public Referenced, public Observer
setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,array->getDataPointer()); setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,array->getDataPointer());
} }
} }
else disableVertexAttribPointer(unit);
} }
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..); /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
@ -952,6 +1089,16 @@ class OSG_EXPORT State : public Referenced, public Observer
void disableVertexAttribPointersAboveAndIncluding( unsigned int index ); 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 ) inline void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index )
{ {
while (index<_vertexAttribArrayList.size()) while (index<_vertexAttribArrayList.size())
@ -1096,6 +1243,10 @@ class OSG_EXPORT State : public Referenced, public Observer
virtual void objectDeleted(void* object); 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: protected:
virtual ~State(); virtual ~State();
@ -1113,6 +1264,7 @@ class OSG_EXPORT State : public Referenced, public Observer
ref_ptr<Uniform> _modelViewMatrixUniform; ref_ptr<Uniform> _modelViewMatrixUniform;
ref_ptr<Uniform> _projectionMatrixUniform; ref_ptr<Uniform> _projectionMatrixUniform;
ref_ptr<Uniform> _modelViewProjectionMatrixUniform; ref_ptr<Uniform> _modelViewProjectionMatrixUniform;
ref_ptr<Uniform> _normalMatrixUniform;
Matrix _initialInverseViewMatrix; Matrix _initialInverseViewMatrix;
@ -1121,6 +1273,38 @@ class OSG_EXPORT State : public Referenced, public Observer
bool* _abortRenderingPtr; bool* _abortRenderingPtr;
CheckForGLErrors _checkGLErrors; 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<VertexAttribAlias> 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 struct ModeStack
{ {
typedef std::vector<StateAttribute::GLModeValue> ValueVec; typedef std::vector<StateAttribute::GLModeValue> ValueVec;
@ -1260,10 +1444,11 @@ class OSG_EXPORT State : public Referenced, public Observer
struct EnabledArrayPair struct EnabledArrayPair
{ {
EnabledArrayPair():_dirty(true),_enabled(false),_normalized(0),_pointer(0) {} EnabledArrayPair():_lazy_disable(false),_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(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) { _dirty=eap._dirty; _enabled=eap._enabled; _normalized=eap._normalized;_pointer=eap._pointer; return *this; } 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 _dirty;
bool _enabled; bool _enabled;
GLboolean _normalized; GLboolean _normalized;
@ -1341,6 +1526,9 @@ class OSG_EXPORT State : public Referenced, public Observer
typedef void (APIENTRY * ActiveTextureProc) (GLenum texture); typedef void (APIENTRY * ActiveTextureProc) (GLenum texture);
typedef void (APIENTRY * FogCoordPointerProc) (GLenum type, GLsizei stride, const GLvoid *pointer); 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 * 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 * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int); typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int); typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int);
@ -1354,6 +1542,9 @@ class OSG_EXPORT State : public Referenced, public Observer
GLint _glMaxTextureUnits; GLint _glMaxTextureUnits;
ActiveTextureProc _glClientActiveTexture; ActiveTextureProc _glClientActiveTexture;
ActiveTextureProc _glActiveTexture; ActiveTextureProc _glActiveTexture;
MultiTexCoord4fProc _glMultiTexCoord4f;
VertexAttrib4fProc _glVertexAttrib4f;
VertexAttrib4fvProc _glVertexAttrib4fv;
FogCoordPointerProc _glFogCoordPointer; FogCoordPointerProc _glFogCoordPointer;
SecondaryColorPointerProc _glSecondaryColorPointer; SecondaryColorPointerProc _glSecondaryColorPointer;
VertexAttribPointerProc _glVertexAttribPointer; VertexAttribPointerProc _glVertexAttribPointer;
@ -1366,6 +1557,8 @@ class OSG_EXPORT State : public Referenced, public Observer
unsigned int _dynamicObjectCount; unsigned int _dynamicObjectCount;
osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback; osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
GLBeginEndAdapter _glBeginEndAdapter;
}; };
inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList) inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)

View File

@ -123,7 +123,7 @@ void GLBufferObject::compileBuffer()
entry.dataSource != bd || entry.dataSource != bd ||
entry.dataSize != bd->getTotalDataSize()) 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"<<std::endl; // osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) updating BufferEntry"<<std::endl;

View File

@ -74,6 +74,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/GL ${HEADER_PATH}/GL
${HEADER_PATH}/GL2Extensions ${HEADER_PATH}/GL2Extensions
${HEADER_PATH}/GLExtensions ${HEADER_PATH}/GLExtensions
${HEADER_PATH}/GLBeginEndAdapter
${HEADER_PATH}/GLObjects ${HEADER_PATH}/GLObjects
${HEADER_PATH}/GLU ${HEADER_PATH}/GLU
${HEADER_PATH}/GraphicsContext ${HEADER_PATH}/GraphicsContext
@ -236,6 +237,7 @@ ADD_LIBRARY(${LIB_NAME}
Geometry.cpp Geometry.cpp
GL2Extensions.cpp GL2Extensions.cpp
GLExtensions.cpp GLExtensions.cpp
GLBeginEndAdapter.cpp
GLObjects.cpp GLObjects.cpp
GraphicsContext.cpp GraphicsContext.cpp
GraphicsThread.cpp GraphicsThread.cpp

View File

@ -0,0 +1,224 @@
/* -*-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.
*/
#include <osg/GLBeginEndAdapter>
#include <osg/State>
#include <osg/Notify>
#include <osg/io_utils>
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());
}

View File

@ -1275,6 +1275,7 @@ void Geometry::releaseGLObjects(State* state) const
void Geometry::drawImplementation(RenderInfo& renderInfo) const void Geometry::drawImplementation(RenderInfo& renderInfo) const
{ {
State& state = *renderInfo.getState(); State& state = *renderInfo.getState();
bool vertexAttribAlias = state.getUseVertexAttributeAliasing();
// unsigned int contextID = state.getContextID(); // unsigned int contextID = state.getContextID();
@ -1304,11 +1305,13 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
return; return;
} }
DrawNormal drawNormal(_normalData.array.get(),_normalData.indices.get()); AttributeBinding normalBinding = _normalData.binding;
DrawColor drawColor(_colorData.array.get(),_colorData.indices.get()); AttributeBinding colorBinding = _colorData.binding;
DrawSecondaryColor drawSecondaryColor(_secondaryColorData.array.get(),_secondaryColorData.indices.get(),extensions);
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; fogCoordBinding = BIND_OFF;
} }
unsigned int normalIndex = 0; unsigned int normalIndex = 0;
unsigned int colorIndex = 0; unsigned int colorIndex = 0;
unsigned int secondaryColorIndex = 0; unsigned int secondaryColorIndex = 0;
@ -1353,13 +1357,40 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
DrawVertexAttribMap drawVertexAttribMap; DrawVertexAttribMap drawVertexAttribMap;
bool vertexVertexAttributesSupported = extensions->isVertexProgramSupported(); bool vertexVertexAttributesSupported = extensions->isVertexProgramSupported();
bool handleVertexAttributes = (!_vertexAttribList.empty() && vertexVertexAttributesSupported); bool handleVertexAttributes = (vertexAttribAlias || !_vertexAttribList.empty()) && vertexVertexAttributesSupported;
bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported();
if (vertexAttribAlias)
{
if (normalBinding!=BIND_OFF && normalBinding!=BIND_PER_VERTEX)
{
osg::notify(osg::NOTICE)<<"normal assign"<<std::endl;
drawVertexAttribMap[normalBinding].push_back( new DrawVertexAttrib(extensions,2,false,_normalData.array.get(),_normalData.indices.get()) );
normalBinding = BIND_OFF;
}
if (colorBinding!=BIND_OFF && colorBinding!=BIND_PER_VERTEX)
{
osg::notify(osg::NOTICE)<<"color assign"<<std::endl;
drawVertexAttribMap[colorBinding].push_back( new DrawVertexAttrib(extensions,3,false,_colorData.array.get(),_colorData.indices.get()) );
colorBinding = BIND_OFF;
}
secondaryColorBinding = BIND_OFF;
fogCoordBinding = BIND_OFF;
}
if (areFastPathsUsed()) if (areFastPathsUsed())
{ {
#define USE_LAZY_DISABLING
#ifdef USE_LAZY_DISABLING
state.lazyDisablingOfVertexAttributes();
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// fast path. // fast path.
@ -1368,20 +1399,55 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
{ {
// osg::notify(osg::NOTICE)<<"Geometry::drawImplementation() Using VertexBufferObjects"<<std::endl; // osg::notify(osg::NOTICE)<<"Geometry::drawImplementation() Using VertexBufferObjects"<<std::endl;
// if( _vertexData.array.valid() )
// Vertex Buffer Object path for defining vertex arrays. state.setVertexPointer(_vertexData.array.get());
// #ifndef USE_LAZY_DISABLING
state.setNormalPointer(_normalData.binding==BIND_PER_VERTEX ? _normalData.array.get() : 0); else
state.setColorPointer(_colorData.binding==BIND_PER_VERTEX ? _colorData.array.get() : 0); state.disableVertexPointer();
state.setSecondaryColorPointer(_secondaryColorData.binding==BIND_PER_VERTEX ? _secondaryColorData.array.get() : 0); #endif
state.setFogCoordPointer(_fogCoordData.binding==BIND_PER_VERTEX ? _fogCoordData.array.get() : 0);
if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid())
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.get());
#ifndef USE_LAZY_DISABLING
else
state.disableColorPointer();
#endif
if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid())
state.setSecondaryColorPointer(_secondaryColorData.array.get());
#ifndef USE_LAZY_DISABLING
else
state.disableSecondaryColorPointer();
#endif
if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid())
state.setFogCoordPointer(_fogCoordData.array.get());
#ifndef USE_LAZY_DISABLING
else
state.disableFogCoordPointer();
#endif
unsigned int unit; unsigned int unit;
for(unit=0;unit<_texCoordList.size();++unit) for(unit=0;unit<_texCoordList.size();++unit)
{ {
state.setTexCoordPointer(unit, _texCoordList[unit].array.get()); const Array* array = _texCoordList[unit].array.get();
if (array)
state.setTexCoordPointer(unit,array);
#ifndef USE_LAZY_DISABLING
else
state.disableTexCoordPointer(unit);
#endif
} }
#ifndef USE_LAZY_DISABLING
state.disableTexCoordPointersAboveAndIncluding(unit); state.disableTexCoordPointersAboveAndIncluding(unit);
#endif
if( handleVertexAttributes ) if( handleVertexAttributes )
{ {
@ -1390,9 +1456,14 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
{ {
const Array* array = _vertexAttribList[index].array.get(); const Array* array = _vertexAttribList[index].array.get();
const AttributeBinding ab = _vertexAttribList[index].binding; const AttributeBinding ab = _vertexAttribList[index].binding;
state.setVertexAttribPointer(index, (ab==BIND_PER_VERTEX ? array : 0), _vertexAttribList[index].normalize);
if(array && ab!=BIND_PER_VERTEX) if( ab == BIND_PER_VERTEX && array )
{
state.setVertexAttribPointer( index, array, _vertexAttribList[index].normalize );
}
else
{
if( array )
{ {
const IndexArray* indexArray = _vertexAttribList[index].indices.get(); const IndexArray* indexArray = _vertexAttribList[index].indices.get();
@ -1407,17 +1478,22 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) );
} }
} }
#ifndef USE_LAZY_DISABLING
state.disableVertexAttribPointer( index );
#endif
} }
}
#ifndef USE_LAZY_DISABLING
state.disableVertexAttribPointersAboveAndIncluding( index ); state.disableVertexAttribPointersAboveAndIncluding( index );
#endif
} }
#ifndef USE_LAZY_DISABLING
else if (vertexVertexAttributesSupported) else if (vertexVertexAttributesSupported)
{ {
state.disableVertexAttribPointersAboveAndIncluding( 0 ); state.disableVertexAttribPointersAboveAndIncluding( 0 );
} }
#endif
state.setVertexPointer(_vertexData.array.get());
} }
else else
{ {
@ -1428,28 +1504,38 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
// //
if( _vertexData.array.valid() ) if( _vertexData.array.valid() )
state.setVertexPointer(_vertexData.array->getDataSize(),_vertexData.array->getDataType(),0,_vertexData.array->getDataPointer()); state.setVertexPointer(_vertexData.array->getDataSize(),_vertexData.array->getDataType(),0,_vertexData.array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableVertexPointer(); state.disableVertexPointer();
#endif
if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) if (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid())
state.setNormalPointer(_normalData.array->getDataType(),0,_normalData.array->getDataPointer()); state.setNormalPointer(_normalData.array->getDataType(),0,_normalData.array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableNormalPointer(); state.disableNormalPointer();
#endif
if (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) 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->getDataSize(),_colorData.array->getDataType(),0,_colorData.array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableColorPointer(); state.disableColorPointer();
#endif
if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) if (secondaryColorBinding==BIND_PER_VERTEX && _secondaryColorData.array.valid())
state.setSecondaryColorPointer(_secondaryColorData.array->getDataSize(),_secondaryColorData.array->getDataType(),0,_secondaryColorData.array->getDataPointer()); state.setSecondaryColorPointer(_secondaryColorData.array->getDataSize(),_secondaryColorData.array->getDataType(),0,_secondaryColorData.array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableSecondaryColorPointer(); state.disableSecondaryColorPointer();
#endif
if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid()) if (fogCoordBinding==BIND_PER_VERTEX && _fogCoordData.array.valid())
state.setFogCoordPointer(GL_FLOAT,0,_fogCoordData.array->getDataPointer()); state.setFogCoordPointer(GL_FLOAT,0,_fogCoordData.array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableFogCoordPointer(); state.disableFogCoordPointer();
#endif
unsigned int unit; unsigned int unit;
for(unit=0;unit<_texCoordList.size();++unit) for(unit=0;unit<_texCoordList.size();++unit)
@ -1457,10 +1543,14 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
const Array* array = _texCoordList[unit].array.get(); const Array* array = _texCoordList[unit].array.get();
if (array) if (array)
state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer()); state.setTexCoordPointer(unit,array->getDataSize(),array->getDataType(),0,array->getDataPointer());
#ifndef USE_LAZY_DISABLING
else else
state.disableTexCoordPointer(unit); state.disableTexCoordPointer(unit);
#endif
} }
#ifndef USE_LAZY_DISABLING
state.disableTexCoordPointersAboveAndIncluding(unit); state.disableTexCoordPointersAboveAndIncluding(unit);
#endif
if( handleVertexAttributes ) if( handleVertexAttributes )
{ {
@ -1493,24 +1583,34 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
} }
} }
#ifndef USE_LAZY_DISABLING
state.disableVertexAttribPointer( index ); state.disableVertexAttribPointer( index );
#endif
} }
} }
#ifndef USE_LAZY_DISABLING
state.disableVertexAttribPointersAboveAndIncluding( index ); state.disableVertexAttribPointersAboveAndIncluding( index );
#endif
} }
#ifndef USE_LAZY_DISABLING
else if (vertexVertexAttributesSupported) else if (vertexVertexAttributesSupported)
{ {
state.disableVertexAttribPointersAboveAndIncluding( 0 ); state.disableVertexAttribPointersAboveAndIncluding( 0 );
} }
#endif
} }
#ifdef USE_LAZY_DISABLING
state.applyDisablingOfVertexAttributes();
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// pass the overall binding values onto OpenGL. // pass the overall binding values onto OpenGL.
// //
if (_normalData.binding==BIND_OVERALL) drawNormal(normalIndex++); if (normalBinding==BIND_OVERALL) drawNormal(normalIndex++);
if (_colorData.binding==BIND_OVERALL) drawColor(colorIndex++); if (colorBinding==BIND_OVERALL) drawColor(colorIndex++);
if (secondaryColorBinding==BIND_OVERALL) drawSecondaryColor(secondaryColorIndex++); if (secondaryColorBinding==BIND_OVERALL) drawSecondaryColor(secondaryColorIndex++);
if (fogCoordBinding==BIND_OVERALL) drawFogCoord(fogCoordIndex++); if (fogCoordBinding==BIND_OVERALL) drawFogCoord(fogCoordIndex++);
if (handleVertexAttributes) if (handleVertexAttributes)
@ -1532,8 +1632,8 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
++itr) ++itr)
{ {
if (_normalData.binding==BIND_PER_PRIMITIVE_SET) drawNormal(normalIndex++); if (normalBinding==BIND_PER_PRIMITIVE_SET) drawNormal(normalIndex++);
if (_colorData.binding==BIND_PER_PRIMITIVE_SET) drawColor(colorIndex++); if (colorBinding==BIND_PER_PRIMITIVE_SET) drawColor(colorIndex++);
if (secondaryColorBinding==BIND_PER_PRIMITIVE_SET) drawSecondaryColor(secondaryColorIndex++); if (secondaryColorBinding==BIND_PER_PRIMITIVE_SET) drawSecondaryColor(secondaryColorIndex++);
if (fogCoordBinding==BIND_PER_PRIMITIVE_SET) drawFogCoord(fogCoordIndex++); if (fogCoordBinding==BIND_PER_PRIMITIVE_SET) drawFogCoord(fogCoordIndex++);
if (handleVertexAttributes) if (handleVertexAttributes)

View File

@ -181,10 +181,10 @@ void Program::compileGLObjects( osg::State& state ) const
for( unsigned int i=0; i < _shaderList.size(); ++i ) 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) 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; if( ! _needsLink ) return;
_needsLink = false; _needsLink = false;
@ -485,13 +485,27 @@ void Program::PerContextProgram::linkProgram()
_lastAppliedUniformList.clear(); _lastAppliedUniformList.clear();
// set any explicit vertex attribute bindings // set any explicit vertex attribute bindings
const AttribBindingList& bindlist = _program->getAttribBindingList(); const AttribBindingList& programBindlist = _program->getAttribBindingList();
for( AttribBindingList::const_iterator itr = bindlist.begin(); for( AttribBindingList::const_iterator itr = programBindlist.begin();
itr != bindlist.end(); ++itr ) itr != programBindlist.end(); ++itr )
{ {
osg::notify(osg::NOTICE)<<"Program's vertex attrib binding "<<itr->second<<", "<<itr->first<<std::endl;
_extensions->glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() ); _extensions->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 "<<itr->second<<", "<<itr->first<<std::endl;
_extensions->glBindAttribLocation( _glProgramHandle, itr->second, itr->first.c_str() );
}
}
// set any explicit frag data bindings // set any explicit frag data bindings
const FragDataBindingList& fdbindlist = _program->getFragDataBindingList(); const FragDataBindingList& fdbindlist = _program->getFragDataBindingList();
for( FragDataBindingList::const_iterator itr = fdbindlist.begin(); for( FragDataBindingList::const_iterator itr = fdbindlist.begin();

View File

@ -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 ); PerContextShader* pcs = getPCS( state.getContextID() );
if( pcs ) pcs->compileShader(); if( pcs ) pcs->compileShader( state );
} }
@ -374,12 +374,18 @@ namespace
} }
} }
void Shader::PerContextShader::compileShader() void Shader::PerContextShader::compileShader(osg::State& state)
{ {
if( ! _needsCompile ) return; if( ! _needsCompile ) return;
_needsCompile = false; _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) if (osg::getNotifyLevel()>=osg::INFO)
{ {
@ -389,7 +395,7 @@ void Shader::PerContextShader::compileShader()
} }
GLint compiled = GL_FALSE; GLint compiled = GL_FALSE;
const char* sourceText = _shader->getShaderSource().c_str(); const char* sourceText = source.c_str();
_extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL ); _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
_extensions->glCompileShader( _glShaderHandle ); _extensions->glCompileShader( _glShaderHandle );
_extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled ); _extensions->glGetShaderiv( _glShaderHandle, GL_COMPILE_STATUS, &compiled );

View File

@ -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 // The code is mostly duplicated in order to hoist the back/front face
// test out of the loop for efficiency // test out of the loop for efficiency
glBegin(GL_QUAD_STRIP); GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
gl.Begin(GL_QUAD_STRIP);
if (drawFrontFace) { if (drawFrontFace) {
@ -103,23 +105,23 @@ void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius,
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(c,s,0.0f); gl.Normal3f(c,s,0.0f);
glTexCoord2f(texCoord,1.0f); gl.TexCoord2f(texCoord,1.0f);
glVertex3f(c*r,s*r,topz); gl.Vertex3f(c*r,s*r,topz);
glTexCoord2f(texCoord,0.0f); gl.TexCoord2f(texCoord,0.0f);
glVertex3f(c*r,s*r,basez); gl.Vertex3f(c*r,s*r,basez);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(r,0.0f,topz); gl.Vertex3f(r,0.0f,topz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(r,0.0f,basez); gl.Vertex3f(r,0.0f,basez);
} }
if (drawBackFace) { if (drawBackFace) {
@ -130,26 +132,26 @@ void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius,
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(-c,-s,0.0f); gl.Normal3f(-c,-s,0.0f);
glTexCoord2f(texCoord,0.0f); gl.TexCoord2f(texCoord,0.0f);
glVertex3f(c*r,s*r,basez); gl.Vertex3f(c*r,s*r,basez);
glTexCoord2f(texCoord,1.0f); gl.TexCoord2f(texCoord,1.0f);
glVertex3f(c*r,s*r,topz); gl.Vertex3f(c*r,s*r,topz);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(r,0.0f,basez); gl.Vertex3f(r,0.0f,basez);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(r,0.0f,topz); 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 rowbegin = top?numRows/2:0;
unsigned int rowend = top?numRows:numRows/2; unsigned int rowend = top?numRows:numRows/2;
GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
for(unsigned int rowi=rowbegin; rowi<rowend; ++rowi) for(unsigned int rowi=rowbegin; rowi<rowend; ++rowi)
{ {
@ -186,7 +190,7 @@ void DrawShapeVisitor::drawHalfSphere(unsigned int numSegments, unsigned int num
float nzTop= sinf(lTop); float nzTop= sinf(lTop);
float nRatioTop= cosf(lTop); float nRatioTop= cosf(lTop);
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
float angle = 0.0f; float angle = 0.0f;
float texCoord = 0.0f; float texCoord = 0.0f;
@ -204,28 +208,28 @@ void DrawShapeVisitor::drawHalfSphere(unsigned int numSegments, unsigned int num
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(c*nRatioTop,s*nRatioTop,nzTop); gl.Normal3f(c*nRatioTop,s*nRatioTop,nzTop);
glTexCoord2f(texCoord,vTop); gl.TexCoord2f(texCoord,vTop);
glVertex3f(c*rTop,s*rTop,zTop+zOffset); gl.Vertex3f(c*rTop,s*rTop,zTop+zOffset);
glNormal3f(c*nRatioBase,s*nRatioBase,nzBase); gl.Normal3f(c*nRatioBase,s*nRatioBase,nzBase);
glTexCoord2f(texCoord,vBase); gl.TexCoord2f(texCoord,vBase);
glVertex3f(c*rBase,s*rBase,zBase+zOffset); gl.Vertex3f(c*rBase,s*rBase,zBase+zOffset);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,vTop);
glVertex3f(rTop,0.0f,zTop+zOffset); gl.Vertex3f(rTop,0.0f,zTop+zOffset);
glNormal3f(nRatioBase,0.0f,nzBase); gl.Normal3f(nRatioBase,0.0f,nzBase);
glTexCoord2f(1.0f,vBase); gl.TexCoord2f(1.0f,vBase);
glVertex3f(rBase,0.0f,zBase+zOffset); gl.Vertex3f(rBase,0.0f,zBase+zOffset);
} }
if (drawBackFace) { if (drawBackFace) {
@ -236,32 +240,31 @@ void DrawShapeVisitor::drawHalfSphere(unsigned int numSegments, unsigned int num
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(-c*nRatioBase,-s*nRatioBase,-nzBase); gl.Normal3f(-c*nRatioBase,-s*nRatioBase,-nzBase);
glTexCoord2f(texCoord,vBase); gl.TexCoord2f(texCoord,vBase);
glVertex3f(c*rBase,s*rBase,zBase+zOffset); gl.Vertex3f(c*rBase,s*rBase,zBase+zOffset);
glNormal3f(-c*nRatioTop,-s*nRatioTop,-nzTop); gl.Normal3f(-c*nRatioTop,-s*nRatioTop,-nzTop);
glTexCoord2f(texCoord,vTop); gl.TexCoord2f(texCoord,vTop);
glVertex3f(c*rTop,s*rTop,zTop+zOffset); gl.Vertex3f(c*rTop,s*rTop,zTop+zOffset);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,vBase);
glVertex3f(rBase,0.0f,zBase+zOffset); gl.Vertex3f(rBase,0.0f,zBase+zOffset);
glNormal3f(-nRatioTop,0.0f,-nzTop); gl.Normal3f(-nRatioTop,0.0f,-nzTop);
glTexCoord2f(1.0f,vTop); gl.TexCoord2f(1.0f,vTop);
glVertex3f(rTop,0.0f,zTop+zOffset); gl.Vertex3f(rTop,0.0f,zTop+zOffset);
} }
glEnd(); gl.End();
lBase=lTop; lBase=lTop;
rBase=rTop; rBase=rTop;
@ -271,15 +274,16 @@ void DrawShapeVisitor::drawHalfSphere(unsigned int numSegments, unsigned int num
nRatioBase=nRatioTop; nRatioBase=nRatioTop;
} }
} }
void DrawShapeVisitor::apply(const Sphere& sphere) void DrawShapeVisitor::apply(const Sphere& sphere)
{ {
glPushMatrix(); GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
glTranslatef(sphere.getCenter().x(),sphere.getCenter().y(),sphere.getCenter().z()); gl.PushMatrix();
gl.Translated(sphere.getCenter().x(),sphere.getCenter().y(),sphere.getCenter().z());
bool drawFrontFace = _hints ? _hints->getCreateFrontFace() : true; bool drawFrontFace = _hints ? _hints->getCreateFrontFace() : true;
bool drawBackFace = _hints ? _hints->getCreateBackFace() : false; 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 angleDelta = osg::PI*2.0f/(float)numSegments;
float texCoordHorzDelta = 1.0f/(float)numSegments; float texCoordHorzDelta = 1.0f/(float)numSegments;
gl.Begin(GL_QUAD_STRIP);
if (drawBackFace) if (drawBackFace)
{ {
float lBase=-osg::PI*0.5f; float lBase=-osg::PI*0.5f;
@ -321,7 +327,7 @@ void DrawShapeVisitor::apply(const Sphere& sphere)
float nzTop= sinf(lTop); float nzTop= sinf(lTop);
float nRatioTop= cosf(lTop); float nRatioTop= cosf(lTop);
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
float angle = 0.0f; float angle = 0.0f;
float texCoord = 0.0f; float texCoord = 0.0f;
@ -333,32 +339,32 @@ void DrawShapeVisitor::apply(const Sphere& sphere)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(-c*nRatioBase,-s*nRatioBase,-nzBase); gl.Normal3f(-c*nRatioBase,-s*nRatioBase,-nzBase);
glTexCoord2f(texCoord,vBase); gl.TexCoord2f(texCoord,vBase);
glVertex3f(c*rBase,s*rBase,zBase); gl.Vertex3f(c*rBase,s*rBase,zBase);
glNormal3f(-c*nRatioTop,-s*nRatioTop,-nzTop); gl.Normal3f(-c*nRatioTop,-s*nRatioTop,-nzTop);
glTexCoord2f(texCoord,vTop); gl.TexCoord2f(texCoord,vTop);
glVertex3f(c*rTop,s*rTop,zTop); gl.Vertex3f(c*rTop,s*rTop,zTop);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,vBase);
glVertex3f(rBase,0.0f,zBase); gl.Vertex3f(rBase,0.0f,zBase);
glNormal3f(-nRatioTop,0.0f,-nzTop); gl.Normal3f(-nRatioTop,0.0f,-nzTop);
glTexCoord2f(1.0f,vTop); gl.TexCoord2f(1.0f,vTop);
glVertex3f(rTop,0.0f,zTop); gl.Vertex3f(rTop,0.0f,zTop);
glEnd(); gl.End();
lBase=lTop; lBase=lTop;
@ -391,7 +397,7 @@ void DrawShapeVisitor::apply(const Sphere& sphere)
float nzTop= sinf(lTop); float nzTop= sinf(lTop);
float nRatioTop= cosf(lTop); float nRatioTop= cosf(lTop);
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
float angle = 0.0f; float angle = 0.0f;
float texCoord = 0.0f; float texCoord = 0.0f;
@ -403,30 +409,30 @@ void DrawShapeVisitor::apply(const Sphere& sphere)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(c*nRatioTop,s*nRatioTop,nzTop); gl.Normal3f(c*nRatioTop,s*nRatioTop,nzTop);
glTexCoord2f(texCoord,vTop); gl.TexCoord2f(texCoord,vTop);
glVertex3f(c*rTop,s*rTop,zTop); gl.Vertex3f(c*rTop,s*rTop,zTop);
glNormal3f(c*nRatioBase,s*nRatioBase,nzBase); gl.Normal3f(c*nRatioBase,s*nRatioBase,nzBase);
glTexCoord2f(texCoord,vBase); gl.TexCoord2f(texCoord,vBase);
glVertex3f(c*rBase,s*rBase,zBase); gl.Vertex3f(c*rBase,s*rBase,zBase);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,vTop);
glVertex3f(rTop,0.0f,zTop); gl.Vertex3f(rTop,0.0f,zTop);
glNormal3f(nRatioBase,0.0f,nzBase); gl.Normal3f(nRatioBase,0.0f,nzBase);
glTexCoord2f(1.0f,vBase); gl.TexCoord2f(1.0f,vBase);
glVertex3f(rBase,0.0f,zBase); gl.Vertex3f(rBase,0.0f,zBase);
glEnd(); gl.End();
lBase=lTop; lBase=lTop;
@ -439,12 +445,13 @@ void DrawShapeVisitor::apply(const Sphere& sphere)
} }
} }
gl.PopMatrix();
glPopMatrix();
} }
void DrawShapeVisitor::apply(const Box& box) void DrawShapeVisitor::apply(const Box& box)
{ {
GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
// evaluate hints // evaluate hints
bool createBody = (_hints ? _hints->getCreateBody() : true); bool createBody = (_hints ? _hints->getCreateBody() : true);
bool createTop = (_hints ? _hints->getCreateTop() : true); bool createTop = (_hints ? _hints->getCreateTop() : true);
@ -454,130 +461,132 @@ void DrawShapeVisitor::apply(const Box& box)
float dy = box.getHalfLengths().y(); float dy = box.getHalfLengths().y();
float dz = box.getHalfLengths().z(); 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()) if (!box.zeroRotation())
{ {
Matrix rotation(box.computeRotationMatrix()); Matrixd rotation(box.computeRotationMatrix());
glMultMatrix(rotation.ptr()); gl.MultMatrixd(rotation.ptr());
} }
glBegin(GL_QUADS); gl.Begin(GL_QUADS);
if (createBody) { if (createBody) {
// -ve y plane // -ve y plane
glNormal3f(0.0f,-1.0f,0.0f); gl.Normal3f(0.0f,-1.0f,0.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(-dx,-dy,dz); gl.Vertex3f(-dx,-dy,dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(-dx,-dy,-dz); gl.Vertex3f(-dx,-dy,-dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(dx,-dy,-dz); gl.Vertex3f(dx,-dy,-dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(dx,-dy,dz); gl.Vertex3f(dx,-dy,dz);
// +ve y plane // +ve y plane
glNormal3f(0.0f,1.0f,0.0f); gl.Normal3f(0.0f,1.0f,0.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(dx,dy,dz); gl.Vertex3f(dx,dy,dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(dx,dy,-dz); gl.Vertex3f(dx,dy,-dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(-dx,dy,-dz); gl.Vertex3f(-dx,dy,-dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(-dx,dy,dz); gl.Vertex3f(-dx,dy,dz);
// +ve x plane // +ve x plane
glNormal3f(1.0f,0.0f,0.0f); gl.Normal3f(1.0f,0.0f,0.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(dx,-dy,dz); gl.Vertex3f(dx,-dy,dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(dx,-dy,-dz); gl.Vertex3f(dx,-dy,-dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(dx,dy,-dz); gl.Vertex3f(dx,dy,-dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(dx,dy,dz); gl.Vertex3f(dx,dy,dz);
// -ve x plane // -ve x plane
glNormal3f(-1.0f,0.0f,0.0f); gl.Normal3f(-1.0f,0.0f,0.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(-dx,dy,dz); gl.Vertex3f(-dx,dy,dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(-dx,dy,-dz); gl.Vertex3f(-dx,dy,-dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(-dx,-dy,-dz); gl.Vertex3f(-dx,-dy,-dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(-dx,-dy,dz); gl.Vertex3f(-dx,-dy,dz);
} }
if (createTop) { if (createTop) {
// +ve z plane // +ve z plane
glNormal3f(0.0f,0.0f,1.0f); gl.Normal3f(0.0f,0.0f,1.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(-dx,dy,dz); gl.Vertex3f(-dx,dy,dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(-dx,-dy,dz); gl.Vertex3f(-dx,-dy,dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(dx,-dy,dz); gl.Vertex3f(dx,-dy,dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(dx,dy,dz); gl.Vertex3f(dx,dy,dz);
} }
if (createBottom) { if (createBottom) {
// -ve z plane // -ve z plane
glNormal3f(0.0f,0.0f,-1.0f); gl.Normal3f(0.0f,0.0f,-1.0f);
glTexCoord2f(0.0f,1.0f); gl.TexCoord2f(0.0f,1.0f);
glVertex3f(dx,dy,-dz); gl.Vertex3f(dx,dy,-dz);
glTexCoord2f(0.0f,0.0f); gl.TexCoord2f(0.0f,0.0f);
glVertex3f(dx,-dy,-dz); gl.Vertex3f(dx,-dy,-dz);
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(-dx,-dy,-dz); gl.Vertex3f(-dx,-dy,-dz);
glTexCoord2f(1.0f,1.0f); gl.TexCoord2f(1.0f,1.0f);
glVertex3f(-dx,dy,-dz); gl.Vertex3f(-dx,dy,-dz);
} }
glEnd(); gl.End();
glPopMatrix(); gl.PopMatrix();
} }
void DrawShapeVisitor::apply(const Cone& cone) 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()) if (!cone.zeroRotation())
{ {
Matrix rotation(cone.computeRotationMatrix()); Matrixd rotation(cone.computeRotationMatrix());
glMultMatrix(rotation.ptr()); gl.MultMatrixd(rotation.ptr());
} }
// evaluate hints // evaluate hints
@ -624,7 +633,7 @@ void DrawShapeVisitor::apply(const Cone& cone)
// we can't use a fan for the cone top // we can't use a fan for the cone top
// since we need different normals at the top // since we need different normals at the top
// for each face.. // for each face..
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
angle = 0.0f; angle = 0.0f;
texCoord = 0.0f; texCoord = 0.0f;
@ -634,38 +643,38 @@ void DrawShapeVisitor::apply(const Cone& cone)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glNormal3f(c*normalRatio,s*normalRatio,normalz); gl.Normal3f(c*normalRatio,s*normalRatio,normalz);
glTexCoord2f(texCoord,topv); gl.TexCoord2f(texCoord,topv);
glVertex3f(c*topr,s*topr,topz); gl.Vertex3f(c*topr,s*topr,topz);
glTexCoord2f(texCoord,basev); gl.TexCoord2f(texCoord,basev);
glVertex3f(c*baser,s*baser,basez); gl.Vertex3f(c*baser,s*baser,basez);
} }
// do last point by hand to ensure no round off errors. // 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); gl.TexCoord2f(1.0f,topv);
glVertex3f(topr,0.0f,topz); gl.Vertex3f(topr,0.0f,topz);
glTexCoord2f(1.0f,basev); gl.TexCoord2f(1.0f,basev);
glVertex3f(baser,0.0f,basez); gl.Vertex3f(baser,0.0f,basez);
glEnd(); gl.End();
} }
} }
if (createBottom) { if (createBottom) {
glBegin(GL_TRIANGLE_FAN); gl.Begin(GL_TRIANGLE_FAN);
angle = osg::PI*2.0f; angle = osg::PI*2.0f;
texCoord = 1.0f; texCoord = 1.0f;
basez = cone.getBaseOffset(); basez = cone.getBaseOffset();
glNormal3f(0.0f,0.0f,-1.0f); gl.Normal3f(0.0f,0.0f,-1.0f);
glTexCoord2f(0.5f,0.5f); gl.TexCoord2f(0.5f,0.5f);
glVertex3f(0.0f,0.0f,basez); gl.Vertex3f(0.0f,0.0f,basez);
for(unsigned int bottomi=0;bottomi<numSegments; for(unsigned int bottomi=0;bottomi<numSegments;
++bottomi,angle-=angleDelta,texCoord-=texCoordHorzDelta) { ++bottomi,angle-=angleDelta,texCoord-=texCoordHorzDelta) {
@ -673,29 +682,31 @@ void DrawShapeVisitor::apply(const Cone& cone)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glTexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f); gl.TexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f);
glVertex3f(c*r,s*r,basez); gl.Vertex3f(c*r,s*r,basez);
} }
glTexCoord2f(1.0f,0.0f); gl.TexCoord2f(1.0f,0.0f);
glVertex3f(r,0.0f,basez); gl.Vertex3f(r,0.0f,basez);
glEnd(); gl.End();
} }
glPopMatrix(); gl.PopMatrix();
} }
void DrawShapeVisitor::apply(const Cylinder& cylinder) void DrawShapeVisitor::apply(const Cylinder& cylinder)
{ {
glPushMatrix(); GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
glTranslatef(cylinder.getCenter().x(),cylinder.getCenter().y(),cylinder.getCenter().z()); gl.PushMatrix();
gl.Translated(cylinder.getCenter().x(),cylinder.getCenter().y(),cylinder.getCenter().z());
if (!cylinder.zeroRotation()) if (!cylinder.zeroRotation())
{ {
Matrix rotation(cylinder.computeRotationMatrix()); Matrixd rotation(cylinder.computeRotationMatrix());
glMultMatrix(rotation.ptr()); gl.MultMatrixd(rotation.ptr());
} }
// evaluate hints // evaluate hints
@ -730,11 +741,11 @@ void DrawShapeVisitor::apply(const Cylinder& cylinder)
// cylinder top // cylinder top
if (createTop) { if (createTop) {
glBegin(GL_TRIANGLE_FAN); gl.Begin(GL_TRIANGLE_FAN);
glNormal3f(0.0f,0.0f,1.0f); gl.Normal3f(0.0f,0.0f,1.0f);
glTexCoord2f(0.5f,0.5f); gl.TexCoord2f(0.5f,0.5f);
glVertex3f(0.0f,0.0f,topz); gl.Vertex3f(0.0f,0.0f,topz);
angle = 0.0f; angle = 0.0f;
texCoord = 0.0f; texCoord = 0.0f;
@ -745,24 +756,24 @@ void DrawShapeVisitor::apply(const Cylinder& cylinder)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glTexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f); gl.TexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f);
glVertex3f(c*r,s*r,topz); gl.Vertex3f(c*r,s*r,topz);
} }
glTexCoord2f(1.0f,0.5f); gl.TexCoord2f(1.0f,0.5f);
glVertex3f(r,0.0f,topz); gl.Vertex3f(r,0.0f,topz);
glEnd(); gl.End();
} }
// cylinder bottom // cylinder bottom
if (createBottom) if (createBottom)
{ {
glBegin(GL_TRIANGLE_FAN); gl.Begin(GL_TRIANGLE_FAN);
glNormal3f(0.0f,0.0f,-1.0f); gl.Normal3f(0.0f,0.0f,-1.0f);
glTexCoord2f(0.5f,0.5f); gl.TexCoord2f(0.5f,0.5f);
glVertex3f(0.0f,0.0f,basez); gl.Vertex3f(0.0f,0.0f,basez);
angle = osg::PI*2.0f; angle = osg::PI*2.0f;
texCoord = 1.0f; texCoord = 1.0f;
@ -773,29 +784,31 @@ void DrawShapeVisitor::apply(const Cylinder& cylinder)
float c = cosf(angle); float c = cosf(angle);
float s = sinf(angle); float s = sinf(angle);
glTexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f); gl.TexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f);
glVertex3f(c*r,s*r,basez); gl.Vertex3f(c*r,s*r,basez);
} }
glTexCoord2f(1.0f,0.5f); gl.TexCoord2f(1.0f,0.5f);
glVertex3f(r,0.0f,basez); gl.Vertex3f(r,0.0f,basez);
glEnd(); gl.End();
} }
glPopMatrix(); gl.PopMatrix();
} }
void DrawShapeVisitor::apply(const Capsule& capsule) void DrawShapeVisitor::apply(const Capsule& capsule)
{ {
glPushMatrix(); GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
glTranslatef(capsule.getCenter().x(),capsule.getCenter().y(),capsule.getCenter().z()); gl.PushMatrix();
gl.Translated(capsule.getCenter().x(),capsule.getCenter().y(),capsule.getCenter().z());
if (!capsule.zeroRotation()) if (!capsule.zeroRotation())
{ {
Matrix rotation(capsule.computeRotationMatrix()); Matrixd rotation(capsule.computeRotationMatrix());
glMultMatrix(rotation.ptr()); gl.MultMatrixd(rotation.ptr());
} }
// evaluate hints // evaluate hints
@ -828,7 +841,7 @@ void DrawShapeVisitor::apply(const Capsule& capsule)
if (createBottom) if (createBottom)
drawHalfSphere(numSegments, numRows, capsule.getRadius(), SphereBottomHalf, -capsule.getHeight()/2.0f); drawHalfSphere(numSegments, numRows, capsule.getRadius(), SphereBottomHalf, -capsule.getHeight()/2.0f);
glPopMatrix(); gl.PopMatrix();
} }
void DrawShapeVisitor::apply(const InfinitePlane&) void DrawShapeVisitor::apply(const InfinitePlane&)
@ -838,12 +851,14 @@ void DrawShapeVisitor::apply(const InfinitePlane&)
void DrawShapeVisitor::apply(const TriangleMesh& mesh) void DrawShapeVisitor::apply(const TriangleMesh& mesh)
{ {
GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
const Vec3Array* vertices = mesh.getVertices(); const Vec3Array* vertices = mesh.getVertices();
const IndexArray* indices = mesh.getIndices(); const IndexArray* indices = mesh.getIndices();
if (vertices && indices) if (vertices && indices)
{ {
glBegin(GL_TRIANGLES); gl.Begin(GL_TRIANGLES);
for(unsigned int i=0;i+2<indices->getNumElements();i+=3) for(unsigned int i=0;i+2<indices->getNumElements();i+=3)
{ {
@ -853,14 +868,14 @@ void DrawShapeVisitor::apply(const TriangleMesh& mesh)
Vec3 normal = (v2-v1)^(v3-v2); Vec3 normal = (v2-v1)^(v3-v2);
normal.normalize(); normal.normalize();
glNormal3fv(normal.ptr()); gl.Normal3fv(normal.ptr());
glVertex3fv(v1.ptr()); gl.Vertex3fv(v1.ptr());
glVertex3fv(v2.ptr()); gl.Vertex3fv(v2.ptr());
glVertex3fv(v3.ptr()); gl.Vertex3fv(v3.ptr());
} }
glEnd(); gl.End();
} }
} }
@ -873,15 +888,17 @@ void DrawShapeVisitor::apply(const HeightField& field)
{ {
if (field.getNumColumns()==0 || field.getNumRows()==0) return; if (field.getNumColumns()==0 || field.getNumRows()==0) return;
glPushMatrix(); GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
glTranslatef(field.getOrigin().x(),field.getOrigin().y(),field.getOrigin().z()); gl.PushMatrix();
gl.Translated(field.getOrigin().x(),field.getOrigin().y(),field.getOrigin().z());
if (!field.zeroRotation()) if (!field.zeroRotation())
{ {
Matrix rotation(field.computeRotationMatrix()); Matrixd rotation(field.computeRotationMatrix());
glMultMatrix(rotation.ptr()); gl.MultMatrixd(rotation.ptr());
} }
float dx = field.getXInterval(); float dx = field.getXInterval();
@ -900,7 +917,7 @@ void DrawShapeVisitor::apply(const HeightField& field)
if (field.getSkirtHeight()!=0.0f) if (field.getSkirtHeight()!=0.0f)
{ {
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
float u = 0.0f; float u = 0.0f;
@ -913,20 +930,20 @@ void DrawShapeVisitor::apply(const HeightField& field)
vertTop.z() = field.getHeight(col,0); vertTop.z() = field.getHeight(col,0);
normTop.set(field.getNormal(col,0)); normTop.set(field.getNormal(col,0));
glTexCoord2f(u,0.0f); gl.TexCoord2f(u,0.0f);
glNormal3fv(normTop.ptr()); gl.Normal3fv(normTop.ptr());
glVertex3fv(vertTop.ptr()); gl.Vertex3fv(vertTop.ptr());
vertTop.z()-=field.getSkirtHeight(); vertTop.z()-=field.getSkirtHeight();
glVertex3fv(vertTop.ptr()); gl.Vertex3fv(vertTop.ptr());
} }
glEnd(); gl.End();
// draw top skirt // draw top skirt
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
unsigned int row = field.getNumRows()-1; unsigned int row = field.getNumRows()-1;
@ -938,17 +955,17 @@ void DrawShapeVisitor::apply(const HeightField& field)
vertTop.z() = field.getHeight(col,row); vertTop.z() = field.getHeight(col,row);
normTop.set(field.getNormal(col,row)); normTop.set(field.getNormal(col,row));
glTexCoord2f(u,1.0f); gl.TexCoord2f(u,1.0f);
glNormal3fv(normTop.ptr()); 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(); //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; float u = 0.0f;
glBegin(GL_QUAD_STRIP); gl.Begin(GL_QUAD_STRIP);
// draw skirt at beginning of this row if required. // draw skirt at beginning of this row if required.
if (field.getSkirtHeight()!=0.0f) 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()); vertBase.set(0.0f,dy*(float)row,field.getHeight(0,row)-field.getSkirtHeight());
normBase.set(field.getNormal(0,row)); normBase.set(field.getNormal(0,row));
glTexCoord2f(u,vTop); gl.TexCoord2f(u,vTop);
glNormal3fv(normTop.ptr()); gl.Normal3fv(normTop.ptr());
glVertex3fv(vertTop.ptr()); gl.Vertex3fv(vertTop.ptr());
glTexCoord2f(u,vBase); gl.TexCoord2f(u,vBase);
glNormal3fv(normBase.ptr()); gl.Normal3fv(normBase.ptr());
glVertex3fv(vertBase.ptr()); gl.Vertex3fv(vertBase.ptr());
} }
// draw the actual row // 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)); vertBase.set(dx*(float)col,dy*(float)row,field.getHeight(col,row));
normBase.set(field.getNormal(col,row)); normBase.set(field.getNormal(col,row));
glTexCoord2f(u,vTop); gl.TexCoord2f(u,vTop);
glNormal3fv(normTop.ptr()); gl.Normal3fv(normTop.ptr());
glVertex3fv(vertTop.ptr()); gl.Vertex3fv(vertTop.ptr());
glTexCoord2f(u,vBase); gl.TexCoord2f(u,vBase);
glNormal3fv(normBase.ptr()); gl.Normal3fv(normBase.ptr());
glVertex3fv(vertBase.ptr()); gl.Vertex3fv(vertBase.ptr());
} }
@ -1007,20 +1024,20 @@ void DrawShapeVisitor::apply(const HeightField& field)
vertBase.z()-=field.getSkirtHeight(); vertBase.z()-=field.getSkirtHeight();
vertTop.z()-=field.getSkirtHeight(); vertTop.z()-=field.getSkirtHeight();
glTexCoord2f(u,vTop); gl.TexCoord2f(u,vTop);
glNormal3fv(normTop.ptr()); gl.Normal3fv(normTop.ptr());
glVertex3fv(vertTop.ptr()); gl.Vertex3fv(vertTop.ptr());
glTexCoord2f(u,vBase); gl.TexCoord2f(u,vBase);
glNormal3fv(normBase.ptr()); gl.Normal3fv(normBase.ptr());
glVertex3fv(vertBase.ptr()); gl.Vertex3fv(vertBase.ptr());
} }
glEnd(); gl.End();
} }
glPopMatrix(); gl.PopMatrix();
} }
@ -1904,6 +1921,7 @@ void PrimitiveShapeVisitor::apply(const CompositeShape& group)
ShapeDrawable::ShapeDrawable(): ShapeDrawable::ShapeDrawable():
_color(1.0f,1.0f,1.0f,1.0f) _color(1.0f,1.0f,1.0f,1.0f)
{ {
//setUseDisplayList(false);
} }
ShapeDrawable::ShapeDrawable(Shape* shape,TessellationHints* hints): ShapeDrawable::ShapeDrawable(Shape* shape,TessellationHints* hints):
@ -1911,6 +1929,7 @@ ShapeDrawable::ShapeDrawable(Shape* shape,TessellationHints* hints):
_tessellationHints(hints) _tessellationHints(hints)
{ {
setShape(shape); setShape(shape);
//setUseDisplayList(false);
} }
ShapeDrawable::ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop): ShapeDrawable::ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop):
@ -1918,6 +1937,7 @@ ShapeDrawable::ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop):
_color(pg._color), _color(pg._color),
_tessellationHints(pg._tessellationHints) _tessellationHints(pg._tessellationHints)
{ {
//setUseDisplayList(false);
} }
ShapeDrawable::~ShapeDrawable() ShapeDrawable::~ShapeDrawable()
@ -1944,10 +1964,11 @@ void ShapeDrawable::setTessellationHints(TessellationHints* hints)
void ShapeDrawable::drawImplementation(RenderInfo& renderInfo) const void ShapeDrawable::drawImplementation(RenderInfo& renderInfo) const
{ {
osg::State& state = *renderInfo.getState(); osg::State& state = *renderInfo.getState();
GLBeginEndAdapter& gl = state.getGLBeginEndAdapter();
if (_shape.valid()) if (_shape.valid())
{ {
glColor4fv(_color.ptr()); gl.Color4fv(_color.ptr());
DrawShapeVisitor dsv(state,_tessellationHints.get()); DrawShapeVisitor dsv(state,_tessellationHints.get());

View File

@ -17,6 +17,8 @@
#include <osg/GLExtensions> #include <osg/GLExtensions>
#include <osg/ApplicationUsage> #include <osg/ApplicationUsage>
#include <sstream>
#ifndef GL_MAX_TEXTURE_COORDS #ifndef GL_MAX_TEXTURE_COORDS
#define GL_MAX_TEXTURE_COORDS 0x8871 #define GL_MAX_TEXTURE_COORDS 0x8871
#endif #endif
@ -35,7 +37,8 @@ using namespace osg;
static ApplicationUsageProxy State_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_GL_ERROR_CHECKING <type>","ONCE_PER_ATTRIBUTE | ON | on enables fine grained checking, ONCE_PER_FRAME enables coarse grained checking"); static ApplicationUsageProxy State_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_GL_ERROR_CHECKING <type>","ONCE_PER_ATTRIBUTE | ON | on enables fine grained checking, ONCE_PER_FRAME enables coarse grained checking");
State::State(): State::State():
Referenced(true) Referenced(true),
_glBeginEndAdapter(this)
{ {
_graphicsContext = 0; _graphicsContext = 0;
_contextID = 0; _contextID = 0;
@ -48,6 +51,27 @@ State::State():
_modelViewMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewMatrix"); _modelViewMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewMatrix");
_projectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ProjectionMatrix"); _projectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ProjectionMatrix");
_modelViewProjectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewProjectionMatrix"); _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"<<i;
osg_MultiTexCoord<<"osg_MultiTexCoord"<<i;
setUpVertexAttribAlias(_texCoordAliasList[i], 8+i, gl_MultiTexCoord.str(), osg_MultiTexCoord.str(), "attribute vec4 ");
}
}
_abortRenderingPtr = false; _abortRenderingPtr = false;
@ -95,12 +119,15 @@ State::State():
_maxTexturePoolSize = 0; _maxTexturePoolSize = 0;
_maxBufferObjectPoolSize = 0; _maxBufferObjectPoolSize = 0;
} }
State::~State() State::~State()
{ {
//_texCoordArrayList.clear();
//_vertexAttribArrayList.clear();
// osg::notify(osg::NOTICE)<<"State::~State()"<<this<<std::endl;
for(AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.begin(); for(AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.begin();
itr != _appliedProgramObjectSet.end(); itr != _appliedProgramObjectSet.end();
++itr) ++itr)
@ -748,6 +775,9 @@ void State::initializeExtensionProcs()
setGLExtensionFuncPtr(_glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT"); setGLExtensionFuncPtr(_glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT");
setGLExtensionFuncPtr(_glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB"); setGLExtensionFuncPtr(_glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB");
setGLExtensionFuncPtr(_glEnableVertexAttribArray, "glEnableVertexAttribArray","glEnableVertexAttribArrayARB"); setGLExtensionFuncPtr(_glEnableVertexAttribArray, "glEnableVertexAttribArray","glEnableVertexAttribArrayARB");
setGLExtensionFuncPtr(_glMultiTexCoord4f, "glMultiTexCoord4f","glMultiTexCoord4fARB");
setGLExtensionFuncPtr(_glVertexAttrib4f, "glVertexAttrib4f");
setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv");
setGLExtensionFuncPtr(_glDisableVertexAttribArray, "glDisableVertexAttribArray","glDisableVertexAttribArrayARB"); setGLExtensionFuncPtr(_glDisableVertexAttribArray, "glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB"); setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB");
@ -815,6 +845,12 @@ bool State::setActiveTextureUnit( unsigned int unit )
} }
void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_fogCoordAlias._location, 1, type, GL_FALSE, stride, ptr);
}
else
{ {
if (_glFogCoordPointer) if (_glFogCoordPointer)
{ {
@ -829,13 +865,20 @@ void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
_fogArray._pointer=ptr; _fogArray._pointer=ptr;
_glFogCoordPointer( type, stride, ptr ); _glFogCoordPointer( type, stride, ptr );
} }
_fogArray._lazy_disable = false;
_fogArray._dirty = false; _fogArray._dirty = false;
} }
}
} }
void State::setSecondaryColorPointer( GLint size, GLenum type, void State::setSecondaryColorPointer( GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr ) GLsizei stride, const GLvoid *ptr )
{
if (_useVertexAttributeAliasing)
{
setVertexAttribPointer(_secondaryColorAlias._location, size, type, GL_FALSE, stride, ptr);
}
else
{ {
if (_glSecondaryColorPointer) if (_glSecondaryColorPointer)
{ {
@ -849,9 +892,11 @@ void State::setSecondaryColorPointer( GLint size, GLenum type,
_secondaryColorArray._pointer=ptr; _secondaryColorArray._pointer=ptr;
_glSecondaryColorPointer( size, type, stride, ptr ); _glSecondaryColorPointer( size, type, stride, ptr );
} }
_secondaryColorArray._lazy_disable = false;
_secondaryColorArray._dirty = false; _secondaryColorArray._dirty = false;
} }
} }
}
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..); /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/ * note, only updates values that change.*/
@ -861,20 +906,25 @@ void State::setVertexAttribPointer( unsigned int index,
{ {
if (_glVertexAttribPointer) if (_glVertexAttribPointer)
{ {
// osg::notify(osg::NOTICE)<<"State::setVertexAttribPointer("<<index<<",...)"<<std::endl;
if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
EnabledArrayPair& eap = _vertexAttribArrayList[index]; EnabledArrayPair& eap = _vertexAttribArrayList[index];
if (!eap._enabled || eap._dirty) if (!eap._enabled || eap._dirty)
{ {
eap._enabled = true; eap._enabled = true;
// osg::notify(osg::NOTICE)<<" _glEnableVertexAttribArray( "<<index<<" )"<<std::endl;
_glEnableVertexAttribArray( index ); _glEnableVertexAttribArray( index );
} }
//if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty) //if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
{ {
// osg::notify(osg::NOTICE)<<" _glVertexAttribPointer( "<<index<<" )"<<std::endl;
_glVertexAttribPointer( index, size, type, normalized, stride, ptr ); _glVertexAttribPointer( index, size, type, normalized, stride, ptr );
eap._pointer = ptr; eap._pointer = ptr;
eap._normalized = normalized; eap._normalized = normalized;
} }
eap._lazy_disable = false;
eap._dirty = false; eap._dirty = false;
} }
} }
@ -892,6 +942,7 @@ void State::disableVertexAttribPointer( unsigned int index )
{ {
eap._enabled = false; eap._enabled = false;
eap._dirty = false; eap._dirty = false;
// osg::notify(osg::NOTICE)<<" _glDisableVertexAttribArray( "<<index<<" )"<<std::endl;
_glDisableVertexAttribArray( index ); _glDisableVertexAttribArray( index );
} }
} }
@ -908,6 +959,7 @@ void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
{ {
eap._enabled = false; eap._enabled = false;
eap._dirty = false; eap._dirty = false;
// osg::notify(osg::NOTICE)<<" State::disableVertexAttribPointersAboveAndIncluding(): _glDisableVertexAttribArray( "<<index<<" )"<<std::endl;
_glDisableVertexAttribArray( index ); _glDisableVertexAttribArray( index );
} }
++index; ++index;
@ -915,6 +967,57 @@ void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
} }
} }
void State::lazyDisablingOfVertexAttributes()
{
// osg::notify(osg::NOTICE)<<"lazyDisablingOfVertexAttributes()"<<std::endl;
if (!_useVertexAttributeAliasing)
{
_vertexArray._lazy_disable = true;
_normalArray._lazy_disable = true;
_colorArray._lazy_disable = true;
_secondaryColorArray._lazy_disable = true;
_indexArray._lazy_disable = true;
_fogArray._lazy_disable = true;
for(EnabledTexCoordArrayList::iterator itr = _texCoordArrayList.begin();
itr != _texCoordArrayList.end();
++itr)
{
itr->_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()"<<std::endl;
if (!_useVertexAttributeAliasing)
{
if (_vertexArray._lazy_disable) disableVertexPointer();
if (_normalArray._lazy_disable) disableNormalPointer();
if (_colorArray._lazy_disable) disableColorPointer();
if (_secondaryColorArray._lazy_disable) disableSecondaryColorPointer();
if (_indexArray._lazy_disable) disableIndexPointer();
if (_fogArray._lazy_disable) disableFogCoordPointer();
for(unsigned int i=0; i<_texCoordArrayList.size(); ++i)
{
if (_texCoordArrayList[i]._lazy_disable) disableTexCoordPointer(i);
}
}
for(unsigned int i=0; i<_vertexAttribArrayList.size(); ++i)
{
if (_vertexAttribArrayList[i]._lazy_disable) disableVertexAttribPointer(i);
}
// osg::notify(osg::NOTICE)<<"end of applyDisablingOfVertexAttributes()"<<std::endl;
}
bool State::computeSecondaryColorSupported() const bool State::computeSecondaryColorSupported() const
{ {
_isSecondaryColorSupportResolved = true; _isSecondaryColorSupportResolved = true;
@ -999,4 +1102,163 @@ void State::applyModelViewAndProjectionUniformsIfRequired()
if (_modelViewMatrixUniform.valid()) _lastAppliedProgramObject->apply(*_modelViewMatrixUniform); if (_modelViewMatrixUniform.valid()) _lastAppliedProgramObject->apply(*_modelViewMatrixUniform);
if (_projectionMatrixUniform) _lastAppliedProgramObject->apply(*_projectionMatrixUniform); if (_projectionMatrixUniform) _lastAppliedProgramObject->apply(*_projectionMatrixUniform);
if (_modelViewProjectionMatrixUniform) _lastAppliedProgramObject->apply(*_modelViewProjectionMatrixUniform); 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<str.size())
{
char c = str[endOfPhrasePos];
if ((c>='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()"<<std::endl;
osg::notify(osg::NOTICE)<<"++Before Converted source "<<std::endl<<source<<std::endl<<"++++++++"<<std::endl;
// replace ftransform as it only works with built-ins
State_Utils::replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex");
State_Utils::replaceAndInsertDeclaration(source, "gl_Normal", "osg_Normal", "attribute vec3 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_Vertex", "osg_Vertex", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_Color", "osg_Color", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_SecondaryColor", "osg_SecondaryColor", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_FogCoord", "osg_FogCoord", "attribute float ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord0", "osg_MultiTexCoord0", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord1", "osg_MultiTexCoord1", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord2", "osg_MultiTexCoord2", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord3", "osg_MultiTexCoord3", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord4", "osg_MultiTexCoord4", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord5", "osg_MultiTexCoord5", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord6", "osg_MultiTexCoord6", "attribute vec4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord7", "osg_MultiTexCoord7", "attribute vec4 ");
// replace built in uniform
State_Utils::replaceAndInsertDeclaration(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix", "uniform mat4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix", "uniform mat4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_ProjectionMatrix", "osg_ProjectionMatrix", "uniform mat4 ");
State_Utils::replaceAndInsertDeclaration(source, "gl_NormalMatrix", "osg_NormalMatrix", "uniform mat3 ");
osg::notify(osg::NOTICE)<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl;
return true;
}
void State::setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration)
{
alias = VertexAttribAlias(location, glName, osgName, declaration);
_attributeBindingList[osgName] = location;
}
void State::applyProjectionMatrix(const osg::RefMatrix* matrix)
{
if (_projection!=matrix)
{
if (matrix)
{
_projection=matrix;
}
else
{
_projection=_identity;
}
if (_useModelViewAndProjectionUniforms)
{
if (_projectionMatrixUniform.valid()) _projectionMatrixUniform->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 <osg/io_utils>
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<<std::endl;
_normalMatrixUniform->set(normalMatrix);
}
} }

View File

@ -35,8 +35,11 @@ using namespace osgUtil;
SceneGraphBuilder::SceneGraphBuilder(): SceneGraphBuilder::SceneGraphBuilder():
_statesetAssigned(false), _statesetAssigned(false),
_normalSet(false),
_normal(0.0f,0.0f,1.0f), _normal(0.0f,0.0f,1.0f),
_colorSet(false),
_color(1.0f,1.0f,1.0f,1.0f), _color(1.0f,1.0f,1.0f,1.0f),
_maxNumTexCoordComponents(0),
_texCoord(0.f,0.0f,0.0f,1.0f) _texCoord(0.f,0.0f,0.0f,1.0f)
{ {
} }