I have some images that I know will be stored with either PVR or ETC compression. I would like to be able to convert these images into uncompressed RGB. However, because of binary size constraints, I would like to do so without adding a dedicated library for the conversion.

Does there exist any ways to do this? I know functions like glCompressedTexImage2D will let me load the compressed image to GPU. However, I'm having issues reading the decoded version out. For extra context, I am trying to do this with OpenGL ES 2.0.


  • 2
    $\begingroup$ Textures should be stored on GPU VRAM in their compressed form, AFAIK they are decompressed by texture samplers at rendering time rather than at load time, as that would defeat the purpose of compression if you were to unpack them to VRAM. You should do something like render the texture via a quad into an RGB buffer if you want the decompressed version. $\endgroup$ – PaulHK Jan 17 '18 at 2:10
  • $\begingroup$ Why can you not simply have compressed and uncompressed versions of the images on disk? $\endgroup$ – Nicol Bolas Jan 17 '18 at 6:12
  • $\begingroup$ @NicolBolas My guess is it's a demo-scene program where the total size of assets and program is limited and the questioner is trying to push the limit. $\endgroup$ – Dan Hulme Jan 17 '18 at 9:44
  • $\begingroup$ If you really want the decompressed texels, why not render a 1:1 quad with the texture on it and read back the resulting pixels in the framebuffer. $\endgroup$ – Simon F Jan 17 '18 at 9:55

Desktop OpenGL requires implementations to convert pixel data between the internal format of the image and the format you specify in the pixel transfer command.

OpenGL ES does not. Indeed, it is so serious about not allowing this that it actually changes the meaning of the parameters to functions like glTexImage*d. In ES, you cannot use sized internal formats (well, outside of texture storage calls). Instead, the internal format is kinda there. What really defines the internal format is the pixel format and type parameters.

That is, when you tell OpenGL ES that the pixel data you're providing looks like X, it requires the implementation to create a texture whose real internal format exactly matches that. And if you're using glTexSubImage*d or glGetTexImage, you must provide pixel transfer parameters that match those you provided to the glTexImage*d call.

So OpenGL ES doesn't allow any of that pixel conversion stuff.

| improve this answer | |

The commentary in this thread is correct. OpenGL ES does not have built in support for reading textures directly.

Best option it seems, given stated constraints, is to draw the compressed texture to a quad then read it back out. (Same as suggested by "Simon F" in the question comment thread above.)

As reference for people stumbling upon this with the same problem, this answer to a different, but similar question gives steps for doing the above.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.