From fc585cd33dac5e95b6061f4da84ee504d4ceae4d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 6 May 2005 09:04:41 +0000 Subject: [PATCH] From Farshid Lashkari, support for non power of two extension. --- include/osg/Texture | 10 ++++++++++ src/osg/Texture.cpp | 21 +++++++++++++++++---- src/osg/Texture1D.cpp | 4 +++- src/osg/Texture3D.cpp | 26 ++++++++++++++++++++++---- src/osg/TextureCubeMap.cpp | 6 ++++++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/include/osg/Texture b/include/osg/Texture index 60c60f709..6dbdba59c 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -294,6 +294,15 @@ class OSG_EXPORT Texture : public osg::StateAttribute /** Gets whether to use client storage for the texture. */ inline bool getClientStorageHint() const { return _clientStorageHint; } + /** Sets whether to force the texture to resize images that have dimensions + * that are not a power of two. If enabled, NPOT images will be resized, + * whether or not NPOT textures are supported by the hardware. If disabled, + * NPOT images will not be resized if supported by hardware. */ + inline void setResizeNonPowerOfTwoHint(bool flag) { _resizeNonPowerOfTwoHint = flag; } + + /** Gets whether texture will force non power to two images to be resized. */ + inline bool getResizeNonPowerOfTwoHint() const { return _resizeNonPowerOfTwoHint; } + enum InternalFormatMode { USE_IMAGE_DATA_FORMAT, USE_USER_DEFINED_FORMAT, @@ -556,6 +565,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute bool _useHardwareMipMapGeneration; bool _unrefImageDataAfterApply; bool _clientStorageHint; + bool _resizeNonPowerOfTwoHint; Vec4 _borderColor; GLint _borderWidth; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 8bfc0900b..946695c47 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -337,6 +337,7 @@ Texture::Texture(): _useHardwareMipMapGeneration(true), _unrefImageDataAfterApply(false), _clientStorageHint(false), + _resizeNonPowerOfTwoHint(false), _borderColor(0.0, 0.0, 0.0, 0.0), _borderWidth(0), _internalFormatMode(USE_IMAGE_DATA_FORMAT), @@ -359,6 +360,7 @@ Texture::Texture(const Texture& text,const CopyOp& copyop): _useHardwareMipMapGeneration(text._useHardwareMipMapGeneration), _unrefImageDataAfterApply(text._unrefImageDataAfterApply), _clientStorageHint(text._clientStorageHint), + _resizeNonPowerOfTwoHint(text._resizeNonPowerOfTwoHint), _borderColor(text._borderColor), _borderWidth(text._borderWidth), _internalFormatMode(text._internalFormatMode), @@ -400,7 +402,8 @@ int Texture::compareTexture(const Texture& rhs) const COMPARE_StateAttribute_Parameter(_unrefImageDataAfterApply) COMPARE_StateAttribute_Parameter(_clientStorageHint) - + COMPARE_StateAttribute_Parameter(_resizeNonPowerOfTwoHint) + return 0; } @@ -708,13 +711,23 @@ void Texture::computeRequiredTextureDimensions(State& state, const osg::Image& i const unsigned int contextID = state.getContextID(); const Extensions* extensions = getExtensions(contextID,true); - int width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth; - int height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth; + int width,height; + + if( !_resizeNonPowerOfTwoHint && extensions->isNonPowerOfTwoTextureSupported() ) + { + width = image.s(); + height = image.t(); + } + else + { + width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth; + height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth; + } // cap the size to what the graphics hardware can handle. if (width>extensions->maxTextureSize()) width = extensions->maxTextureSize(); if (height>extensions->maxTextureSize()) height = extensions->maxTextureSize(); - + inwidth = width; inheight = height; diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index 94176493b..8932cec62 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -188,7 +188,9 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz // select the internalFormat required for the texture. bool compressed = isCompressedInternalFormat(_internalFormat); - image->ensureValidSizeForTexturing(extensions->maxTextureSize()); + //Rescale if resize hint is set or NPOT not supported or dimension exceeds max size + if( _resizeNonPowerOfTwoHint || !extensions->isNonPowerOfTwoTextureSupported() || inwidth > extensions->maxTextureSize() ) + image->ensureValidSizeForTexturing(extensions->maxTextureSize()); glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 4d9344926..b57e47892 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -97,10 +97,22 @@ void Texture3D::computeRequiredTextureDimensions(State& state, const osg::Image& { const unsigned int contextID = state.getContextID(); const Extensions* extensions = getExtensions(contextID,true); + const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true); - int width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth; - int height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth; - int depth = Image::computeNearestPowerOfTwo(image.r()-2*_borderWidth)+2*_borderWidth; + int width,height,depth; + + if( !_resizeNonPowerOfTwoHint && texExtensions->isNonPowerOfTwoTextureSupported() ) + { + width = image.s(); + height = image.t(); + depth = image.r(); + } + else + { + width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth; + height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth; + depth = Image::computeNearestPowerOfTwo(image.r()-2*_borderWidth)+2*_borderWidth; + } // cap the size to what the graphics hardware can handle. if (width>extensions->maxTexture3DSize()) width = extensions->maxTexture3DSize(); @@ -250,6 +262,7 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz // current OpenGL context. const unsigned int contextID = state.getContextID(); const Extensions* extensions = getExtensions(contextID,true); + const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true); // compute the internal texture format, this set the _internalFormat to an appropriate value. computeInternalFormat(); @@ -264,7 +277,12 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz //return; } - image->ensureValidSizeForTexturing(extensions->maxTexture3DSize()); + //Rescale if resize hint is set or NPOT not supported or dimensions exceed max size + if( _resizeNonPowerOfTwoHint || !texExtensions->isNonPowerOfTwoTextureSupported() + || inwidth > extensions->maxTexture3DSize() + || inheight > extensions->maxTexture3DSize() + || indepth > extensions->maxTexture3DSize() ) + image->ensureValidSizeForTexturing(extensions->maxTexture3DSize()); glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 97d628ef1..3c052cc2a 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -258,6 +258,12 @@ void TextureCubeMap::apply(State& state) const // compute the dimensions of the texture. computeRequiredTextureDimensions(state,*_images[0],_textureWidth, _textureHeight, _numMipmapLevels); + // cubemap textures must have square dimensions + if( _textureWidth != _textureHeight ) + { + _textureWidth = _textureHeight = minimum( _textureWidth , _textureHeight ); + } + _textureObjectBuffer[contextID] = textureObject = generateTextureObject( contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);