Added shader pipeline support to osg::TexGen.
This commit is contained in:
parent
2fc28a7f64
commit
59a28859ec
@ -14,8 +14,9 @@
|
||||
#ifndef OSG_TEXGEN
|
||||
#define OSG_TEXGEN 1
|
||||
|
||||
#include <osg/Plane>
|
||||
#include <osg/StateAttribute>
|
||||
#include <osg/TextureAttribute>
|
||||
#include <osg/Uniform>
|
||||
#include <osg/State>
|
||||
|
||||
#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<PlaneUniform> _plane_s;
|
||||
ref_ptr<PlaneUniform> _plane_t;
|
||||
ref_ptr<PlaneUniform> _plane_r;
|
||||
ref_ptr<PlaneUniform> _plane_q;
|
||||
|
||||
StateSet::DefineList _defineList;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/TexGen>
|
||||
#include <osg/State>
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
|
||||
@ -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<<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)
|
||||
{
|
||||
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<<","<<plane<<")"<<std::endl; break;
|
||||
}
|
||||
}
|
||||
@ -47,11 +117,11 @@ const Plane& TexGen::getPlane(Coord which) const
|
||||
{
|
||||
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)"<<std::endl; return _plane_r;
|
||||
case S : return _plane_s->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)"<<std::endl; return _plane_r->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)"<<std::endl; return _plane_r;
|
||||
case S : return _plane_s->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)"<<std::endl; return _plane_r->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."<<std::endl;
|
||||
if (state.getUseStateAttributeShaders())
|
||||
#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