diff --git a/include/osg/TexGen b/include/osg/TexGen index 3d265fe5b..09f4073ab 100644 --- a/include/osg/TexGen +++ b/include/osg/TexGen @@ -14,8 +14,9 @@ #ifndef OSG_TEXGEN #define OSG_TEXGEN 1 -#include -#include +#include +#include +#include #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE) #define GL_OBJECT_LINEAR 0x2401 @@ -39,25 +40,17 @@ namespace osg { /** TexGen encapsulates the OpenGL glTexGen (texture coordinate generation) * state.*/ -class OSG_EXPORT TexGen : public StateAttribute +class OSG_EXPORT TexGen : public TextureAttribute { public : TexGen(); /** Copy constructor using CopyOp to manage deep vs shallow copy. */ - TexGen(const TexGen& texgen,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - StateAttribute(texgen,copyop), - _mode(texgen._mode), - _plane_s(texgen._plane_s), - _plane_t(texgen._plane_t), - _plane_r(texgen._plane_r), - _plane_q(texgen._plane_q) {} + TexGen(const TexGen& texgen,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_StateAttribute(osg, TexGen, TEXGEN); - virtual bool isTextureAttribute() const { return true; } - /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ virtual int compare(const StateAttribute& sa) const { @@ -105,7 +98,7 @@ class OSG_EXPORT TexGen : public StateAttribute REFLECTION_MAP = GL_REFLECTION_MAP }; - inline void setMode( Mode mode ) { _mode = mode; } + void setMode( Mode mode ); Mode getMode() const { return _mode; } @@ -129,12 +122,18 @@ class OSG_EXPORT TexGen : public StateAttribute virtual ~TexGen( void ); + std::string getUniformName(const char* baseName, unsigned int unit); + + void configureUniformNames(); + Mode _mode; - /** Additional texgen coefficients for GL_OBJECT_PLANE or - * GL_EYE_PLANE, */ - Plane _plane_s, _plane_t, _plane_r, _plane_q; + ref_ptr _plane_s; + ref_ptr _plane_t; + ref_ptr _plane_r; + ref_ptr _plane_q; + StateSet::DefineList _defineList; }; } diff --git a/src/osg/TexGen.cpp b/src/osg/TexGen.cpp index ec0bb0197..a90f12737 100644 --- a/src/osg/TexGen.cpp +++ b/src/osg/TexGen.cpp @@ -11,6 +11,7 @@ * OpenSceneGraph Public License for more details. */ #include +#include #include #include @@ -19,10 +20,25 @@ using namespace osg; TexGen::TexGen() { _mode = OBJECT_LINEAR; - _plane_s.set(1.0f, 0.0f, 0.0f, 0.0f); - _plane_t.set(0.0f, 1.0f, 0.0f, 0.0f); - _plane_r.set(0.0f, 0.0f, 1.0f, 0.0f); - _plane_q.set(0.0f, 0.0f, 0.0f, 1.0f); + _plane_s = new osg::PlaneUniform(osg::Plane(1.0f, 0.0f, 0.0f, 0.0f)); + _plane_t = new osg::PlaneUniform(osg::Plane(0.0f, 1.0f, 0.0f, 0.0f)); + _plane_r = new osg::PlaneUniform(osg::Plane(0.0f, 0.0f, 1.0f, 0.0f)); + _plane_q = new osg::PlaneUniform(osg::Plane(0.0f, 0.0f, 0.0f, 1.0f)); + + configureUniformNames(); +} + +/** Copy constructor using CopyOp to manage deep vs shallow copy. */ +TexGen::TexGen(const TexGen& texgen,const CopyOp& copyop): + TextureAttribute(texgen,copyop), + _mode(texgen._mode) +{ + _plane_s = new osg::PlaneUniform(texgen._plane_s->getValue()); + _plane_t = new osg::PlaneUniform(texgen._plane_t->getValue()); + _plane_r = new osg::PlaneUniform(texgen._plane_r->getValue()); + _plane_q = new osg::PlaneUniform(texgen._plane_q->getValue()); + + configureUniformNames(); } @@ -30,15 +46,69 @@ TexGen::~TexGen() { } +void TexGen::setMode( Mode mode ) +{ + if (_mode!=mode) + { + _mode = mode; + configureUniformNames(); + } +} + + +void TexGen::configureUniformNames() +{ + OSG_NOTICE<<__PRETTY_FUNCTION__<<" _textureUnit="<<_textureUnit<setName("osg_ObjectPlaneS", _textureUnit); + _plane_t->setName("osg_ObjectPlaneT", _textureUnit); + _plane_r->setName("osg_ObjectPlaneR", _textureUnit); + _plane_q->setName("osg_ObjectPlaneQ", _textureUnit); + + _defineList[TEXTURE_GEN_FUNCTION] = StateSet::DefinePair(str.clear()<<"(texcoord, unit, s, t, r, q) texgen_OBJECT_LINEAR(texcoord, unit, s, t, r, q)", osg::StateAttribute::ON); + break; + + case(EYE_LINEAR): + _plane_s->setName("osg_EyePlaneS", _textureUnit); + _plane_t->setName("osg_EyePlaneT", _textureUnit); + _plane_r->setName("osg_EyePlaneR", _textureUnit); + _plane_q->setName("osg_EyePlaneQ", _textureUnit); + _defineList[TEXTURE_GEN_FUNCTION] = StateSet::DefinePair(str.clear()<<"(texcoord, unit, s, t, r, q) texgen_EYE_LINEAR(texcoord, unit, s, t, r, q)", osg::StateAttribute::ON); + break; + + case(NORMAL_MAP): + _defineList[TEXTURE_GEN_FUNCTION] = StateSet::DefinePair(str.clear()<<"(texcoord, unit, s, t, r, q) texgen_NORMAL_MAP(texcoord, unit, s, t, r, q)", osg::StateAttribute::ON); + break; + + case(REFLECTION_MAP): + _defineList[TEXTURE_GEN_FUNCTION] = StateSet::DefinePair(str.clear()<<"(texcoord, unit, s, t, r, q) texgen_REFLECTION_MAP(texcoord, unit, s, t, r, q)", osg::StateAttribute::ON); + break; + + case(SPHERE_MAP): + _defineList[TEXTURE_GEN_FUNCTION] = StateSet::DefinePair(str.clear()<<"(texcoord, unit, s, t, r, q) texgen_SPHERE_MAP(texcoord, unit, s, t, r, q)", osg::StateAttribute::ON); + break; + + default: + break; + } +} void TexGen::setPlane(Coord which, const Plane& plane) { switch( which ) { - case S : _plane_s = plane; break; - case T : _plane_t = plane; break; - case R : _plane_r = plane; break; - case Q : _plane_q = plane; break; + case S : _plane_s->setValue(plane); break; + case T : _plane_t->setValue(plane); break; + case R : _plane_r->setValue(plane); break; + case Q : _plane_q->setValue(plane); break; default : OSG_WARN<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<getValue(); + case T : return _plane_t->getValue(); + case R : return _plane_r->getValue(); + case Q : return _plane_q->getValue(); + default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<getValue(); } } @@ -59,73 +129,99 @@ Plane& TexGen::getPlane(Coord which) { switch( which ) { - case S : return _plane_s; - case T : return _plane_t; - case R : return _plane_r; - case Q : return _plane_q; - default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<getValue(); + case T : return _plane_t->getValue(); + case R : return _plane_r->getValue(); + case Q : return _plane_q->getValue(); + default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<getValue(); } } void TexGen::setPlanesFromMatrix(const Matrixd& matrix) { - _plane_s.set(matrix(0,0),matrix(1,0),matrix(2,0),matrix(3,0)); - _plane_t.set(matrix(0,1),matrix(1,1),matrix(2,1),matrix(3,1)); - _plane_r.set(matrix(0,2),matrix(1,2),matrix(2,2),matrix(3,2)); - _plane_q.set(matrix(0,3),matrix(1,3),matrix(2,3),matrix(3,3)); + _plane_s->setValue(Plane(matrix(0,0),matrix(1,0),matrix(2,0),matrix(3,0))); + _plane_t->setValue(Plane(matrix(0,1),matrix(1,1),matrix(2,1),matrix(3,1))); + _plane_r->setValue(Plane(matrix(0,2),matrix(1,2),matrix(2,2),matrix(3,2))); + _plane_q->setValue(Plane(matrix(0,3),matrix(1,3),matrix(2,3),matrix(3,3))); } -void TexGen::apply(State&) const + +void TexGen::apply(State& state) const { #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE) - if (_mode == OBJECT_LINEAR || _mode == EYE_LINEAR) + if (state.getUseStateAttributeFixedFunction()) { - GLenum glmode = _mode == OBJECT_LINEAR ? GL_OBJECT_PLANE : GL_EYE_PLANE; - - if (sizeof(_plane_s[0])==sizeof(GLfloat)) + if (_mode == OBJECT_LINEAR || _mode == EYE_LINEAR) { - glTexGenfv(GL_S, glmode, (const GLfloat*)_plane_s.ptr()); - glTexGenfv(GL_T, glmode, (const GLfloat*)_plane_t.ptr()); - glTexGenfv(GL_R, glmode, (const GLfloat*)_plane_r.ptr()); - glTexGenfv(GL_Q, glmode, (const GLfloat*)_plane_q.ptr()); + GLenum glmode = _mode == OBJECT_LINEAR ? GL_OBJECT_PLANE : GL_EYE_PLANE; + + if (sizeof(_plane_s[0])==sizeof(GLfloat)) + { + glTexGenfv(GL_S, glmode, (const GLfloat*)_plane_s->getValue().ptr()); + glTexGenfv(GL_T, glmode, (const GLfloat*)_plane_t->getValue().ptr()); + glTexGenfv(GL_R, glmode, (const GLfloat*)_plane_r->getValue().ptr()); + glTexGenfv(GL_Q, glmode, (const GLfloat*)_plane_q->getValue().ptr()); + } + else + { + glTexGendv(GL_S, glmode, (const GLdouble*)_plane_s->getValue().ptr()); + glTexGendv(GL_T, glmode, (const GLdouble*)_plane_t->getValue().ptr()); + glTexGendv(GL_R, glmode, (const GLdouble*)_plane_r->getValue().ptr()); + glTexGendv(GL_Q, glmode, (const GLdouble*)_plane_q->getValue().ptr()); + } + + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); + } - else + else if (_mode == NORMAL_MAP) { - glTexGendv(GL_S, glmode, (const GLdouble*)_plane_s.ptr()); - glTexGendv(GL_T, glmode, (const GLdouble*)_plane_t.ptr()); - glTexGendv(GL_R, glmode, (const GLdouble*)_plane_r.ptr()); - glTexGendv(GL_Q, glmode, (const GLdouble*)_plane_q.ptr()); + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); + // glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); } + else if (_mode == REFLECTION_MAP) + { + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); + // glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); + } + else // SPHERE_MAP + { + // Also don't set the mode of GL_R & GL_Q as these will generate + // GL_INVALID_ENUM (See OpenGL Reference Guide, glTexGEn.) - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); + } + } - } - else if (_mode == NORMAL_MAP) - { - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); -// glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); - } - else if (_mode == REFLECTION_MAP) - { - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode ); -// glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode ); - } - else // SPHERE_MAP - { - // Also don't set the mode of GL_R & GL_Q as these will generate - // GL_INVALID_ENUM (See OpenGL Reference Guide, glTexGEn.) - - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode ); - } -#else - OSG_NOTICE<<"Warning: TexGen::apply(State&) - not supported."<