PDA

View Full Version : DXTC image uploading issues



skynet
05-29-2008, 12:18 PM
Hello,

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:

10. 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?

dletozeun
05-29-2008, 12:30 PM
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...

Ilian Dinev
05-29-2008, 02:52 PM
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;
}

}

Ilian Dinev
05-30-2008, 12:17 AM
Ah, some errata:
for(int b=hei*rowsize;b--;){ // for each block
should be replaced with
for(int b=wid*hei/16;b--;){ // for each block

Hampel
05-30-2008, 01:43 AM
better use the texture matrix for flipping, something like this should do the trick:
1 0 0 0
0 -1 0 1
0 0 1 0
0 0 0 1

Xmas
05-30-2008, 03:18 AM
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.

skynet
05-30-2008, 06:57 AM
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.

remdul
05-30-2008, 08:08 AM
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):

http://www.google.com/search?hl=en&q=nv_dds.cpp&btnG=Google+Search

Make sure you have the latest (beta) drivers, there was a bug in the 169.21 ForceWare drivers that corrupted DXT1 mipmaps, and possibly other issues.

http://www.opengl.org/discussion_boards/...true#Post236337 (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Board=3&Number=236337&Searchpage=4&Main=46550&Words=dxt3+dxt5+bug&topic=0&Search=true#Post236337)

skynet
05-30-2008, 09:25 AM
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)

Thanks, this is exactly what I needed.

skynet
05-30-2008, 11:32 AM
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.

tamlin
05-31-2008, 01:00 PM
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.

And this surprises you? DXTn works (only!) on 4x4 blocks.

You might want to have a look at
http://msdn.microsoft.com/en-us/library/bb206238(VS.85).aspx