From Farshid Lashkari, support for non power of two extension.

This commit is contained in:
Robert Osfield 2005-05-06 09:04:41 +00:00
parent fd9f5c0f43
commit fc585cd33d
5 changed files with 58 additions and 9 deletions

View File

@ -294,6 +294,15 @@ class OSG_EXPORT Texture : public osg::StateAttribute
/** Gets whether to use client storage for the texture. */ /** Gets whether to use client storage for the texture. */
inline bool getClientStorageHint() const { return _clientStorageHint; } 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 { enum InternalFormatMode {
USE_IMAGE_DATA_FORMAT, USE_IMAGE_DATA_FORMAT,
USE_USER_DEFINED_FORMAT, USE_USER_DEFINED_FORMAT,
@ -556,6 +565,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute
bool _useHardwareMipMapGeneration; bool _useHardwareMipMapGeneration;
bool _unrefImageDataAfterApply; bool _unrefImageDataAfterApply;
bool _clientStorageHint; bool _clientStorageHint;
bool _resizeNonPowerOfTwoHint;
Vec4 _borderColor; Vec4 _borderColor;
GLint _borderWidth; GLint _borderWidth;

View File

@ -337,6 +337,7 @@ Texture::Texture():
_useHardwareMipMapGeneration(true), _useHardwareMipMapGeneration(true),
_unrefImageDataAfterApply(false), _unrefImageDataAfterApply(false),
_clientStorageHint(false), _clientStorageHint(false),
_resizeNonPowerOfTwoHint(false),
_borderColor(0.0, 0.0, 0.0, 0.0), _borderColor(0.0, 0.0, 0.0, 0.0),
_borderWidth(0), _borderWidth(0),
_internalFormatMode(USE_IMAGE_DATA_FORMAT), _internalFormatMode(USE_IMAGE_DATA_FORMAT),
@ -359,6 +360,7 @@ Texture::Texture(const Texture& text,const CopyOp& copyop):
_useHardwareMipMapGeneration(text._useHardwareMipMapGeneration), _useHardwareMipMapGeneration(text._useHardwareMipMapGeneration),
_unrefImageDataAfterApply(text._unrefImageDataAfterApply), _unrefImageDataAfterApply(text._unrefImageDataAfterApply),
_clientStorageHint(text._clientStorageHint), _clientStorageHint(text._clientStorageHint),
_resizeNonPowerOfTwoHint(text._resizeNonPowerOfTwoHint),
_borderColor(text._borderColor), _borderColor(text._borderColor),
_borderWidth(text._borderWidth), _borderWidth(text._borderWidth),
_internalFormatMode(text._internalFormatMode), _internalFormatMode(text._internalFormatMode),
@ -400,6 +402,7 @@ int Texture::compareTexture(const Texture& rhs) const
COMPARE_StateAttribute_Parameter(_unrefImageDataAfterApply) COMPARE_StateAttribute_Parameter(_unrefImageDataAfterApply)
COMPARE_StateAttribute_Parameter(_clientStorageHint) COMPARE_StateAttribute_Parameter(_clientStorageHint)
COMPARE_StateAttribute_Parameter(_resizeNonPowerOfTwoHint)
return 0; return 0;
} }
@ -708,8 +711,18 @@ void Texture::computeRequiredTextureDimensions(State& state, const osg::Image& i
const unsigned int contextID = state.getContextID(); const unsigned int contextID = state.getContextID();
const Extensions* extensions = getExtensions(contextID,true); const Extensions* extensions = getExtensions(contextID,true);
int width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth; int width,height;
int height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth;
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. // cap the size to what the graphics hardware can handle.
if (width>extensions->maxTextureSize()) width = extensions->maxTextureSize(); if (width>extensions->maxTextureSize()) width = extensions->maxTextureSize();

View File

@ -188,6 +188,8 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
// select the internalFormat required for the texture. // select the internalFormat required for the texture.
bool compressed = isCompressedInternalFormat(_internalFormat); bool compressed = isCompressedInternalFormat(_internalFormat);
//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()); image->ensureValidSizeForTexturing(extensions->maxTextureSize());
glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());

View File

@ -97,10 +97,22 @@ void Texture3D::computeRequiredTextureDimensions(State& state, const osg::Image&
{ {
const unsigned int contextID = state.getContextID(); const unsigned int contextID = state.getContextID();
const Extensions* extensions = getExtensions(contextID,true); 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 width,height,depth;
int height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth;
int depth = Image::computeNearestPowerOfTwo(image.r()-2*_borderWidth)+2*_borderWidth; 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. // cap the size to what the graphics hardware can handle.
if (width>extensions->maxTexture3DSize()) width = extensions->maxTexture3DSize(); if (width>extensions->maxTexture3DSize()) width = extensions->maxTexture3DSize();
@ -250,6 +262,7 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
// current OpenGL context. // current OpenGL context.
const unsigned int contextID = state.getContextID(); const unsigned int contextID = state.getContextID();
const Extensions* extensions = getExtensions(contextID,true); 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. // compute the internal texture format, this set the _internalFormat to an appropriate value.
computeInternalFormat(); computeInternalFormat();
@ -264,6 +277,11 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
//return; //return;
} }
//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()); image->ensureValidSizeForTexturing(extensions->maxTexture3DSize());
glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());

View File

@ -258,6 +258,12 @@ void TextureCubeMap::apply(State& state) const
// compute the dimensions of the texture. // compute the dimensions of the texture.
computeRequiredTextureDimensions(state,*_images[0],_textureWidth, _textureHeight, _numMipmapLevels); 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( _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0); contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);