diff --git a/include/osg/Texture b/include/osg/Texture index 53c8930ae..119c3cae8 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -71,6 +71,10 @@ #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 #endif +#ifndef GL_OES_compressed_ETC1_RGB8_texture + #define GL_ETC1_RGB8_OES 0x8D64 +#endif + #ifndef GL_ARB_INTERNAL_TEXTURE_FORMAT #define GL_RGBA32F_ARB 0x8814 #define GL_RGB32F_ARB 0x8815 @@ -446,6 +450,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute USE_S3TC_DXT1_COMPRESSION, USE_S3TC_DXT3_COMPRESSION, USE_S3TC_DXT5_COMPRESSION, + USE_PVRTC_2BPP_COMPRESSION, + USE_PVRTC_4BPP_COMPRESSION, + USE_ETC_COMPRESSION, USE_RGTC1_COMPRESSION, USE_RGTC2_COMPRESSION, USE_S3TC_DXT1c_COMPRESSION, @@ -644,6 +651,15 @@ class OSG_EXPORT Texture : public osg::StateAttribute void setTextureCompressionS3TCSupported(bool flag) { _isTextureCompressionS3TCSupported=flag; } bool isTextureCompressionS3TCSupported() const { return _isTextureCompressionS3TCSupported; } + void setTextureCompressionPVRTC2BPPSupported(bool flag) { _isTextureCompressionPVRTC2BPPSupported=flag; } + bool isTextureCompressionPVRTC2BPPSupported() const { return _isTextureCompressionPVRTC2BPPSupported; } + + void setTextureCompressionPVRTC4BPPSupported(bool flag) { _isTextureCompressionPVRTC4BPPSupported=flag; } + bool isTextureCompressionPVRTC4BPPSupported() const { return _isTextureCompressionPVRTC4BPPSupported; } + + void setTextureCompressionETCSupported(bool flag) { _isTextureCompressionETCSupported=flag; } + bool isTextureCompressionETCSupported() const { return _isTextureCompressionETCSupported; } + void setTextureCompressionRGTCSupported(bool flag) { _isTextureCompressionRGTCSupported=flag; } bool isTextureCompressionRGTCSupported() const { return _isTextureCompressionRGTCSupported; } @@ -748,6 +764,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute bool _isTextureFilterAnisotropicSupported; bool _isTextureCompressionARBSupported; bool _isTextureCompressionS3TCSupported; + bool _isTextureCompressionPVRTC2BPPSupported; + bool _isTextureCompressionPVRTC4BPPSupported; + bool _isTextureCompressionETCSupported; bool _isTextureCompressionRGTCSupported; bool _isTextureCompressionPVRTCSupported; bool _isTextureMirroredRepeatSupported; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index ca11ac6d9..58d017f86 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -311,6 +311,7 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat) case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): return 3; case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): return 4; case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): return 4; + case(GL_ETC1_RGB8_OES): return 3; case(GL_COLOR_INDEX): return 1; case(GL_STENCIL_INDEX): return 1; case(GL_DEPTH_COMPONENT): return 1; @@ -415,17 +416,15 @@ 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; - case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): return 4; case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): return 2; case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): return 4; case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): return 2; - + case(GL_ETC1_RGB8_OES): return 4; default: break; } @@ -564,6 +563,7 @@ bool Image::isCompressed() const case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): + case(GL_ETC1_RGB8_OES): return true; default: return false; @@ -604,6 +604,11 @@ unsigned int Image::getTotalSizeInBytesIncludingMipmaps() const break; case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): + case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): + case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): + case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): + case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): + case(GL_ETC1_RGB8_OES): sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 16 break; case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index f1544b4e3..fc27b3452 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -138,6 +138,8 @@ void Texture::TextureProfile::computeSize() case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): numBitsPerTexel = 2; break; case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): numBitsPerTexel = 4; break; case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): numBitsPerTexel = 4; break; + + case(GL_ETC1_RGB8_OES): numBitsPerTexel = 4; break; } _size = (unsigned int)(ceil(double(_width * _height * _depth * numBitsPerTexel)/8.0)); @@ -1358,7 +1360,40 @@ void Texture::computeInternalFormatWithImage(const osg::Image& image) const } else internalFormat = image.getInternalTextureFormat(); break; - + case(USE_PVRTC_2BPP_COMPRESSION): + if (extensions->isTextureCompressionPVRTC2BPPSupported()) + { + switch(image.getPixelFormat()) + { + case(3): + case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; break; + case(4): + case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; break; + default: internalFormat = image.getInternalTextureFormat(); break; + } + } + case(USE_PVRTC_4BPP_COMPRESSION): + if (extensions->isTextureCompressionPVRTC4BPPSupported()) + { + switch(image.getPixelFormat()) + { + case(3): + case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; + case(4): + case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; break; + default: internalFormat = image.getInternalTextureFormat(); break; + } + } + case(USE_ETC_COMPRESSION): + if (extensions->isTextureCompressionETCSupported()) + { + switch(image.getPixelFormat()) + { + case(3): + case(GL_RGB): internalFormat = GL_ETC1_RGB8_OES; break; + default: internalFormat = image.getInternalTextureFormat(); break; + } + } case(USE_RGTC1_COMPRESSION): if (extensions->isTextureCompressionRGTCSupported()) { @@ -1505,6 +1540,7 @@ bool Texture::isCompressedInternalFormat(GLint internalFormat) case(GL_COMPRESSED_RED_RGTC1_EXT): case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): + case(GL_ETC1_RGB8_OES): case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): @@ -1521,6 +1557,8 @@ 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_ETC1_RGB8_OES) + 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) @@ -1777,10 +1815,15 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima switch(_internalFormat) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + case GL_ETC1_RGB8_OES: case GL_COMPRESSED_RGB: _internalFormat = GL_RGB; break; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: case GL_COMPRESSED_RGBA: _internalFormat = GL_RGBA; break; case GL_COMPRESSED_ALPHA: _internalFormat = GL_ALPHA; break; case GL_COMPRESSED_LUMINANCE: _internalFormat = GL_LUMINANCE; break; @@ -2413,6 +2456,13 @@ Texture::Extensions::Extensions(unsigned int contextID) _isTextureCompressionS3TCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc"); + _isTextureCompressionPVRTC2BPPSupported = isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc"); + + _isTextureCompressionPVRTC4BPPSupported = _isTextureCompressionPVRTC2BPPSupported;//covered by same extension + + _isTextureCompressionETCSupported = isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture"); + + _isTextureCompressionRGTCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc"); _isTextureCompressionPVRTCSupported = isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc"); diff --git a/src/osgPlugins/pvr/ReaderWriterPVR.cpp b/src/osgPlugins/pvr/ReaderWriterPVR.cpp index 8956a1626..8a5a9a672 100644 --- a/src/osgPlugins/pvr/ReaderWriterPVR.cpp +++ b/src/osgPlugins/pvr/ReaderWriterPVR.cpp @@ -45,7 +45,8 @@ enum kPVRTextureFlagTypePVRTC_2 = 12, kPVRTextureFlagTypePVRTC_4, kPVRTextureFlagTypeOGLPVRTC_2 = 24, - kPVRTextureFlagTypeOGLPVRTC_4 + kPVRTextureFlagTypeOGLPVRTC_4, + kPVRTextureFlagTypeETC = 54 }; typedef struct _PVRTexHeader @@ -154,11 +155,14 @@ public: bool hasAlpha; if(formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2 || - formatFlags == kPVRTextureFlagTypeOGLPVRTC_4 || formatFlags == kPVRTextureFlagTypeOGLPVRTC_2){ + formatFlags == kPVRTextureFlagTypeOGLPVRTC_4 || formatFlags == kPVRTextureFlagTypeOGLPVRTC_2 || + formatFlags == kPVRTextureFlagTypeETC){ if(formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypeOGLPVRTC_4) internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; else if(formatFlags == kPVRTextureFlagTypePVRTC_2 || formatFlags == kPVRTextureFlagTypeOGLPVRTC_2) internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + else if(formatFlags == kPVRTextureFlagTypeETC) + internalFormat = GL_ETC1_RGB8_OES; width = header.width; height = header.height; @@ -193,6 +197,11 @@ public: widthBlocks = width / 4; heightBlocks = height / 4; bpp = 4; + }else if(formatFlags == kPVRTextureFlagTypeETC){ + blockSize = 4 * 4; // Pixel by pixel block size for 4bpp + widthBlocks = width / 4; + heightBlocks = height / 4; + bpp = 4; }else{ blockSize = 8 * 4; // Pixel by pixel block size for 2bpp widthBlocks = width / 8;