7
votes

I need to serialise an arbitrary OpenGL texture object to be able to restore it later with the exact same state and data.

I'm looking for a way to get the texture image data. Here's what I've found so far:

  • There's glGetTexImage.

    It allows to gets the texture image, but it requires a specified format/type pair (like (GL_RGBGL_HALF_FLOAT) to which it performs a conversion.

    The allowed formats and types don't map 1:1 to image formats though, and won't allow to get more obscure formats like GL_R3_G3_B2 without additional conversion.

    Also correctly determining the C type for base internal formats (like GL_RGB with no size) involves some non-trivial labour.

  • There's ARB_internalformat_query2 that allows to ask for GL_GET_TEXTURE_IMAGE_FORMAT and GL_GET_TEXTURE_IMAGE_TYPE which represent the best choices for glGetTexImage for a given texture.

    Nice, but suffers from the same limitations as glGetTexImage and isn't widely available.

  • There's the wonderful glGetCompressedTexImage that elegantly returns the compressed texture's data as-is, but it neither works for non-compressed images nor has a counterpart that would.

None of these allows to get or set raw data for non-compressed textures. Is there a way?

1

1 Answers

2
votes

The trick is, to find matches of format and type the yield the right data layout.

The allowed formats and types don't map 1:1 to image formats though, and won't allow to get more obscure formats like GL_R3_G3_B2 without additional conversion.

That would be GL_RGB, GL_UNSIGNED_BYTE_3_3_2

Also correctly determining the C type for base internal formats (like GL_RGB with no size) involves some non-trivial labour.

Yes it does. *puts on sunglasses* Deal with it! ;)

As for the internal format. I hereby refer you to

glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_INTERNAL_FORMAT,…);
glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_{RED,GREEN,BLUE,ALPHA,DEPTH}_TYPE, …);
glGetTexLevelParameter(GL_TEXTURE_…, …, GL_TEXTURE_{RED,GREEN,BLUE,ALPHA,DEPTH}_SIZE, …);