diff --git a/include/osg/Texture b/include/osg/Texture index 87199db92..e329a8fac 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -99,7 +99,9 @@ class SG_EXPORT Texture : public StateAttribute _textureHeight(text._textureHeight), _subloadMode(text._subloadMode), _subloadOffsX(text._subloadOffsX), - _subloadOffsY(text._subloadOffsY) {} + _subloadOffsY(text._subloadOffsY), + _subloadWidth(text._subloadWidth), + _subloadHeight(text._subloadHeight) {} META_StateAttribute(Texture,(Type)(TEXTURE_0+_textureUnit)); @@ -260,6 +262,19 @@ class SG_EXPORT Texture : public StateAttribute y = _subloadOffsY; } + /** Set the texture subload width. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setSubloadSize(const int width, const int height) { + _subloadWidth = width; + _subloadHeight = height; + } + + /** Get the texture subload width. */ + inline void getSubloadSize(int& width, int& height) const { + width = _subloadWidth; + height = _subloadHeight; + } + /** Get the handle to the texture object for the current context.*/ inline GLuint& getHandle(const uint contextID) const { @@ -358,7 +373,8 @@ class SG_EXPORT Texture : public StateAttribute mutable unsigned int _textureWidth, _textureHeight; SubloadMode _subloadMode; - unsigned int _subloadOffsX, _subloadOffsY; + unsigned GLint _subloadOffsX, _subloadOffsY; + unsigned GLsizei _subloadWidth, _subloadHeight; // static cache of deleted display lists which can only // by completely deleted once the appropriate OpenGL context diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 8bc8f0020..19776254d 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -42,6 +42,7 @@ Texture::Texture() _subloadMode = OFF; _subloadOffsX = _subloadOffsY = 0; + _subloadWidth = _subloadHeight = 0; _borderColor.set(0.0, 0.0, 0.0, 0.0);//OpenGL default @@ -95,6 +96,8 @@ int Texture::compare(const StateAttribute& sa) const COMPARE_StateAttribute_Parameter(_subloadMode) COMPARE_StateAttribute_Parameter(_subloadOffsX) COMPARE_StateAttribute_Parameter(_subloadOffsY) + COMPARE_StateAttribute_Parameter(_subloadWidth) + COMPARE_StateAttribute_Parameter(_subloadHeight) return 0; // passed all the above comparison macro's, must be equal. } @@ -209,7 +212,7 @@ void Texture::apply(State& state) const if (_texParamtersDirty) applyTexParameters(_target,state); glTexSubImage2D(_target, 0, _subloadOffsX, _subloadOffsY, - _image->s(), _image->t(), + (_subloadWidth>0)?_subloadWidth:_image->s(), (_subloadHeight>0)?_subloadHeight:_image->t(), (GLenum) _image->pixelFormat(), (GLenum) _image->dataType(), _image->data()); // update the modified flag to show that the image has been loaded. @@ -453,14 +456,17 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const if (s_SGIS_GenMipmap && (_min_filter != LINEAR && _min_filter != NEAREST)) { glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); } - + + GLsizei width = (_subloadWidth>0)?_subloadWidth:image->s(); + GLsizei height = (_subloadHeight>0)?_subloadHeight:image->t(); + // calculate texture dimension _textureWidth = 1; - for (; _textureWidth < (_subloadOffsX + image->s()); _textureWidth <<= 1) + for (; _textureWidth < (_subloadOffsX + width); _textureWidth <<= 1) ; _textureHeight = 1; - for (; _textureHeight < (_subloadOffsY + image->t()); _textureHeight <<= 1) + for (; _textureHeight < (_subloadOffsY + height); _textureHeight <<= 1) ; // reserve appropriate texture memory @@ -471,7 +477,7 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const glTexSubImage2D(target, 0, _subloadOffsX, _subloadOffsY, - image->s(), image->t(), + width, height, (GLenum) image->pixelFormat(), (GLenum) image->dataType(), image->data()); } diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index cc00d7d9e..75f7f2048 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -205,7 +205,7 @@ void TextureCubeMap::apply(State& state) const { glTexSubImage2D(faceTarget[n], 0, _subloadOffsX, _subloadOffsY, - _images[n]->s(), _images[n]->t(), + (_subloadWidth>0)?_subloadWidth:_images[n]->s(), (_subloadHeight>0)?_subloadHeight:_images[n]->t(), (GLenum) _images[n]->pixelFormat(), (GLenum) _images[n]->dataType(), _images[n]->data()); // update the modified flag to show that the image has been loaded. diff --git a/src/osgPlugins/osg/Texture.cpp b/src/osgPlugins/osg/Texture.cpp index d198e0fd8..98cb5bfc8 100644 --- a/src/osgPlugins/osg/Texture.cpp +++ b/src/osgPlugins/osg/Texture.cpp @@ -128,6 +128,16 @@ bool Texture_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } } + if (fr[0].matchWord("subloadSize")) + { + int width, height; + if (fr[1].getInt(width) && fr[2].getInt(height)) + { + texture.setSubloadSize(width, height); + fr += 3; + iteratorAdvanced = true; + } + } return iteratorAdvanced; } @@ -164,6 +174,10 @@ bool Texture_writeLocalData(const Object& obj, Output& fw) int x, y; texture.getSubloadOffset(x, y); fw.indent() << "subloadOffset " << x << " " << y << std::endl; + + int width, height; + texture.getSubloadSize(width, height); + fw.indent() << "subloadSize " << width << " " << height << std::endl; } return true;