I have two problem which are related to loading DDS files as textures.
First, DDS is a DirectX format whose image origin is top-left. When trying to upload such an image into OpenGL, the image is flipped. Can anything be done about that whitout touching the texture coordinates? Is it possible to vertically “flip” the DXTC image data in compressed form?
Second problem is when trying to use NPOT+DXTC. The s3tc specs say:
How does this extension interact with specific texture compression
extensions such as EXT_texture_compression_s3tc?
STATUS: RESOLVED
RESOLUTION: It does not. If both this extension and
EXT_texture_compression_s3tc are supported, applications can safely
load NPOT S3TC-compressed textures.
But when trying to actually make use of this, I get GL errors. I have to make the textures power-of-two first. Has anyone experienced the same?
I don’t know well the dds format, but did you try to flip vertically your picture data array? I mean maybe you could copy data in a new array reading the first from bottom to top…
http://en.wikipedia.org/wiki/S3TC
It’s blocks of 4x4 pixels, each block having a color-data “header”.
You’ll need to flip all rows of blocks, and also flip that table in each block.
Here’s how I think you’ll swap DXT1:
void DXT1_SwapVertically(int* data,int wid=256,int hei=128){
int rowsize=wid*2; // in dwords
int *ptr1=data; // first row
int *ptr2=data+(rowsize*(hei-1)); // last row
for(int y=hei/8;y--;){ // this loop flips blocks vertically
for(int x=rowsize;x--;){
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
ptr1++;
ptr2++;
}
ptr2-=2*rowsize;
}
#define DXT_IS_COLOR_FIRST 1 // I am not sure which it is
#if DXT_IS_COLOR_FIRST
char* ptr3=(char*)(data+1);
#else
char* ptr3=(char*)data;
#endif
for(int b=hei*rowsize;b--;){ // for each block
// this whole thing can be done easily with "bswap" in inline asm
char temp2;
temp2 = ptr3[0];
ptr3[0]=ptr3[3];
ptr3[3]=temp;
temp2 = ptr3[1];
ptr3[1]=ptr3[2];
ptr3[2]=temp;
ptr3+=8;
}
}
Actually you should not have to flip at all. While OpenGL defines the texture origin as bottom-left (which is a rather meaningless statement for texture space as it has no orientation), it also defines that texture data is uploaded in bottom-to-top order.
EXT_texture_compression_s3tc also defines the block and texel positions this way, so that the first block (the one at the lowest address in memory) is always at the origin of texture space.
Ok, I tried to flip the DXTC data line by line(leaving the blocks itself intact). This didn’t help completely…it really seems I have to flip the blocks internally, too.
There’s some code included in the NV SDK to flip DXT compressed images without de- & re-compressing them. If you just want the relevant snippets (nv_dds.cpp):
There’s some code included in the NV SDK to flip DXT compressed images without de- & re-compressing them. If you just want the relevant snippets (nv_dds.cpp)
Update: I got vertical flipping and uploading NPOT-DTXn-Textures working.
When uploading NPOT-DXTn data, you need to calculate the imageSize parameter of glCompressedTexImage2DARB as if you would round both ‘width’ and ‘height’ up to the next divisible-by-4 values. The same is true to get from one mipmap-image to the next inside the DDS file.