From 8551e1c5550f6d8584093913aa9ab7c193d213fc Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 15 Aug 2002 20:27:33 +0000 Subject: [PATCH] Supported added for secondary color & fog coords to osg::Geometry and osg::State. --- include/osg/Geometry | 22 +++++ include/osg/State | 54 +++++++++++- src/osg/Geometry.cpp | 198 ++++++++++++++++++++++++++++++++++++++++--- src/osg/State.cpp | 45 ++++++++++ 4 files changed, 305 insertions(+), 14 deletions(-) diff --git a/include/osg/Geometry b/include/osg/Geometry index ede7793e4..06b363a58 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -59,6 +59,22 @@ class SG_EXPORT Geometry : public Drawable const Array* getColorArray() const { return _colorArray.get(); } + void setSecondaryColorBinding(AttributeBinding ab) { _secondaryColorBinding = ab; } + AttributeBinding getSecondaryColorBinding() const { return _secondaryColorBinding; } + + void setSecondaryColorArray(Array* array) { _secondaryColorArray = array; if (!_secondaryColorArray.valid()) _secondaryColorBinding=BIND_OFF; dirtyDisplayList(); } + Array* getSecondaryColorArray() { return _secondaryColorArray.get(); } + const Array* getSecondaryColorArray() const { return _secondaryColorArray.get(); } + + + void setFogCoordBinding(AttributeBinding ab) { _fogCoordBinding = ab; } + AttributeBinding getFogCoordBinding() const { return _fogCoordBinding; } + + void setFogCoordArray(FloatArray* array) { _fogCoordArray = array; if (!_fogCoordArray.valid()) _fogCoordBinding=BIND_OFF; dirtyDisplayList(); } + FloatArray* getFogCoordArray() { return _fogCoordArray.get(); } + const FloatArray* getFogCoordArray() const { return _fogCoordArray.get(); } + + typedef std::vector< ref_ptr > TexCoordArrayList; @@ -121,6 +137,12 @@ class SG_EXPORT Geometry : public Drawable AttributeBinding _colorBinding; ref_ptr _colorArray; + AttributeBinding _secondaryColorBinding; + ref_ptr _secondaryColorArray; + + AttributeBinding _fogCoordBinding; + ref_ptr _fogCoordArray; + TexCoordArrayList _texCoordList; }; diff --git a/include/osg/State b/include/osg/State index beab1600f..43fd80cf6 100644 --- a/include/osg/State +++ b/include/osg/State @@ -24,6 +24,21 @@ namespace osg { #define GL_TEXTURE0 0x84C0 #endif +#ifndef GL_FOG_COORDINATE_ARRAY + #ifdef GL_FOG_COORDINATE_ARRAY_EXT + #define GL_FOG_COORDINATE_ARRAY GL_FOG_COORDINATE_ARRAY_EXT + #else + #define GL_FOG_COORDINATE_ARRAY 0x8457 + #endif +#endif + +#ifndef GL_SECONDARY_COLOR_ARRAY + #ifdef GL_SECONDARY_COLOR_ARRAY + #define GL_SECONDARY_COLOR_ARRAY GL_SECONDARY_COLOR_ARRAY_EXT + #else + #define GL_SECONDARY_COLOR_ARRAY 0x845E + #endif +#endif /** macro for use with osg::StateAttrbiute::apply methods for detected and * reporting OpenGL error messages.*/ @@ -287,6 +302,21 @@ class SG_EXPORT State : public Referenced } } + /** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..); + * note, only updates values that change.*/ + void setSecondaryColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ); + + /** wrapper around glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + * note, only updates values that change.*/ + inline void disableSecondaryColorPointer() + { + if (_secondaryColorArray._enabled) + { + _secondaryColorArray._enabled = false; + glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + } + } + /** wrapper around glEnableClientState(GL_INDEX_ARRAY);glIndexPointer(..); * note, only updates values that change.*/ inline void setIndexPointer( GLenum type, GLsizei stride, @@ -315,6 +345,23 @@ class SG_EXPORT State : public Referenced } } + /** wrapper around glEnableClientState(GL_FOG_COORDINATE_ARRAY);glFogCoordPointer(..); + * note, only updates values that change.*/ + void setFogCoordPointer( GLenum type, GLsizei stride, const GLvoid *ptr ); + + /** wrapper around glDisableClientState(GL_FOG_COORDINATE_ARRAY); + * note, only updates values that change.*/ + inline void disableFogCoordPointer() + { + if (_fogArray._enabled) + { + _fogArray._enabled = false; + glDisableClientState(GL_FOG_COORDINATE_ARRAY); + } + } + + + /** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..); * note, only updates values that change.*/ inline void setTexCoordPointer( unsigned int unit, @@ -383,7 +430,6 @@ class SG_EXPORT State : public Referenced bool setActiveTextureUnit( unsigned int unit ); - /** Set the current OpenGL context uniqueID. Note, it is the application developers responsibility to set up unique ID for each OpenGL context. This value is @@ -535,9 +581,11 @@ class SG_EXPORT State : public Referenced typedef std::vector EnabledTexCoordArrayList; EnabledArrayPair _vertexArray; - EnabledArrayPair _colorArray; - EnabledArrayPair _indexArray; EnabledArrayPair _normalArray; + EnabledArrayPair _colorArray; + EnabledArrayPair _secondaryColorArray; + EnabledArrayPair _indexArray; + EnabledArrayPair _fogArray; EnabledTexCoordArrayList _texCoordArrayList; unsigned int _currentActiveTextureUnit; diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 0919a9d1b..28405f950 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -7,6 +7,8 @@ Geometry::Geometry() { _normalBinding = BIND_OFF; _colorBinding = BIND_OFF; + _secondaryColorBinding = BIND_OFF; + _fogCoordBinding = BIND_OFF; } Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): @@ -15,7 +17,11 @@ Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): _normalBinding(geometry._normalBinding), _normalArray(dynamic_cast(copyop(geometry._normalArray.get()))), _colorBinding(geometry._colorBinding), - _colorArray(copyop(geometry._colorArray.get())) + _colorArray(copyop(geometry._colorArray.get())), + _secondaryColorBinding(geometry._secondaryColorBinding), + _secondaryColorArray(copyop(geometry._secondaryColorArray.get())), + _fogCoordBinding(geometry._fogCoordBinding), + _fogCoordArray(dynamic_cast(copyop(geometry._fogCoordArray.get()))) { for(PrimitiveList::const_iterator pitr=geometry._primitives.begin(); pitr!=geometry._primitives.end(); @@ -60,14 +66,25 @@ const Array* Geometry::getTexCoordArray(unsigned int unit) const else return 0; } +typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord); +typedef void (APIENTRY * SecondaryColor3ubvProc) (const GLubyte* coord); +typedef void (APIENTRY * SecondaryColor3fvProc) (const GLfloat* coord); + void Geometry::drawImmediateMode(State& state) { if (!_vertexArray.valid()) return; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // // set up the vertex arrays. + // state.setVertexPointer(3,GL_FLOAT,0,_vertexArray->getDataPointer()); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // // set up texture coordinates. + // unsigned int i; for(i=0;i<_texCoordList.size();++i) { @@ -80,32 +97,46 @@ void Geometry::drawImmediateMode(State& state) state.disableTexCoordPointersAboveAndIncluding(i); - // set up normals. + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // +; // set up normals if required. + // Vec3* normalPointer = 0; if (_normalArray.valid() && !_normalArray->empty()) normalPointer = &(_normalArray->front()); - switch (_normalBinding) + AttributeBinding normalBinding = _normalBinding; + if (normalBinding!=BIND_OFF && !normalPointer) + { + // switch off if not supported or have a valid data. + normalBinding = BIND_OFF; + } + + switch (normalBinding) { case(BIND_OFF): state.disableNormalPointer(); break; case(BIND_OVERALL): state.disableNormalPointer(); - if (normalPointer) glNormal3fv(reinterpret_cast(normalPointer)); + glNormal3fv(reinterpret_cast(normalPointer)); break; case(BIND_PER_PRIMITIVE): state.disableNormalPointer(); break; case(BIND_PER_VERTEX): - if (normalPointer) state.setNormalPointer(GL_FLOAT,0,normalPointer); - else state.disableNormalPointer(); + state.setNormalPointer(GL_FLOAT,0,normalPointer); break; } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Set up color if required. + // // set up colors, complicated by the fact that the color array // might be bound in 4 different ways, and be represented as 3 different data types - // Vec3, Vec4 or UByte4 Arrays. + // const unsigned char* colorPointer = 0; unsigned int colorStride = 0; Array::Type colorType = Array::ArrayType; @@ -136,8 +167,16 @@ void Geometry::drawImmediateMode(State& state) break; } } + + + AttributeBinding colorBinding = _colorBinding; + if (colorBinding!=BIND_OFF && !colorPointer) + { + // switch off if not supported or have a valid data. + colorBinding = BIND_OFF; + } - switch (_colorBinding) + switch (colorBinding) { case(BIND_OFF): state.disableColorPointer(); @@ -166,22 +205,138 @@ void Geometry::drawImmediateMode(State& state) state.disableColorPointer(); break; case(BIND_PER_VERTEX): - if (colorPointer) state.setColorPointer(_colorArray->getDataSize(),_colorArray->getDataType(),0,colorPointer); - else state.disableColorPointer(); + state.setColorPointer(_colorArray->getDataSize(),_colorArray->getDataType(),0,colorPointer); } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Set up secondary color if required. + // + // set up colors, complicated by the fact that the color array + // might be bound in 4 different ways, and be represented as 3 different data types - + // Vec3, Vec4 or UByte4 Arrays. + const unsigned char* secondaryColorPointer = 0; + unsigned int secondaryColorStride = 0; + Array::Type secondaryColorType = Array::ArrayType; + if (_secondaryColorArray.valid()) + { + secondaryColorType = _secondaryColorArray->getType(); + switch(secondaryColorType) + { + case(Array::UByte4ArrayType): + { + secondaryColorPointer = reinterpret_cast(_secondaryColorArray->getDataPointer()); + secondaryColorStride = 4; + break; + } + case(Array::Vec3ArrayType): + { + secondaryColorPointer = reinterpret_cast(_secondaryColorArray->getDataPointer()); + secondaryColorStride = 12; + break; + } + default: + break; + } + } + + + AttributeBinding secondaryColorBinding = _secondaryColorBinding; + if (secondaryColorBinding!=BIND_OFF && !secondaryColorPointer) + { + // switch off if not supported or have a valid data. + secondaryColorBinding = BIND_OFF; + } + + static SecondaryColor3ubvProc s_glSecondaryColor3ubv = + (SecondaryColor3ubvProc) osg::getGLExtensionFuncPtr("glSecondaryColor3ubv","glSecondaryColor3ubvEXT"); + static SecondaryColor3fvProc s_glSecondaryColor3fv = + (SecondaryColor3fvProc) osg::getGLExtensionFuncPtr("glSecondaryColor3fv","glSecondaryColor3fvEXT"); + + switch (secondaryColorBinding) + { + case(BIND_OFF): + state.disableSecondaryColorPointer(); + break; + case(BIND_OVERALL): + state.disableSecondaryColorPointer(); + if (secondaryColorPointer) + { + switch(secondaryColorType) + { + case(Array::UByte4ArrayType): + s_glSecondaryColor3ubv(reinterpret_cast(secondaryColorPointer)); + break; + case(Array::Vec3ArrayType): + s_glSecondaryColor3fv(reinterpret_cast(secondaryColorPointer)); + break; + default: + break; + } + } + break; + case(BIND_PER_PRIMITIVE): + state.disableSecondaryColorPointer(); + break; + case(BIND_PER_VERTEX): + state.setSecondaryColorPointer(_secondaryColorArray->getDataSize(),_secondaryColorArray->getDataType(),0,secondaryColorPointer); + } + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Set up fog coord if required. + // + + GLfloat* fogCoordPointer = 0; + if (_fogCoordArray.valid() && !_fogCoordArray->empty()) fogCoordPointer = &(_fogCoordArray->front()); + + static FogCoordProc s_glFogCoordfv = + (FogCoordProc) osg::getGLExtensionFuncPtr("glFogCoordfv","glFogCoordfvEXT"); + + + AttributeBinding fogCoordBinding = _fogCoordBinding; + if (fogCoordBinding!=BIND_OFF && (!s_glFogCoordfv || !fogCoordPointer)) + { + // swithc off if not supported or have a valid data. + fogCoordBinding = BIND_OFF; + } + + switch (fogCoordBinding) + { + case(BIND_OFF): + state.disableFogCoordPointer(); + break; + case(BIND_OVERALL): + state.disableFogCoordPointer(); + s_glFogCoordfv(fogCoordPointer); + break; + case(BIND_PER_PRIMITIVE): + state.disableFogCoordPointer(); + break; + case(BIND_PER_VERTEX): + state.setFogCoordPointer(GL_FLOAT,0,fogCoordPointer); + break; + } + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // // draw the primitives themselves. + // + for(PrimitiveList::iterator itr=_primitives.begin(); itr!=_primitives.end(); ++itr) { - if (_normalBinding==BIND_PER_PRIMITIVE) + if (normalBinding==BIND_PER_PRIMITIVE) { glNormal3fv((const GLfloat *)normalPointer++); } - if (_colorBinding==BIND_PER_PRIMITIVE) + if (colorBinding==BIND_PER_PRIMITIVE) { switch(colorType) { @@ -200,6 +355,27 @@ void Geometry::drawImmediateMode(State& state) colorPointer += colorStride; } + if (secondaryColorBinding==BIND_PER_PRIMITIVE) + { + switch(secondaryColorType) + { + case(Array::UByte4ArrayType): + s_glSecondaryColor3ubv(reinterpret_cast(colorPointer)); + break; + case(Array::Vec3ArrayType): + s_glSecondaryColor3fv(reinterpret_cast(colorPointer)); + break; + default: + break; + } + colorPointer += colorStride; + } + + if (fogCoordBinding==BIND_PER_PRIMITIVE) + { + s_glFogCoordfv(fogCoordPointer++); + } + (*itr)->draw(); } diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 7da8cde31..38291c1d5 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -440,3 +440,48 @@ bool State::setActiveTextureUnit( unsigned int unit ) } return true; } + +typedef void (APIENTRY * FogCoordPointerProc) (GLenum type, GLsizei stride, const GLvoid *pointer); +void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + static FogCoordPointerProc s_glFogCoordPointer = + (FogCoordPointerProc) osg::getGLExtensionFuncPtr("glFogCoordPointer","glFogCoordPointerEXT"); + + if (s_glFogCoordPointer) + { + + if (!_fogArray._enabled) + { + _fogArray._enabled = true; + glEnableClientState(GL_FOG_COORDINATE_ARRAY); + } + if (_fogArray._pointer!=ptr) + { + _fogArray._pointer=ptr; + s_glFogCoordPointer( type, stride, ptr ); + } + } + +} + +typedef void (APIENTRY * SecondaryColorPointerProc) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void State::setSecondaryColorPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ) +{ + static SecondaryColorPointerProc s_glSecondaryColorPointer = + (SecondaryColorPointerProc) osg::getGLExtensionFuncPtr("glFogCoordPointer","glFogCoordPointerEXT"); + + if (s_glSecondaryColorPointer) + { + if (!_secondaryColorArray._enabled) + { + _secondaryColorArray._enabled = true; + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + } + if (_secondaryColorArray._pointer!=ptr) + { + _secondaryColorArray._pointer=ptr; + s_glSecondaryColorPointer( size, type, stride, ptr ); + } + } +}