diff --git a/examples/osgtexturerectangle/osgtexturerectangle.cpp b/examples/osgtexturerectangle/osgtexturerectangle.cpp index a0b4961ec..99ffe520b 100644 --- a/examples/osgtexturerectangle/osgtexturerectangle.cpp +++ b/examples/osgtexturerectangle/osgtexturerectangle.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -40,10 +41,9 @@ class TexturePanCallback : public osg::NodeCallback { public: - TexturePanCallback(osg::Geometry* geom, osg::Image* img, + TexturePanCallback(osg::TexMat* texmat, double delay = 0.05) : - _geom(geom), - _img(img), + _texmat(texmat), _phaseS(35.0f), _phaseT(18.0f), _phaseScale(5.0f), @@ -54,7 +54,7 @@ public: virtual void operator()(osg::Node*, osg::NodeVisitor* nv) { - if (!_geom || !_img) + if (!_texmat) return; if (nv->getFrameStamp()) { @@ -69,16 +69,11 @@ public: // calculate new texture coordinates float s, t; - s = ((sin(rad * _phaseS) + 1) * 0.5f) * (_img->s() * scaleR); - t = ((sin(rad * _phaseT) + 1) * 0.5f) * (_img->t() * scaleR); + s = ((sin(rad * _phaseS) + 1) * 0.5f) * (scaleR); + t = ((sin(rad * _phaseT) + 1) * 0.5f) * (scaleR); - // set new texture coordinate array - osg::Vec2Array* texcoords = (osg::Vec2Array*) _geom->getTexCoordArray(0); - float w = _img->s() * scale, h = _img->t() * scale; - (*texcoords)[0].set(s, t+h); - (*texcoords)[1].set(s, t); - (*texcoords)[2].set(s+w, t); - (*texcoords)[3].set(s+w, t+h); + + _texmat->setMatrix(osg::Matrix::translate(s,t,1.0)*osg::Matrix::scale(scale,scale,1.0)); // record time _prevTime = currTime; @@ -87,8 +82,7 @@ public: } private: - osg::Geometry* _geom; - osg::Image* _img; + osg::TexMat* _texmat; float _phaseS, _phaseT, _phaseScale; @@ -148,13 +142,18 @@ osg::Node* createRectangle(osg::BoundingBox& bb, osg::StateSet* state = geom->getOrCreateStateSet(); state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); + // setup state + osg::TexMat* texmat = new osg::TexMat; + texmat->setScaleByTextureRectangleSize(true); + state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); + // turn off lighting state->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // install 'update' callback osg::Geode* geode = new osg::Geode; geode->addDrawable(geom); - geode->setUpdateCallback(new TexturePanCallback(geom, img)); + geode->setUpdateCallback(new TexturePanCallback(texmat)); return geode; } @@ -194,7 +193,7 @@ osg::Node* createHUD() const char* text[] = { "TextureRectangle Mini-HOWTO", "- essentially behaves like Texture2D, *except* that:", - "- tex coords must be non-normalized (0..pixel) instead of (0..1)", + "- tex coords must be non-normalized (0..pixel) instead of (0..1),\nalternatively you can use osg::TexMat to scale normal non dimensional texcoords.", "- wrap modes must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER\n repeating wrap modes are not supported", "- filter modes must be NEAREST or LINEAR since\n mipmaps are not supported", "- texture borders are not supported", diff --git a/include/osg/TexMat b/include/osg/TexMat index afdcd4751..d4a29792f 100644 --- a/include/osg/TexMat +++ b/include/osg/TexMat @@ -60,6 +60,16 @@ class OSG_EXPORT TexMat : public StateAttribute /** Get the const texture matrix */ inline const Matrix& getMatrix() const { return _matrix; } + /** Switch on/off the post scaling of the TexMat matrix by the size of the last applied texture rectangle. + * Use a TexMat alongside a TextureRectangle with this scaling applied allows one to treat a TextureRectnagles texture coordinate + * range as if it were the usual non dimensional 0.0 to 1.0 range. + * Note, the TexMat matrix itself is not modified by the post scaling, its purely an operation passed to OpenGL to do the post scaling once the + * the TexMat matrix has been loaded.*/ + void setScaleByTextureRectangleSize(bool flag) { _scaleByTextureRectangleSize = flag; } + + /** Get whether the post scaling of the TexMat matrix, by the size of the last applied texture rectangle, is switched on/off.*/ + bool getScaleByTextureRectangleSize() const { return _scaleByTextureRectangleSize; } + /** Apply texture matrix to OpenGL state. */ virtual void apply(State& state) const; @@ -68,6 +78,7 @@ class OSG_EXPORT TexMat : public StateAttribute virtual ~TexMat( void ); Matrix _matrix; + bool _scaleByTextureRectangleSize; }; diff --git a/src/osg/TexMat.cpp b/src/osg/TexMat.cpp index 830490fc6..69b6da623 100644 --- a/src/osg/TexMat.cpp +++ b/src/osg/TexMat.cpp @@ -12,10 +12,13 @@ */ #include #include +#include +#include using namespace osg; -TexMat::TexMat() +TexMat::TexMat(): + _scaleByTextureRectangleSize(false) { } @@ -24,9 +27,20 @@ TexMat::~TexMat() { } -void TexMat::apply(State&) const +void TexMat::apply(State& state) const { + glMatrixMode( GL_TEXTURE ); glLoadMatrix(_matrix.ptr()); + + if (_scaleByTextureRectangleSize) + { + const osg::TextureRectangle* tex = dynamic_cast(state.getLastAppliedTextureAttribute(state.getActiveTextureUnit(), osg::StateAttribute::TEXTURE)); + if (tex) + { + glScalef(tex->getTextureWidth(),tex->getTextureHeight(),1.0f); + } + } + glMatrixMode( GL_MODELVIEW ); } diff --git a/src/osgPlugins/ive/IveVersion.h b/src/osgPlugins/ive/IveVersion.h index b5a311174..264f99735 100644 --- a/src/osgPlugins/ive/IveVersion.h +++ b/src/osgPlugins/ive/IveVersion.h @@ -25,8 +25,9 @@ #define VERSION_0014 14 #define VERSION_0015 15 #define VERSION_0016 16 +#define VERSION_0017 17 -#define VERSION VERSION_0016 +#define VERSION VERSION_0017 /* The BYTE_SEX tag is used to check the endian of the IVE file being read in. The IVE format diff --git a/src/osgPlugins/ive/TexMat.cpp b/src/osgPlugins/ive/TexMat.cpp index b33ed1d02..94e8e100e 100644 --- a/src/osgPlugins/ive/TexMat.cpp +++ b/src/osgPlugins/ive/TexMat.cpp @@ -32,6 +32,12 @@ void TexMat::write(DataOutputStream* out){ // Write mode out->writeMatrixf(getMatrix()); + + if ( out->getVersion() >= VERSION_0017 ) + { + out->writeBool(getScaleByTextureRectangleSize()); + } + } void TexMat::read(DataInputStream* in){ @@ -51,6 +57,11 @@ void TexMat::read(DataInputStream* in){ // Read matrix setMatrix(in->readMatrixf()); + + if ( in->getVersion() >= VERSION_0017 ) + { + setScaleByTextureRectangleSize(in->readBool()); + } } else{ diff --git a/src/osgPlugins/osg/TexMat.cpp b/src/osgPlugins/osg/TexMat.cpp index 0f895cc3d..58531f77c 100644 --- a/src/osgPlugins/osg/TexMat.cpp +++ b/src/osgPlugins/osg/TexMat.cpp @@ -53,6 +53,22 @@ bool TexMat_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } + if (fr[0].matchWord("scaleByTextureRectangleSize")) + { + if (fr[1].matchWord("TRUE")) + { + texmat.setScaleByTextureRectangleSize(true); + fr +=2 ; + iteratorAdvanced = true; + } + else if (fr[1].matchWord("FALSE")) + { + texmat.setScaleByTextureRectangleSize(false); + fr +=2 ; + iteratorAdvanced = true; + } + } + return iteratorAdvanced; } @@ -65,5 +81,11 @@ bool TexMat_writeLocalData(const Object& obj, Output& fw) fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl; fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl; fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl; + + if (texmat.getScaleByTextureRectangleSize()) + { + fw.indent() << "scaleByTextureRectangleSize TRUE"<