Texture pre-compression, is data vendor dependent?

Started by
6 comments, last by theagentd 10 years, 4 months ago

If I compress a texture, retrieve the compressed data using glGetCompressedTexImage2D() and store it in a file, will the resulting data be compatible with all OpenGL implementations? Or is the compressed data only compatible with the GPU/driver/vendor it was compressed on?

Advertisement

If I compress a texture, retrieve the compressed data using glGetCompressedTexImage2D() and store it in a file, will the resulting data be compatible with all OpenGL implementations? Or is the compressed data only compatible with the GPU/driver/vendor it was compressed on?

It will be compatible with any GL implementation which supports that particular compression format. This is assuming the texture is actually compressed in the format you think it is. GL implementations are free to convert the texture into an alternate format, so it is necessary to actually query whether or not the texture is compressed and in what format.

Awesome! Okay, I'll be careful! =D

EDIT: Followup question! Let's say I compress my texture using a specific compression format. I'm planning on using the following formats:

- GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT (OGL 3)

- GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM (OGL 4)

- GL_COMPRESSED_RG_RGTC2 (normal maps)

From what I understand, the implementation is free to ignore these and compress the data in some other format, or possibly even leave the data uncompressed. What would happen if I were to load data precompressed in a format that the current implementation would ignore? Would the implementation re/decompress the data into a supported format? The data is meant to be streamed in using a separate OpenGL context which works fine for uncompressed textures, but on-the-fly compression turned out to be ridiculously slow. I'm afraid that the streaming will completely break playability on some implementations.

The game is limited to OGL3+. I'd be happy enough if I knew that these specific formats are supported by Nvidia, AMD and possibly Intel to some extent.

EDIT2: My Nvidia GTX 770 driver reports that the supplied internal formats are being used.

EDIT3: Another question...

To avoid having to use several megabytes of VRAM, I've started streaming my texture to OpenGL in parts. Basically I allocate a small PBO, say a megabyte, and then in a loop upload a number of rows of pixels into this buffer depending on the format and resolution of the texture. This is to avoid needing a huge PBO to store the complete texture (uncompressed 4096x4096 textures were 64MBs). With uncompressed textures, it was easy to break up the texture into multiple parts. From what I can tell, all the above 3 formats compress data into 4x4 blocks. The question is how the compressed data is formatted. If I have a compressed 512x512 texture, can I just split up its data buffer into 128 equal parts and load these 512x4 strips using glCompressedTexSubImage2D()?

RGTC is core in GL since version 3.0 and BPTC since version 4.2. If your implementation supplies contexts with those version or higher then it needs to be able to handle loading those formats. If the hardware doesn't directly support it, then the driver will need to reformat the texture data. S3TC will probably never be supported by core, but as an extension it is very well supported. If you want to know what the layout of the data is in a compressed texture, you should take a look at how they are implemented. S3TC, RGTC and BPTC correspond to BC1/BC2/BC3 BC4/BC5 and BC6H/BC7 respectively. When using glCompressedTexSubImage on one of these formats you will want to stick to the 4x4 boundaries.

Sounds good. I'll get to it!

There is generally no good reason to call glGetCompressedTexImage2D() and store the results in a file. There are offline tools to convert images files to all major compressed texture formats.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

There is generally no good reason to call glGetCompressedTexImage2D() and store the results in a file. There are offline tools to convert images files to all major compressed texture formats.

^^in addition, when writing an algorithm to compress data into these formats, there is a quality vs time trade-off.
When you ask the driver to compress a texture, I would guess that it will use the fastest possible algorithm for performance reasons, instead of blocking for 2 minutes to get the highest quality results.
If you use an offline tool instead I your video driver, you can gain control over the quality.

Hmm, that makes sense. I'm currently using a custom file format for storing all mipmap levels of a texture. It's simply a header with the size and byte offsets of each mipmap and then each mipmap's data sequentially. I'd prefer to keep using a custom format, and since I'm using Java for both the game and the custom format texture conversion tool, glGetCompressedTexImage2D() is an extremely simple cross-platform way of generating mipmaps (our artists are on Macs for example). Unless there is some smooth way of implementing this I'll probably stick to OpenGL driver compression for simplicity.

This topic is closed to new replies.

Advertisement