From 6b59f66d803257e04d4fa3763236b30d3989a2de Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 28 Jul 2002 23:28:27 +0000 Subject: [PATCH] Checked in new methods for setting up texture subloading, these allow the user to control which parts on an image are subloaded from, and how big the initial texture is. --- include/osg/Texture | 102 ++++++++++++++++++++++--------------- src/osg/Texture.cpp | 95 +++++++++++++++++++++++++--------- src/osg/TextureCubeMap.cpp | 17 +++++-- 3 files changed, 145 insertions(+), 69 deletions(-) diff --git a/include/osg/Texture b/include/osg/Texture index 253e943dd..4d597f68f 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -77,30 +77,8 @@ class SG_EXPORT Texture : public StateAttribute Texture(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ - Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - StateAttribute(text,copyop), - _handleList(), - _modifiedTag(), - _image(copyop(text._image.get())), - _unrefImageAfterApply(text._unrefImageAfterApply), - _target(text._target), - _wrap_s(text._wrap_s), - _wrap_t(text._wrap_t), - _wrap_r(text._wrap_r), - _min_filter(text._min_filter), - _mag_filter(text._mag_filter), - _texParamtersDirty(false), - _internalFormatMode(text._internalFormatMode), - _internalFormatValue(text._internalFormatValue), - _borderColor(text._borderColor), - _textureWidth(text._textureWidth), - _textureHeight(text._textureHeight), - _subloadMode(text._subloadMode), - _subloadOffsX(text._subloadOffsX), - _subloadOffsY(text._subloadOffsY), - _subloadWidth(text._subloadWidth), - _subloadHeight(text._subloadHeight) {} - + Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + META_StateAttribute(osg, Texture,TEXTURE); virtual bool isTextureAttribute() const { return true; } @@ -121,9 +99,16 @@ class SG_EXPORT Texture : public StateAttribute /** Get the const texture image. */ inline const Image* getImage() const { return _image.get(); } - + + /** Set the unreference image after apply flag, default value is false. + * If set to true the attached image is unreferenced via a _image = 0; + * if the image has no other references to it, it will be automatically + * deleted. Note, this should only by used in case where only a single + * graphics context is being used, otherwise only the first context will + * be set, with the rest left with no image to apply.*/ void setUnrefImageAfterApply(bool unrefImage) { _unrefImageAfterApply = unrefImage; } + /** Get the unreference image after apply flag.*/ bool getUnrefImageAfterApply() const { return _unrefImageAfterApply; } /** Copy pixels into a 2D texture image.As per glCopyTexImage2D. @@ -238,29 +223,63 @@ class SG_EXPORT Texture : public StateAttribute /** Get the texture subload mode. */ inline const SubloadMode getSubloadMode() const { return _subloadMode; } - /** Set the texture subload offsets. */ - inline void setSubloadOffset(const int x, const int y) { - _subloadOffsX = x; - _subloadOffsY = y; + /** Set the texture subload texture offsets. */ + inline void setSubloadTextureOffset(const int x, const int y) + { + _subloadTextureOffsetX = x; + _subloadTextureOffsetY = y; } - /** Get the texture subload offsets. */ - inline void getSubloadOffset(int& x, int& y) const { - x = _subloadOffsX; - y = _subloadOffsY; + /** Get the texture subload texture offsets. */ + inline void getSubloadTextureOffset(int& x, int& y) const + { + x = _subloadTextureOffsetX; + y = _subloadTextureOffsetY; } /** 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; + inline void setSubloadTextureSize(const int width, const int height) + { + _textureWidth = width; + _textureHeight = height; } /** Get the texture subload width. */ - inline void getSubloadSize(int& width, int& height) const { - width = _subloadWidth; - height = _subloadHeight; + inline void getSubloadTextureSize(int& width, int& height) const + { + width = _textureWidth; + height = _textureHeight; + } + + + /** Set the subload image offsets. */ + inline void setSubloadImageOffset(const int x, const int y) + { + _subloadImageOffsetX = x; + _subloadImageOffsetY = y; + } + + /** Get the subload image offsets. */ + inline void getSubloadImageOffset(int& x, int& y) const + { + x = _subloadImageOffsetX; + y = _subloadImageOffsetY; + } + + /** Set the image subload width. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setSubloadImageSize(const int width, const int height) + { + _subloadImageWidth = width; + _subloadImageHeight = height; + } + + /** Get the image subload width. */ + inline void getSubloadImageSize(int& width, int& height) const + { + width = _subloadImageWidth; + height = _subloadImageHeight; } /** Get the handle to the texture object for the current context.*/ @@ -358,8 +377,9 @@ class SG_EXPORT Texture : public StateAttribute mutable GLsizei _textureWidth, _textureHeight; SubloadMode _subloadMode; - GLint _subloadOffsX, _subloadOffsY; - GLsizei _subloadWidth, _subloadHeight; + GLint _subloadTextureOffsetX, _subloadTextureOffsetY; + GLint _subloadImageOffsetX, _subloadImageOffsetY; + GLsizei _subloadImageWidth, _subloadImageHeight; // 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 53641074a..618978451 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -19,8 +19,8 @@ using namespace osg; Texture::DeletedTextureObjectCache Texture::s_deletedTextureObjectCache; Texture::Texture(): + _unrefImageAfterApply(false), _target(GL_TEXTURE_2D), - _unrefImageAfterApply(true), _wrap_s(CLAMP), _wrap_t(CLAMP), _wrap_r(CLAMP), @@ -33,16 +33,44 @@ Texture::Texture(): _textureWidth(0), _textureHeight(0), _subloadMode(OFF), - _subloadOffsX(0), - _subloadOffsY(0), - _subloadWidth(0), - _subloadHeight(0) + _subloadTextureOffsetX(0), + _subloadTextureOffsetY(0), + _subloadImageOffsetX(0), + _subloadImageOffsetY(0), + _subloadImageWidth(0), + _subloadImageHeight(0) { _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); } +Texture::Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + StateAttribute(text,copyop), + _handleList(), + _modifiedTag(), + _image(copyop(text._image.get())), + _unrefImageAfterApply(text._unrefImageAfterApply), + _target(text._target), + _wrap_s(text._wrap_s), + _wrap_t(text._wrap_t), + _wrap_r(text._wrap_r), + _min_filter(text._min_filter), + _mag_filter(text._mag_filter), + _texParamtersDirty(false), + _internalFormatMode(text._internalFormatMode), + _internalFormatValue(text._internalFormatValue), + _borderColor(text._borderColor), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _subloadMode(text._subloadMode), + _subloadTextureOffsetX(text._subloadTextureOffsetX), + _subloadTextureOffsetY(text._subloadTextureOffsetY), + _subloadImageOffsetX(text._subloadImageOffsetX), + _subloadImageOffsetY(text._subloadImageOffsetY), + _subloadImageWidth(text._subloadImageWidth), + _subloadImageHeight(text._subloadImageHeight) +{} Texture::~Texture() { @@ -87,10 +115,12 @@ int Texture::compare(const StateAttribute& sa) const COMPARE_StateAttribute_Parameter(_textureWidth) COMPARE_StateAttribute_Parameter(_textureHeight) COMPARE_StateAttribute_Parameter(_subloadMode) - COMPARE_StateAttribute_Parameter(_subloadOffsX) - COMPARE_StateAttribute_Parameter(_subloadOffsY) - COMPARE_StateAttribute_Parameter(_subloadWidth) - COMPARE_StateAttribute_Parameter(_subloadHeight) + COMPARE_StateAttribute_Parameter(_subloadTextureOffsetX) + COMPARE_StateAttribute_Parameter(_subloadTextureOffsetY) + COMPARE_StateAttribute_Parameter(_subloadImageOffsetX) + COMPARE_StateAttribute_Parameter(_subloadImageOffsetY) + COMPARE_StateAttribute_Parameter(_subloadImageWidth) + COMPARE_StateAttribute_Parameter(_subloadImageHeight) return 0; // passed all the above comparison macro's, must be equal. } @@ -200,11 +230,16 @@ void Texture::apply(State& state) const if (_subloadMode == AUTO || (_subloadMode == IF_DIRTY && modifiedTag != _image->getModifiedTag())) { + glPixelStorei(GL_UNPACK_ROW_LENGTH,_image->getRowSizeInBytes()); + glTexSubImage2D(_target, 0, - _subloadOffsX, _subloadOffsY, - (_subloadWidth>0)?_subloadWidth:_image->s(), (_subloadHeight>0)?_subloadHeight:_image->t(), + _subloadTextureOffsetX, _subloadTextureOffsetY, + (_subloadImageWidth>0)?_subloadImageWidth:_image->s(), (_subloadImageHeight>0)?_subloadImageHeight:_image->t(), (GLenum) _image->getPixelFormat(), (GLenum) _image->getDataType(), - _image->data()); + _image->data(_subloadImageOffsetX,_subloadImageOffsetY)); + + glPixelStorei(GL_UNPACK_ROW_LENGTH,0); + // update the modified flag to show that the image has been loaded. modifiedTag = _image->getModifiedTag(); } @@ -517,29 +552,39 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); } - GLsizei width = (_subloadWidth>0)?_subloadWidth:image->s(); - GLsizei height = (_subloadHeight>0)?_subloadHeight:image->t(); + GLsizei width = (_subloadImageWidth>0)?_subloadImageWidth:image->s(); + GLsizei height = (_subloadImageHeight>0)?_subloadImageHeight:image->t(); + + if (_textureWidth==0) + { + // need to calculate texture dimension + _textureWidth = 1; + for (; _textureWidth < (static_cast(_subloadTextureOffsetX) + width); _textureWidth <<= 1) {} + } + + if (_textureHeight==0) + { + // need to calculate texture dimension + _textureHeight = 1; + for (; _textureHeight < (static_cast(_subloadTextureOffsetY) + height); _textureHeight <<= 1) {} + } - // calculate texture dimension - _textureWidth = 1; - for (; _textureWidth < (static_cast(_subloadOffsX) + width); _textureWidth <<= 1) - ; - - _textureHeight = 1; - for (; _textureHeight < (static_cast(_subloadOffsY) + height); _textureHeight <<= 1) - ; - // reserve appropriate texture memory glTexImage2D(target, 0, internalFormat, _textureWidth, _textureHeight, 0, (GLenum) image->getPixelFormat(), (GLenum) image->getDataType(), NULL); + + glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowSizeInBytes()); + glTexSubImage2D(target, 0, - _subloadOffsX, _subloadOffsY, + _subloadTextureOffsetX, _subloadTextureOffsetY, width, height, (GLenum) image->getPixelFormat(), (GLenum) image->getDataType(), - image->data()); + image->data(_subloadImageOffsetX,_subloadImageOffsetY)); + + glPixelStorei(GL_UNPACK_ROW_LENGTH,0); } } diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 9e59ccce7..559cd7049 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -195,20 +195,31 @@ void TextureCubeMap::apply(State& state) const modifiedTag = 0; glBindTexture( _target, handle ); if (_texParamtersDirty) applyTexParameters(_target,state); + + + unsigned int rowwidth = 0; for (int n=0; n<6; n++) { if ((_subloadMode == AUTO) || (_subloadMode == IF_DIRTY && modifiedTag != _images[n]->getModifiedTag())) { + + if (rowwidth != _images[n]->getRowSizeInBytes()) + { + rowwidth = _images[n]->getRowSizeInBytes(); + glPixelStorei(GL_UNPACK_ROW_LENGTH,rowwidth); + } + glTexSubImage2D(faceTarget[n], 0, - _subloadOffsX, _subloadOffsY, - (_subloadWidth>0)?_subloadWidth:_images[n]->s(), (_subloadHeight>0)?_subloadHeight:_images[n]->t(), + _subloadTextureOffsetX, _subloadTextureOffsetX, + (_subloadImageWidth>0)?_subloadImageWidth:_images[n]->s(), (_subloadImageHeight>0)?_subloadImageHeight:_images[n]->t(), (GLenum) _images[n]->getPixelFormat(), (GLenum) _images[n]->getDataType(), - _images[n]->data()); + _images[n]->data(_subloadImageOffsetX,_subloadImageOffsetY)); // update the modified flag to show that the image has been loaded. modifiedTag += _images[n]->getModifiedTag(); } } + glPixelStorei(GL_UNPACK_ROW_LENGTH,0); } } else if (imagesValid())