diff --git a/include/osg/Texture b/include/osg/Texture index be68d03db..c49859336 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -57,6 +57,13 @@ #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif +#ifndef GL_EXT_texture_compression_rgtc + #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB + #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC + #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD + #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + #ifndef GL_ARB_INTERNAL_TEXTURE_FORMAT #define GL_RGBA32F_ARB 0x8814 #define GL_RGB32F_ARB 0x8815 @@ -435,7 +442,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute USE_ARB_COMPRESSION, USE_S3TC_DXT1_COMPRESSION, USE_S3TC_DXT3_COMPRESSION, - USE_S3TC_DXT5_COMPRESSION + USE_S3TC_DXT5_COMPRESSION, + USE_RGTC1_COMPRESSION, + USE_RGTC2_COMPRESSION }; /** Sets the internal texture format mode. Note: If the texture format is @@ -630,6 +639,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute void setTextureCompressionS3TCSupported(bool flag) { _isTextureCompressionS3TCSupported=flag; } bool isTextureCompressionS3TCSupported() const { return _isTextureCompressionS3TCSupported; } + void setTextureCompressionRGTCSupported(bool flag) { _isTextureCompressionRGTCSupported=flag; } + bool isTextureCompressionRGTCSupported() const { return _isTextureCompressionRGTCSupported; } + void setTextureMirroredRepeatSupported(bool flag) { _isTextureMirroredRepeatSupported=flag; } bool isTextureMirroredRepeatSupported() const { return _isTextureMirroredRepeatSupported; } @@ -728,6 +740,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute bool _isTextureFilterAnisotropicSupported; bool _isTextureCompressionARBSupported; bool _isTextureCompressionS3TCSupported; + bool _isTextureCompressionRGTCSupported; bool _isTextureMirroredRepeatSupported; bool _isTextureEdgeClampSupported; bool _isTextureBorderClampSupported; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 363143884..715000dc2 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -332,6 +332,10 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat) case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): return 4; case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): return 4; case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): return 4; + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): return 1; + case(GL_COMPRESSED_RED_RGTC1_EXT): return 1; + case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): return 2; + case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): return 2; case(GL_COLOR_INDEX): return 1; case(GL_STENCIL_INDEX): return 1; case(GL_DEPTH_COMPONENT): return 1; @@ -436,6 +440,12 @@ unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type) case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): return 4; case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): return 8; case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): return 8; + + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): return 4; + case(GL_COMPRESSED_RED_RGTC1_EXT): return 4; + case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): return 8; + case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): return 8; + default: break; } @@ -588,6 +598,14 @@ unsigned int Image::getTotalSizeInBytesIncludingMipmaps() const case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 16 break; + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): + case(GL_COMPRESSED_RED_RGTC1_EXT): + sizeOfLastMipMap = maximum(sizeOfLastMipMap, 8u); // block size of 8 + break; + case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): + case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): + sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 8 + break; default: break; } diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 24840a378..9c496d035 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -130,6 +130,11 @@ void Texture::TextureProfile::computeSize() case(GL_COMPRESSED_RGB_ARB): numBitsPerTexel = 8; break; case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): numBitsPerTexel = 8; break; case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): numBitsPerTexel = 8; break; + + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): numBitsPerTexel = 4; break; + case(GL_COMPRESSED_RED_RGTC1_EXT): numBitsPerTexel = 4; break; + case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): numBitsPerTexel = 8; break; + case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): numBitsPerTexel = 8; break; } _size = (unsigned int)(ceil(double(_width * _height * _depth * numBitsPerTexel)/8.0)); @@ -1199,6 +1204,35 @@ void Texture::computeInternalFormatWithImage(const osg::Image& image) const } else internalFormat = image.getInternalTextureFormat(); break; + + case(USE_RGTC1_COMPRESSION): + if (extensions->isTextureCompressionRGTCSupported()) + { + switch(image.getPixelFormat()) + { + case(3): + case(GL_RGB): internalFormat = GL_COMPRESSED_RED_RGTC1_EXT; break; + case(4): + case(GL_RGBA): internalFormat = GL_COMPRESSED_RED_RGTC1_EXT; break; + default: internalFormat = image.getInternalTextureFormat(); break; + } + } + else internalFormat = image.getInternalTextureFormat(); + break; + case(USE_RGTC2_COMPRESSION): + if (extensions->isTextureCompressionRGTCSupported()) + { + switch(image.getPixelFormat()) + { + case(3): + case(GL_RGB): internalFormat = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; break; + case(4): + case(GL_RGBA): internalFormat = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; break; + default: internalFormat = image.getInternalTextureFormat(); break; + } + } + else internalFormat = image.getInternalTextureFormat(); + break; default: break; } @@ -1313,6 +1347,10 @@ bool Texture::isCompressedInternalFormat(GLint internalFormat) case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): + case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): + case(GL_COMPRESSED_RED_RGTC1_EXT): + case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): + case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): return true; default: return false; @@ -1325,6 +1363,10 @@ void Texture::getCompressedSize(GLenum internalFormat, GLint width, GLint height blockSize = 8; else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) blockSize = 16; + else if (internalFormat == GL_COMPRESSED_RED_RGTC1_EXT || internalFormat == GL_COMPRESSED_SIGNED_RED_RGTC1_EXT) + blockSize = 8; + else if (internalFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT || internalFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) + blockSize = 16; else { OSG_WARN<<"Texture::getCompressedSize(...) : cannot compute correct size of compressed format ("<= GL_COMPRESSED_RED_RGTC1_EXT && + pixelFormat <= GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT ) + { + width = (width + 3) & ~3; + height = (height + 3) & ~3; + } // compute size of one row unsigned int size = osg::Image::computeRowWidthInBytes ( width, pixelFormat, pixelType, packing ); @@ -517,6 +533,16 @@ osg::Image* ReadDDSFile(std::istream& _istream) internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; + case FOURCC_ATI1: + OSG_INFO << "ReadDDSFile info : format = ATI1" << std::endl; + internalFormat = GL_COMPRESSED_RED_RGTC1_EXT; + pixelFormat = GL_COMPRESSED_RED_RGTC1_EXT; + break; + case FOURCC_ATI2: + OSG_INFO << "ReadDDSFile info : format = ATI2" << std::endl; + internalFormat = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + pixelFormat = GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + break; case 0x00000024: // A16B16G16R16 OSG_INFO << "ReadDDSFile info : format = A16B16G16R16" << std::endl; internalFormat = GL_RGBA; @@ -850,6 +876,38 @@ bool WriteDDSFile(const osg::Image *img, std::ostream& fout) SD_flags |= DDSD_LINEARSIZE; } break; + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + { + ddpf.dwFourCC = FOURCC_ATI1; + PF_flags |= DDPF_FOURCC; /* No alpha here */ + ddsd.dwLinearSize = imageSize; + SD_flags |= DDSD_LINEARSIZE; + } + break; + case GL_COMPRESSED_RED_RGTC1_EXT: + { + ddpf.dwFourCC = FOURCC_ATI1; + PF_flags |= DDPF_FOURCC; /* No alpha here */ + ddsd.dwLinearSize = imageSize; + SD_flags |= DDSD_LINEARSIZE; + } + break; + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + { + ddpf.dwFourCC = FOURCC_ATI2; + PF_flags |= DDPF_FOURCC; /* No alpha here */ + ddsd.dwLinearSize = imageSize; + SD_flags |= DDSD_LINEARSIZE; + } + break; + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + { + ddpf.dwFourCC = FOURCC_ATI2; + PF_flags |= DDPF_FOURCC; /* No alpha here */ + ddsd.dwLinearSize = imageSize; + SD_flags |= DDSD_LINEARSIZE; + } + break; default: OSG_WARN<<"Warning:: unhandled pixel format in image, file cannot be written."<