Added proper handling of 3d texture compression
This commit is contained in:
@@ -448,7 +448,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB,&compressed);
|
||||
}
|
||||
}
|
||||
else if (textureMode==GL_TEXTURE_2D)
|
||||
else if (textureMode==GL_TEXTURE_3D)
|
||||
{
|
||||
if (extensions3D->isCompressedTexImage3DSupported())
|
||||
{
|
||||
|
||||
@@ -600,6 +600,16 @@ bool Texture::isCompressedInternalFormat(GLint internalFormat) const
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::getCompressedSize(GLenum internalFormat, GLint width, GLint height, GLint depth, GLint& blockSize, GLint& size) const
|
||||
{
|
||||
if (_internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || _internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
|
||||
blockSize = 8;
|
||||
else
|
||||
blockSize = 16;
|
||||
|
||||
size = ((width+3)/4)*((height+3)/4)*depth*blockSize;
|
||||
}
|
||||
|
||||
void Texture::applyTexParameters(GLenum target, State& state) const
|
||||
{
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
@@ -738,6 +748,7 @@ bool Texture::areAllTextureObjectsLoaded() const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* image, GLsizei inwidth, GLsizei inheight,GLsizei numMipmapLevels) const
|
||||
{
|
||||
// if we don't have a valid image we can't create a texture!
|
||||
@@ -833,8 +844,8 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
|
||||
{
|
||||
numMipmapLevels = 1;
|
||||
|
||||
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
|
||||
GLint size = ((inwidth+3)/4)*((inheight+3)/4)*blockSize;
|
||||
GLint blockSize, size;
|
||||
getCompressedSize(_internalFormat, inwidth, inheight, 1, blockSize,size);
|
||||
|
||||
extensions->glCompressedTexImage2D(target, 0, _internalFormat,
|
||||
inwidth, inheight,0,
|
||||
@@ -879,8 +890,8 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
|
||||
}
|
||||
else if (extensions->isCompressedTexImage2DSupported())
|
||||
{
|
||||
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
|
||||
GLint size = 0;
|
||||
GLint blockSize, size;
|
||||
|
||||
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
|
||||
{
|
||||
if (width == 0)
|
||||
@@ -888,7 +899,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
|
||||
size = ((width+3)/4)*((height+3)/4)*blockSize;
|
||||
getCompressedSize(_internalFormat, width, height, 1, blockSize,size);
|
||||
extensions->glCompressedTexImage2D(target, k, _internalFormat,
|
||||
width, height, _borderWidth,
|
||||
size, image->getMipmapData(k));
|
||||
@@ -1034,8 +1045,8 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
}
|
||||
else if (extensions->isCompressedTexImage2DSupported())
|
||||
{
|
||||
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
|
||||
GLint size = ((inwidth+3)/4)*((inheight+3)/4)*blockSize;
|
||||
GLint blockSize,size;
|
||||
getCompressedSize(_internalFormat, inwidth, inheight, 1, blockSize,size);
|
||||
|
||||
extensions->glCompressedTexSubImage2D(target, 0,
|
||||
0,0,
|
||||
@@ -1079,8 +1090,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
}
|
||||
else if (extensions->isCompressedTexImage2DSupported())
|
||||
{
|
||||
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
|
||||
GLint size = 0;
|
||||
GLint blockSize,size;
|
||||
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
|
||||
{
|
||||
if (width == 0)
|
||||
@@ -1088,7 +1098,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
|
||||
size = ((width+3)/4)*((height+3)/4)*blockSize;
|
||||
getCompressedSize(_internalFormat, inwidth, inheight, 1, blockSize,size);
|
||||
|
||||
//state.checkGLErrors("before extensions->glCompressedTexSubImage2D(");
|
||||
|
||||
|
||||
@@ -93,6 +93,53 @@ void Texture3D::setImage(Image* image)
|
||||
_image = image;
|
||||
}
|
||||
|
||||
void Texture3D::computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& inwidth, GLsizei& inheight,GLsizei& indepth, GLsizei& numMipmapLevels) const
|
||||
{
|
||||
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 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();
|
||||
if (height>extensions->maxTexture3DSize()) height = extensions->maxTexture3DSize();
|
||||
if (depth>extensions->maxTexture3DSize()) depth = extensions->maxTexture3DSize();
|
||||
|
||||
inwidth = width;
|
||||
inheight = height;
|
||||
indepth = depth;
|
||||
|
||||
bool useHardwareMipMapGeneration = false; //!image.isMipmap() && _useHardwareMipMapGeneration && extensions->isGenerateMipMapSupported();
|
||||
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST || useHardwareMipMapGeneration )
|
||||
{
|
||||
numMipmapLevels = 1;
|
||||
}
|
||||
else if( image.isMipmap() )
|
||||
{
|
||||
numMipmapLevels = image.getNumMipmapLevels();
|
||||
}
|
||||
else
|
||||
{
|
||||
numMipmapLevels = 0;
|
||||
for( ; (width || height || depth) ;++numMipmapLevels)
|
||||
{
|
||||
|
||||
if (width == 0)
|
||||
width = 1;
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
if (depth == 0)
|
||||
depth = 1;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Texture3D::apply(State& state) const
|
||||
{
|
||||
@@ -155,10 +202,17 @@ void Texture3D::apply(State& state) const
|
||||
else if (_image.valid() && _image->data())
|
||||
{
|
||||
|
||||
// compute the internal texture format, this set the _internalFormat to an appropriate value.
|
||||
computeInternalFormat();
|
||||
|
||||
// compute the dimensions of the texture.
|
||||
computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
|
||||
|
||||
_textureObjectBuffer[contextID] = textureObject = generateTextureObject(contextID,GL_TEXTURE_3D);
|
||||
|
||||
textureObject->bind();
|
||||
|
||||
|
||||
applyTexParameters(GL_TEXTURE_3D,state);
|
||||
|
||||
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
|
||||
@@ -195,7 +249,6 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
// current OpenGL context.
|
||||
const unsigned int contextID = state.getContextID();
|
||||
|
||||
const Extensions* extensions = getExtensions(contextID,true);
|
||||
|
||||
// compute the internal texture format, this set the _internalFormat to an appropriate value.
|
||||
@@ -203,6 +256,8 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
|
||||
|
||||
// select the internalFormat required for the texture.
|
||||
bool compressed = isCompressedInternalFormat(_internalFormat);
|
||||
bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
//notify(WARN)<<"Warning::cannot currently use compressed format with 3D textures."<<std::endl;
|
||||
@@ -216,11 +271,33 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST )
|
||||
{
|
||||
numMipmapLevels = 1;
|
||||
extensions->glTexImage3D( target, 0, _internalFormat,
|
||||
image->s(), image->t(), image->r(), _borderWidth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->data() );
|
||||
|
||||
if (!compressed_image)
|
||||
{
|
||||
// notify(WARN)<<"glTexImage3D"<<std::endl;
|
||||
extensions->glTexImage3D( target, 0, _internalFormat,
|
||||
inwidth, inheight, indepth,
|
||||
_borderWidth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->data() );
|
||||
}
|
||||
else if (extensions->isCompressedTexImage3DSupported())
|
||||
{
|
||||
// notify(WARN)<<"glCompressedTexImage3D "<<inwidth<<", "<<inheight<<", "<<indepth<<std::endl;
|
||||
numMipmapLevels = 1;
|
||||
|
||||
GLint blockSize, size;
|
||||
getCompressedSize(_internalFormat, inwidth, inheight, indepth, blockSize,size);
|
||||
|
||||
extensions->glCompressedTexImage3D(target, 0, _internalFormat,
|
||||
inwidth, inheight, indepth,
|
||||
_borderWidth,
|
||||
size,
|
||||
image->data());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user