I need ‘compressed texture’ in our project.
I try for DXT1~5, ASTC and get some result.
then now i want try BPTC format(BC7), but i cant find BC7 loader anyware!
I get BC7 texture with Compressonator, I open it for vs2019, format is DXGI_FORMAT_BC7_UNORM.
it’s not same to GL_COMPRESSED_RGBA_BPTC_UNORM ?
I have DXT loader, but it’s not work with BC7. result is so…crazy.
left is original, right is BC7.
lower is my DDS file loader.
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
#define FOURCC_BPTC 0x30315844
float loadDDS(const char * imagepath) {
unsigned char header[124];
FILE *fp;
/* try to open the file */
fp = fopen(imagepath, "rb");
if (fp == NULL) {
printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar();
return 0;
}
/* verify the type of file */
char filecode[4];
fread(filecode, 1, 4, fp);
if (strncmp(filecode, "DDS ", 4) != 0) {
fclose(fp);
return 0;
}
/* get the surface desc */
fread(&header, 124, 1, fp);
unsigned int height = *(unsigned int*)&(header[8]);
unsigned int width = *(unsigned int*)&(header[12]);
unsigned int linearSize = *(unsigned int*)&(header[16]);
unsigned int mipMapCount = *(unsigned int*)&(header[24]);
unsigned int fourCC = *(unsigned int*)&(header[80]);
unsigned char * buffer;
unsigned int bufsize;
if (fourCC == FOURCC_BPTC) {//in BC7 header, linearSize is small(8192), width/height is 2048.
linearSize = height * width;
bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
fread(buffer, 1, bufsize, fp);
}
else {
/* how big is it going to be including all mipmaps? */
bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
fread(buffer, 1, bufsize, fp);
}
/* close the file pointer */
fclose(fp);
unsigned int components = (fourCC == FOURCC_DXT1) ? 3 : 4;
unsigned int format;
switch (fourCC)
{
case FOURCC_DXT1:
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
break;
case FOURCC_DXT3:
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case FOURCC_DXT5:
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case FOURCC_BPTC:
format = GL_COMPRESSED_RGBA_BPTC_UNORM;
//format = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
//format = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
//format = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
break;
default:
free(buffer);
return 0;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
unsigned int offset = 0;
float compute_time;
glFinish();
CHECK_TIME_START;
/* load the mipmaps */
for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
{
unsigned int size = ((width + 3) / 4)*((height + 3) / 4)*blockSize;
glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, size, buffer + offset);
offset += size;
width /= 2;
height /= 2;
// Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
if (width < 1) width = 1;
if (height < 1) height = 1;
}
glFinish();
CHECK_TIME_END(compute_time);
free(buffer);
return compute_time;
}
please help me!