Loading DXT compressed (dds) textures from memory [SOLVED]

Hi all

I need to load DXT compressed textures from archive container files into panda directly at runtime. I explicitly do not want to extract/convert prior but load them directly as they are on the users machine.

For the .bmp textures that I also need to process from the same container files this is easy:

ts = StringStream(texfile)  # turn into an istream
ti = PNMImage()             # create panda3d general purpose image object
ti.read(ts)                 # load from istream
                    
t = Texture()               # create texture object
t.load(ti)                  # load texture from pnmimage

but PNMImage does not support dds and I have not found any other way to do this yet. Any ideas?

Any help would be greatly appreciated!

Thanks and regards
Anorian

Time for the DUH moment I guess. RTFM (and if you dont find anything, read again … and again …) does it

I guess this is it.

ts = StringStream(texfile)  # turn into an istream
t = Texture()               # create texture object
t.readDds(ts)               # load texture from dds ram image

HOWEVER … it does not work :frowning:
The program can read the textures that way ( I have also verified the texures themselves to be ok by writing them all out to disk as .dds files: they load and display perfectly well in paint.net) but once Panda wants to render the scene I all I get is

:display:gsg:glgsg(error): GL texture creation failed for  : invalid enumerant
:display:gsg:glgsg(error): Could not load 

and the complete scene renders untextured sigh

Any ideas please?

Cheers

Perhaps the dds file uses some compression mode that isn’t supported by your graphics driver, or some such issue?

David

Hi David

Thanks for your reply!

The dds files are very straight forward, pretty old, DXT1 compressed textures. Headers all look pretty much like this

DDS_HEADER magic:DDS dwSize:124 dwFlags:0xa1007 dwWidth:256 dwHeight:256
dwPitchOrLinearSize:32768 dwDepth:0 dwMipMapCount:0
DDS_PIXELFORMAT dwSize:32 dwFlags:0x4 dwFourCC:DXT1 dwRGBBitCount:0
dwCaps:0x1000 dwCaps2:0x0 dwCaps3:0x0 dwCaps4:0x0

I read them directly from the archive files of the game I am writing this offline 3D viewer for, no conversion or else inbetween (and the game itself renders them fine, albeit its using DX not OGL).

I’ve also extracted a bunch of the textures from the archives and played around with them using the Nvidia dds tools etc, looked at mipmap levels (they dont have any) etc etc. Cant seem to find a cause for this problem so far.

Thanks!

Hmm, seems mysterious all right. What version of Panda are you using, what is your OS and your graphics card, and can you post one of your dds files so I can try it on my machine?

David

Hi

Stock Panda3D 1.7.2 SDK, Windows 7 home premium 64bit, plain nVidia GEFORCE GTX 560 Nvidia Driver version 8.17.13.142.

Can I attach a file to a pm? The textures are read from container files of a game. Even extracting them is probably an EULA violation :wink:, i.e I’d rather not post them publically.

Much appreciate your help!

Regards

Might also be worth trying with Panda3D 1.8. 1.7.2 is pretty old by now.

David

Downloading as I type …

Going to let you know how it goes

No luck. Exactly the same problem under Panda 1.8.0.

sigh

Regards

The sample DDS file you sent me seems to have an invalid header: it has the DDSD_MIPCOUNT flag set, indicating that NumLevels contains the number of mipmap levels in the file; but the value of NumLevels is 0, which would appear to mean it contains no actual data. Panda is interpreting this at face value, and creating a texture with no data, which is of course invalid.

It appears that other DDS readers on the net have a special case to treat NumLevels == 0 the same as NumLevels == 1 (which is no doubt what this texture author intended). I’ve just added this special case to Panda’s DDS reader as well; it will be picked up in the next buildbot release.

For your immediate needs, you can either get the next buildbot (or build Panda yourself), or you can hand-edit your DDS files to set NumLevels to 1 just for these problematic files. This is byte 28 (zero-based) in the file; you can simply change this byte directly to 1.

David

David

That did it! Wonderful. Thank you so much for all your help.

Best regards