Skip to content

Commit 2b7b5ef

Browse files
authored
Merge pull request #37 from kartoffels123/3.6
OSG side of BPTC support
2 parents 0812175 + 8b255c1 commit 2b7b5ef

File tree

5 files changed

+115
-5
lines changed

5 files changed

+115
-5
lines changed

include/osg/Image

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ class OSG_EXPORT Image : public BufferData
439439
void ensureValidSizeForTexturing(GLint maxTextureSize);
440440

441441
static bool isPackedType(GLenum type);
442+
static bool isBPTC(GLenum pixelFormat);
442443
static GLenum computePixelFormat(GLenum pixelFormat);
443444
static GLenum computeFormatDataType(GLenum pixelFormat);
444445

include/osg/Texture

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@
7575
#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
7676
#endif
7777

78+
#ifndef GL_ARB_texture_compression_bptc
79+
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
80+
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
81+
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
82+
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
83+
#endif
84+
7885
#ifndef GL_IMG_texture_compression_pvrtc
7986
#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
8087
#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01

src/osg/Image.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

339353
GLenum 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

10221058
unsigned 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

src/osg/Texture.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ InternalPixelRelations compressedInternalFormats[] = {
199199
, { GL_COMPRESSED_SIGNED_RED_RGTC1_EXT , GL_RED , GL_COMPRESSED_SIGNED_RED_RGTC1_EXT }
200200
// , { GL_COMPRESSED_RG_RGTC2 , GL_RG , GL_COMPRESSED_RG_RGTC2 }
201201
// , { GL_COMPRESSED_SIGNED_RG_RGTC2 , GL_RG , GL_COMPRESSED_SIGNED_RG_RGTC2 }
202-
// , { GL_COMPRESSED_RGBA_BPTC_UNORM , GL_RGBA , GL_COMPRESSED_RGBA_BPTC_UNORM }
203-
// , { GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM , GL_RGBA , GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM }
204-
// , { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT , GL_RGB , GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT }
205-
// , { GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT , GL_RGB , GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT }
202+
, { GL_COMPRESSED_RGBA_BPTC_UNORM , GL_RGBA , GL_COMPRESSED_RGBA_BPTC_UNORM }
203+
, { GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM , GL_RGBA , GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM }
204+
, { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT , GL_RGB , GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT }
205+
, { GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT , GL_RGB , GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT }
206206

207207
, { GL_COMPRESSED_RGB_S3TC_DXT1_EXT , GL_RGB , GL_COMPRESSED_RGB_S3TC_DXT1_EXT }
208208
, { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT , GL_RGBA , GL_COMPRESSED_RGBA_S3TC_DXT1_EXT }
@@ -377,6 +377,12 @@ void Texture::TextureProfile::computeSize()
377377
case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: numBitsPerTexel = 8; break;
378378
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: numBitsPerTexel = 8; break;
379379

380+
// BPTC (BC6H/BC7)
381+
case GL_COMPRESSED_RGBA_BPTC_UNORM: numBitsPerTexel = 8; break;
382+
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: numBitsPerTexel = 8; break;
383+
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: numBitsPerTexel = 8; break;
384+
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: numBitsPerTexel = 8; break;
385+
380386
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: numBitsPerTexel = 2; break;
381387
case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: numBitsPerTexel = 2; break;
382388
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: numBitsPerTexel = 4; break;
@@ -1898,6 +1904,11 @@ bool Texture::isCompressedInternalFormat(GLint internalFormat)
18981904
case (GL_COMPRESSED_RED_RGTC1_EXT):
18991905
case (GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT):
19001906
case (GL_COMPRESSED_RED_GREEN_RGTC2_EXT):
1907+
// BPTC (BC6H/BC7)
1908+
case (GL_COMPRESSED_RGBA_BPTC_UNORM):
1909+
case (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM):
1910+
case (GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT):
1911+
case (GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT):
19011912
case (GL_ETC1_RGB8_OES):
19021913
case (GL_COMPRESSED_RGB8_ETC2):
19031914
case (GL_COMPRESSED_SRGB8_ETC2):
@@ -1969,6 +1980,9 @@ void Texture::getCompressedSize(GLenum internalFormat, GLint width, GLint height
19691980
blockSize = 8;
19701981
else if (internalFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT || internalFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT)
19711982
blockSize = 16;
1983+
// BPTC (BC6H/BC7) - 128 bits per block
1984+
else if (internalFormat == GL_COMPRESSED_RGBA_BPTC_UNORM || internalFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM || internalFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT || internalFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
1985+
blockSize = 16;
19721986
else if (internalFormat == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG || internalFormat == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG)
19731987
{
19741988
blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
@@ -2397,6 +2411,11 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
23972411
case(GL_COMPRESSED_SIGNED_RG11_EAC):
23982412
case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
23992413
case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: _internalFormat = GL_RG; break;
2414+
// BPTC (BC6H/BC7)
2415+
case GL_COMPRESSED_RGBA_BPTC_UNORM:
2416+
case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: _internalFormat = GL_RGBA; break;
2417+
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
2418+
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: _internalFormat = GL_RGB; break;
24002419
}
24012420
}
24022421

src/osgPlugins/dds/ReaderWriterDDS.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,30 @@ osg::Image* ReadDDSFile(std::istream& _istream, bool flipDDSRead)
814814
pixelFormat = GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
815815
break;
816816

817+
case OSG_DXGI_FORMAT_BC6H_UF16:
818+
internalFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
819+
pixelFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
820+
packing = 4; // 8 bits/pixel. 4 px = 4 bytes
821+
break;
822+
823+
case OSG_DXGI_FORMAT_BC6H_SF16:
824+
internalFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
825+
pixelFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
826+
packing = 4; // 8 bits/pixel. 4 px = 4 bytes
827+
break;
828+
829+
case OSG_DXGI_FORMAT_BC7_UNORM:
830+
internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM;
831+
pixelFormat = GL_COMPRESSED_RGBA_BPTC_UNORM;
832+
packing = 4; // 8 bits/pixel. 4 px = 4 bytes
833+
break;
834+
835+
case OSG_DXGI_FORMAT_BC7_UNORM_SRGB:
836+
internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
837+
pixelFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
838+
packing = 4; // 8 bits/pixel. 4 px = 4 bytes
839+
break;
840+
817841
default:
818842
OSG_WARN << "ReadDDSFile warning: unhandled DX10 pixel format 0x"
819843
<< std::hex << std::setw(8) << std::setfill('0')
@@ -1100,7 +1124,11 @@ osg::Image* ReadDDSFile(std::istream& _istream, bool flipDDSRead)
11001124

11011125
if (mipmap_offsets.size()>0) osgImage->setMipmapLevels(mipmap_offsets);
11021126

1103-
if (flipDDSRead) {
1127+
osgImage->setOrigin(osg::Image::TOP_LEFT);
1128+
1129+
// BPTC (BC6H/BC7) textures cannot be flipped in compressed form
1130+
if (flipDDSRead && !osg::Image::isBPTC(internalFormat))
1131+
{
11041132
osgImage->setOrigin(osg::Image::BOTTOM_LEFT);
11051133
if (!isDXTC || ((s>4 && s%4==0 && t>4 && t%4==0) || s<=4)) // Flip may crash (access violation) or fail for non %4 dimensions (except for s<4). Tested with revision trunk 2013-02-22.
11061134
{

0 commit comments

Comments
 (0)