Added shader pipeline support to osg::TexGen.
This commit is contained in:
parent
2fc28a7f64
commit
59a28859ec
@ -14,8 +14,9 @@
|
|||||||
#ifndef OSG_TEXGEN
|
#ifndef OSG_TEXGEN
|
||||||
#define OSG_TEXGEN 1
|
#define OSG_TEXGEN 1
|
||||||
|
|
||||||
#include <osg/Plane>
|
#include <osg/TextureAttribute>
|
||||||
#include <osg/StateAttribute>
|
#include <osg/Uniform>
|
||||||
|
#include <osg/State>
|
||||||
|
|
||||||
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
|
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
|
||||||
#define GL_OBJECT_LINEAR 0x2401
|
#define GL_OBJECT_LINEAR 0x2401
|
||||||
@ -39,25 +40,17 @@ namespace osg {
|
|||||||
|
|
||||||
/** TexGen encapsulates the OpenGL glTexGen (texture coordinate generation)
|
/** TexGen encapsulates the OpenGL glTexGen (texture coordinate generation)
|
||||||
* state.*/
|
* state.*/
|
||||||
class OSG_EXPORT TexGen : public StateAttribute
|
class OSG_EXPORT TexGen : public TextureAttribute
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
TexGen();
|
TexGen();
|
||||||
|
|
||||||
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
||||||
TexGen(const TexGen& texgen,const CopyOp& copyop=CopyOp::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) {}
|
|
||||||
|
|
||||||
META_StateAttribute(osg, TexGen, TEXGEN);
|
META_StateAttribute(osg, TexGen, TEXGEN);
|
||||||
|
|
||||||
virtual bool isTextureAttribute() const { return true; }
|
|
||||||
|
|
||||||
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
|
||||||
virtual int compare(const StateAttribute& sa) const
|
virtual int compare(const StateAttribute& sa) const
|
||||||
{
|
{
|
||||||
@ -105,7 +98,7 @@ class OSG_EXPORT TexGen : public StateAttribute
|
|||||||
REFLECTION_MAP = GL_REFLECTION_MAP
|
REFLECTION_MAP = GL_REFLECTION_MAP
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void setMode( Mode mode ) { _mode = mode; }
|
void setMode( Mode mode );
|
||||||
|
|
||||||
Mode getMode() const { return _mode; }
|
Mode getMode() const { return _mode; }
|
||||||
|
|
||||||
@ -129,12 +122,18 @@ class OSG_EXPORT TexGen : public StateAttribute
|
|||||||
|
|
||||||
virtual ~TexGen( void );
|
virtual ~TexGen( void );
|
||||||
|
|
||||||
|
std::string getUniformName(const char* baseName, unsigned int unit);
|
||||||
|
|
||||||
|
void configureUniformNames();
|
||||||
|
|
||||||
Mode _mode;
|
Mode _mode;
|
||||||
|
|
||||||
/** Additional texgen coefficients for GL_OBJECT_PLANE or
|
ref_ptr<PlaneUniform> _plane_s;
|
||||||
* GL_EYE_PLANE, */
|
ref_ptr<PlaneUniform> _plane_t;
|
||||||
Plane _plane_s, _plane_t, _plane_r, _plane_q;
|
ref_ptr<PlaneUniform> _plane_r;
|
||||||
|
ref_ptr<PlaneUniform> _plane_q;
|
||||||
|
|
||||||
|
StateSet::DefineList _defineList;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* OpenSceneGraph Public License for more details.
|
* OpenSceneGraph Public License for more details.
|
||||||
*/
|
*/
|
||||||
#include <osg/TexGen>
|
#include <osg/TexGen>
|
||||||
|
#include <osg/State>
|
||||||
#include <osg/Notify>
|
#include <osg/Notify>
|
||||||
#include <osg/io_utils>
|
#include <osg/io_utils>
|
||||||
|
|
||||||
@ -19,10 +20,25 @@ using namespace osg;
|
|||||||
TexGen::TexGen()
|
TexGen::TexGen()
|
||||||
{
|
{
|
||||||
_mode = OBJECT_LINEAR;
|
_mode = OBJECT_LINEAR;
|
||||||
_plane_s.set(1.0f, 0.0f, 0.0f, 0.0f);
|
_plane_s = new osg::PlaneUniform(osg::Plane(1.0f, 0.0f, 0.0f, 0.0f));
|
||||||
_plane_t.set(0.0f, 1.0f, 0.0f, 0.0f);
|
_plane_t = new osg::PlaneUniform(osg::Plane(0.0f, 1.0f, 0.0f, 0.0f));
|
||||||
_plane_r.set(0.0f, 0.0f, 1.0f, 0.0f);
|
_plane_r = new osg::PlaneUniform(osg::Plane(0.0f, 0.0f, 1.0f, 0.0f));
|
||||||
_plane_q.set(0.0f, 0.0f, 0.0f, 1.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<<std::endl;
|
||||||
|
|
||||||
|
MakeString str;
|
||||||
|
std::string TEXTURE_GEN_FUNCTION = str<<"TEXTURE_GEN_FUNCTION"<<_textureUnit;
|
||||||
|
|
||||||
|
_defineList.clear();
|
||||||
|
|
||||||
|
switch(_mode)
|
||||||
|
{
|
||||||
|
case(OBJECT_LINEAR):
|
||||||
|
_plane_s->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)
|
void TexGen::setPlane(Coord which, const Plane& plane)
|
||||||
{
|
{
|
||||||
switch( which )
|
switch( which )
|
||||||
{
|
{
|
||||||
case S : _plane_s = plane; break;
|
case S : _plane_s->setValue(plane); break;
|
||||||
case T : _plane_t = plane; break;
|
case T : _plane_t->setValue(plane); break;
|
||||||
case R : _plane_r = plane; break;
|
case R : _plane_r->setValue(plane); break;
|
||||||
case Q : _plane_q = plane; break;
|
case Q : _plane_q->setValue(plane); break;
|
||||||
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<std::endl; break;
|
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<std::endl; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,11 +117,11 @@ const Plane& TexGen::getPlane(Coord which) const
|
|||||||
{
|
{
|
||||||
switch( which )
|
switch( which )
|
||||||
{
|
{
|
||||||
case S : return _plane_s;
|
case S : return _plane_s->getValue();
|
||||||
case T : return _plane_t;
|
case T : return _plane_t->getValue();
|
||||||
case R : return _plane_r;
|
case R : return _plane_r->getValue();
|
||||||
case Q : return _plane_q;
|
case Q : return _plane_q->getValue();
|
||||||
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
|
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r->getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,73 +129,99 @@ Plane& TexGen::getPlane(Coord which)
|
|||||||
{
|
{
|
||||||
switch( which )
|
switch( which )
|
||||||
{
|
{
|
||||||
case S : return _plane_s;
|
case S : return _plane_s->getValue();
|
||||||
case T : return _plane_t;
|
case T : return _plane_t->getValue();
|
||||||
case R : return _plane_r;
|
case R : return _plane_r->getValue();
|
||||||
case Q : return _plane_q;
|
case Q : return _plane_q->getValue();
|
||||||
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
|
default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r->getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexGen::setPlanesFromMatrix(const Matrixd& matrix)
|
void TexGen::setPlanesFromMatrix(const Matrixd& matrix)
|
||||||
{
|
{
|
||||||
_plane_s.set(matrix(0,0),matrix(1,0),matrix(2,0),matrix(3,0));
|
_plane_s->setValue(Plane(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_t->setValue(Plane(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_r->setValue(Plane(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_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 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 (_mode == OBJECT_LINEAR || _mode == EYE_LINEAR)
|
||||||
|
|
||||||
if (sizeof(_plane_s[0])==sizeof(GLfloat))
|
|
||||||
{
|
{
|
||||||
glTexGenfv(GL_S, glmode, (const GLfloat*)_plane_s.ptr());
|
GLenum glmode = _mode == OBJECT_LINEAR ? GL_OBJECT_PLANE : GL_EYE_PLANE;
|
||||||
glTexGenfv(GL_T, glmode, (const GLfloat*)_plane_t.ptr());
|
|
||||||
glTexGenfv(GL_R, glmode, (const GLfloat*)_plane_r.ptr());
|
if (sizeof(_plane_s[0])==sizeof(GLfloat))
|
||||||
glTexGenfv(GL_Q, glmode, (const GLfloat*)_plane_q.ptr());
|
{
|
||||||
|
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());
|
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||||
glTexGendv(GL_T, glmode, (const GLdouble*)_plane_t.ptr());
|
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||||
glTexGendv(GL_R, glmode, (const GLdouble*)_plane_r.ptr());
|
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
|
||||||
glTexGendv(GL_Q, glmode, (const GLdouble*)_plane_q.ptr());
|
// 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_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||||
glTexGeni( GL_T, 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 );
|
}
|
||||||
|
|
||||||
}
|
if (state.getUseStateAttributeShaders())
|
||||||
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."<<std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
state.applyShaderCompositionDefines(_defineList);
|
||||||
|
|
||||||
|
switch(_mode)
|
||||||
|
{
|
||||||
|
case(OBJECT_LINEAR):
|
||||||
|
state.applyShaderCompositionUniform(_plane_s.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_t.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_r.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_q.get());
|
||||||
|
break;
|
||||||
|
case(EYE_LINEAR):
|
||||||
|
state.applyShaderCompositionUniform(_plane_s.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_t.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_r.get());
|
||||||
|
state.applyShaderCompositionUniform(_plane_q.get());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user