@@ -335,6 +335,20 @@ bool Image::isPackedType(GLenum type)
335335 }
336336}
337337
338+ bool Image::isBPTC (GLenum pixelFormat)
339+ {
340+ switch (pixelFormat)
341+ {
342+ case (GL_COMPRESSED_RGBA_BPTC_UNORM):
343+ case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM):
344+ case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT):
345+ case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT):
346+ return true ;
347+ default :
348+ return false ;
349+ }
350+ }
351+
338352
339353GLenum Image::computePixelFormat (GLenum format)
340354{
@@ -707,6 +721,11 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat)
707721 case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : return 4 ;
708722 case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : return 4 ;
709723 case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return 4 ;
724+ // BPTC (BC6H/BC7)
725+ case (GL_COMPRESSED_RGBA_BPTC_UNORM) : return 4 ;
726+ case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) : return 4 ;
727+ case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) : return 3 ;
728+ case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) : return 3 ;
710729 default :
711730 {
712731 OSG_WARN<<" error pixelFormat = " <<std::hex<<pixelFormat<<std::dec<<std::endl;
@@ -733,6 +752,11 @@ unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type)
733752 case (GL_COMPRESSED_RED_RGTC1_EXT): return 4 ;
734753 case (GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): return 8 ;
735754 case (GL_COMPRESSED_RED_GREEN_RGTC2_EXT): return 8 ;
755+ // BPTC (BC6H/BC7) - 128 bits per 4x4 block = 8 bits per pixel
756+ case (GL_COMPRESSED_RGBA_BPTC_UNORM): return 8 ;
757+ case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM): return 8 ;
758+ case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT): return 8 ;
759+ case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT): return 8 ;
736760 case (GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): return 4 ;
737761 case (GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): return 2 ;
738762 case (GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): return 4 ;
@@ -892,6 +916,11 @@ osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat)
892916 case (GL_COMPRESSED_RED_RGTC1_EXT) :
893917 case (GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) :
894918 case (GL_COMPRESSED_RED_GREEN_RGTC2_EXT) :
919+ // BPTC (BC6H/BC7) - 4x4 blocks
920+ case (GL_COMPRESSED_RGBA_BPTC_UNORM) :
921+ case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) :
922+ case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) :
923+ case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) :
895924 case (GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) :
896925 case (GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG) :
897926 case (GL_ETC1_RGB8_OES) :
@@ -971,6 +1000,13 @@ unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing)
9711000 case (GL_COMPRESSED_RED_GREEN_RGTC2_EXT):
9721001 return osg::maximum (16u ,packing); // block size of 16
9731002
1003+ // BPTC (BC6H/BC7) - 16 bytes per block
1004+ case (GL_COMPRESSED_RGBA_BPTC_UNORM):
1005+ case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM):
1006+ case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT):
1007+ case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT):
1008+ return osg::maximum (16u ,packing); // block size of 16
1009+
9741010 case (GL_COMPRESSED_RGB8_ETC2):
9751011 case (GL_COMPRESSED_SRGB8_ETC2):
9761012 case (GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2):
@@ -1021,6 +1057,17 @@ unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing)
10211057
10221058unsigned int Image::computeRowWidthInBytes (int width,GLenum pixelFormat,GLenum type,int packing)
10231059{
1060+ // Handle block-compressed formats (S3TC, RGTC, BPTC, etc.)
1061+ // Prevents stride/pitch misalignment. Surprised this didn't come up sooner on the S3TC formats.
1062+ int blockSize = computeBlockSize (pixelFormat, 0 );
1063+ if (blockSize > 0 ) {
1064+ osg::Vec3i footprint = computeBlockFootprint (pixelFormat);
1065+ int blocksWide = (width + footprint.x () - 1 ) / footprint.x ();
1066+ unsigned int size = blockSize * blocksWide;
1067+ return roudUpToMultiple (size, packing);
1068+ }
1069+
1070+ // Non-compressed formats
10241071 unsigned int pixelSize = computePixelSizeInBits (pixelFormat,type);
10251072 int widthInBits = width*pixelSize;
10261073 int packingInBits = packing!=0 ? packing*8 : 8 ;
@@ -1822,6 +1869,14 @@ void Image::flipVertical()
18221869 return ;
18231870 }
18241871
1872+ // BPTC (BC6H/BC7) textures cannot be flipped in compressed form due to complex per-block encoding.
1873+ // Callers should check isBPTC() and set TOP_LEFT origin instead of calling flipVertical().
1874+ if (Image::isBPTC (_pixelFormat))
1875+ {
1876+ OSG_WARN << " Image::flipVertical(): BPTC (BC6H/BC7) textures cannot be flipped in compressed form." << std::endl;
1877+ return ;
1878+ }
1879+
18251880 unsigned int rowSize = getRowSizeInBytes ();
18261881 unsigned int rowStep = getRowStepInBytes ();
18271882
0 commit comments