<p>OK, when you call the regular <code>SubImage</code> functions, you are passing pixel data. You are <a href="https://www.khronos.org/opengl/wiki/Pixel_Transfer" rel="nofollow noreferrer">provoking a pixel unpack operation</a>, where the implementation will read the pixels from your data in the format specified and convert them to the internal format of the image.</p>

<p>However, if already have compressed data, you don't <em>want</em> that conversion. You just want to pass the compressed data to the GL, and have it use it directly. That's what the <code>Compressed</code> functions are for.</p>

<p>If you want to compress uncompressed data, you use the non-<code>Compressed</code> functions. But you really, <em>really</em>, shouldn't. Indeed, with ASTC, you <em>can't</em> compress the data online. And even for other formats, the quality of the result will be rather sketchy.</p>

<p>Do you really want to rely on the quality of a compression algorithm written to be fast rather than <em>good</em>?</p>

<p>The <a href="https://www.khronos.org/opengl/wiki/Pixel_Transfer_Format" rel="nofollow noreferrer"><code>format</code></a> and <a href="https://www.khronos.org/opengl/wiki/Pixel_Transfer_Type" rel="nofollow noreferrer"><code>type</code></a> transfer parameters describe a single pixel's worth of data, and compressed formats don't generally store data in units of "pixels". Compressed formats usually use blocks of some size. Regular pixel transfers expect a 1:1 correspondence between a pixel in your data and a pixel in the GL-owned image. That simply isn't the case when dealing with compressed data.</p>

<p>So you need a new function, which just takes a block of bits of a known size, whose format is defined by the image's format, and jams it into the image.</p>

<p>The reason why you can't use a generic compressed format with the <code>Compressed</code> transfer functions should be obvious by now. These functions are for providing compressed data in a specific format; <em>by definition</em>, the generic formats are implementation defined. So there's no way you could possibly know what data to provide for generic compressed transfers.</p>

CC BY-SA 3.0
2018-01-15T18:19:49.380Z
Was hoping to hear from you! Fantastic answer. Regarding your warning: If I am making an application where a user can upload images (.jpgs) -  if I want to store them compressed I really have no choice but to compress the data "online" right? (I mean other than converting each uploaded image "offline" then reading it back)?
Startec
CC BY-SA 3.0
2018-01-15T18:22:03.633Z
Furthermore, I read somewhere that OpenGL is going away from the generic `GL_COMPRESSED*` formats. Is there any situation where they are useful / a good idea?
Startec
CC BY-SA 3.0
2018-01-15T18:28:53.160Z
@Startec: What do you mean by "going away from"? It's a part of the specification. And since it wasn't removed in 3.1, the only way to "go away from" it would be to remove it in a newer version of the spec. And that's pretty much not gonna happen. As for when to use it? Pretty much never.
Nicol Bolas
CC BY-SA 3.0
2018-01-15T18:32:46.723Z
By that I meant: Is a more preferred way  to use non-generic formats? It so it sounds like it. I read this somewhere, although I can't find where. So where can a generic compressed type even legally be used?
Startec
CC BY-SA 3.0
2018-01-15T18:34:21.047Z
@Startec: They were never considered a good way to get compressed images, so the status quo hasn't changed. As for where they can be legally used, the standard spells that out adequately. They're internal formats, so they can be used in most places that take internal formats.
Nicol Bolas
CC BY-SA 3.0
2018-01-15T18:02:36.753Z
2018-01-15T18:02:36.753Z
Nicol Bolas
<p>When using an array texture I can call:</p>

<pre><code>glTextureStorage3D(m_texture_array, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, m_num_billboards);
for (int i{}; i &lt; 4; ==i) {
    glTextureSubImage3D(m_texture_array, 0, 0, 0, i, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
}
</code></pre>

<p>Which results in a compressed image. So when do I need to use <code>glCompressedTextureSubImage3D</code> ?</p>

<p>Furthermore, <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml" rel="nofollow noreferrer">the docs</a> say:</p>

<blockquote>
  <p>internalformat must be a known compressed image format (such as GL_RGTC) or an extension-specified compressed-texture format</p>
</blockquote>

<p>Why can't it be a generic format?</p>

<opengl><texture>
glCompressedTextureSubImage3D Usage
Startec
# glCompressedTextureSubImage3D Usage

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

When using an array texture I can call:

```
glTextureStorage3D(m_texture_array, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, m_num_billboards);
for (int i{}; i < 4; ==i) {
    glTextureSubImage3D(m_texture_array, 0, 0, 0, i, width, height, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
}

```

Which results in a compressed image. So when do I need to use `glCompressedTextureSubImage3D` ?

Furthermore, [the docs](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompressedTexSubImage3D.xhtml) say:

> internalformat must be a known compressed image format (such as GL\_RGTC) or an extension-specified compressed-texture format

Why can't it be a generic format?

**Tags:** opengl, texture


---

## 1 answers

### Answer by username_1 on 2018-01-15. Score: 2 | Accepted answer

OK, when you call the regular `SubImage` functions, you are passing pixel data. You are [provoking a pixel unpack operation](https://www.khronos.org/opengl/wiki/Pixel_Transfer), where the implementation will read the pixels from your data in the format specified and convert them to the internal format of the image.

However, if already have compressed data, you don't *want* that conversion. You just want to pass the compressed data to the GL, and have it use it directly. That's what the `Compressed` functions are for.

If you want to compress uncompressed data, you use the non-`Compressed` functions. But you really, *really*, shouldn't. Indeed, with ASTC, you *can't* compress the data online. And even for other formats, the quality of the result will be rather sketchy.

Do you really want to rely on the quality of a compression algorithm written to be fast rather than *good*?

The [`format`](https://www.khronos.org/opengl/wiki/Pixel_Transfer_Format) and [`type`](https://www.khronos.org/opengl/wiki/Pixel_Transfer_Type) transfer parameters describe a single pixel's worth of data, and compressed formats don't generally store data in units of "pixels". Compressed formats usually use blocks of some size. Regular pixel transfers expect a 1:1 correspondence between a pixel in your data and a pixel in the GL-owned image. That simply isn't the case when dealing with compressed data.

So you need a new function, which just takes a block of bits of a known size, whose format is defined by the image's format, and jams it into the image.

The reason why you can't use a generic compressed format with the `Compressed` transfer functions should be obvious by now. These functions are for providing compressed data in a specific format; *by definition*, the generic formats are implementation defined. So there's no way you could possibly know what data to provide for generic compressed transfers.

> **Comments:**
> **username_0**: Was hoping to hear from you! Fantastic answer. Regarding your warning: If I am making an application where a user can upload images (.jpgs) -  if I want to store them compressed I really have no choice but to compress the data "online" right? (I mean other than converting each uploaded image "offline" then reading it back)?  
> **username_0**: Furthermore, I read somewhere that OpenGL is going away from the generic `GL_COMPRESSED*` formats. Is there any situation where they are useful / a good idea?  
> **username_1**: @username_0: What do you mean by "going away from"? It's a part of the specification. And since it wasn't removed in 3.1, the only way to "go away from" it would be to remove it in a newer version of the spec. And that's pretty much not gonna happen. As for when to use it? Pretty much never.  
> **username_0**: By that I meant: Is a more preferred way  to use non-generic formats? It so it sounds like it. I read this somewhere, although I can't find where. So where can a generic compressed type even legally be used?  
> **username_1**: @username_0: They were never considered a good way to get compressed images, so the status quo hasn't changed. As for where they can be legally used, the standard spells that out adequately. They're internal formats, so they can be used in most places that take internal formats.  

---

