<p>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.</p>

<p>OpenGL ES <em>does not</em>. Indeed, it is so serious about not allowing this that it actually changes the <em>meaning</em> of the parameters to functions like <code>glTexImage*d</code>. 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.</p>

<p>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 <code>glTexSubImage*d</code> or <code>glGetTexImage</code>, you <em>must</em> provide pixel transfer parameters that match those you provided to the <code>glTexImage*d</code> call.</p>

<p>So OpenGL ES doesn't allow any of that pixel conversion stuff.</p>

CC BY-SA 3.0
2018-01-17T06:11:32.500Z
2018-01-17T06:11:32.500Z
Nicol Bolas
<p>The commentary in this thread is correct. OpenGL ES does not have built in support for reading textures directly.</p>

<p>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.)</p>

<p>As reference for people stumbling upon this with the same problem, <a href="https://stackoverflow.com/a/11947751">this answer to a different, but similar question</a> gives steps for doing the above. </p>

CC BY-SA 3.0
2018-01-17T22:36:16.387Z
2018-01-17T22:36:16.387Z
knowledgeinchaos
<p>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. </p>

<p>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.</p>

<p>Thanks!</p>

CC BY-SA 3.0
2018-01-17T02:10:36.773Z
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.
PaulHK
CC BY-SA 3.0
2018-01-17T06:12:04.833Z
Why can you not simply have compressed and uncompressed versions of the images on disk?
Nicol Bolas
CC BY-SA 3.0
2018-01-17T09:44:07.407Z
@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.
Dan Hulme
CC BY-SA 3.0
2018-01-17T09:55:55.993Z
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.
Simon F
<opengl-es><compression>
Loading compressed image to GPU and reading back decompressed on CPU
knowledgeinchaos
# Loading compressed image to GPU and reading back decompressed on CPU

(Asked by: username_0 on 2018-01-17)

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.

Thanks!

**Tags:** opengl-es, compression

> **Comments:**
> **username_1**: 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.  
> **username_2**: Why can you not simply have compressed and uncompressed versions of the images on disk?  
> **username_3**: @username_2 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.  
> **username_4**: 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.  

---

## 2 answers

### Answer by username_2 on 2018-01-17. Score: 3

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.


---

### Answer by username_0 on 2018-01-17. Score: 0

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 "username_4 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](https://stackoverflow.com/a/11947751) gives steps for doing the above.


---

