<p>I have now replaced it with the following, which works:</p>

<pre><code>GLuint textureHandle;
glCreateTextures(GL_TEXTURE_2D, 1, &amp;textureHandle);
glTextureStorage2D(textureHandle, 1, GL_RGBA8, imageW, imageH);
glTextureSubImage2D(textureHandle, 0, 0, 0, imageW, imageH, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTextureParameteri(textureHandle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTextureUnit(0, textureHandle);
</code></pre>

CC BY-SA 3.0
2017-01-07T16:03:04.000Z
2017-01-07T16:03:04.000Z
LinAGKar
<p>Just to show a 1:1 comparison to help people easily understand the new functions:<br />
<code>1). create 2). bind 3). allocate 4). upload</code></p>
<pre><code>1: glGenTextures(1,&amp;tex);
2: glBindTexture(GL_TEXTURE_2D,tex);
3: glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w,h, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
4: glTexSubImage2D(GL_TEXTURE_2D, level, x,y,w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);
</code></pre>
<hr />
<pre><code>1: glCreateTextures(GL_TEXTURE_2D,1,&amp;tex);
2: // glBindTextureUnit(unit, tex);
3: glTextureStorage2D(tex, levels, GL_RGBA8, w,h);
4: glTextureSubImage2D(tex, level, x,y,w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);
</code></pre>
<p>Much cleaner. We don't need to bind. We just allocate our texture levels, then upload to them.</p>
<p>Also with <code>glBindTextureUnit</code> we don't need <code>glActiveTexture</code>.<br />
And the equivalent of <code>glTextureStorage2D</code> in the old code would actually be:</p>
<pre><code>for(int i=0; i&lt;levels; i++) glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, max(1,w&gt;&gt;i),max(1,h&gt;&gt;i), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
</code></pre>
<p>Of course you'd still need such a loop if you are uploading different levels manually.</p>
<p>Also here's some other dsa texture functions to use instead:<br />
<code>glTextureParameteri</code> and <code>glGenerateTextureMipmap</code></p>

CC BY-SA 4.0
2022-01-16T06:40:03.123Z
2022-01-16T06:40:03.123Z
Puddle
<p>You still have to bind the desired texture to the texture unit to use it for rendering. In your current code, you're not specifying which texture to use for rendering, so the GL driver doesn't know which one you want to use and is defaulting to "no texture".</p>

<p>There are a few ways to bind a texture. You can keep using <code>glActiveTexture</code>+<code>glBindTexture</code> as in your non-DSA code, or you can use either <a href="http://docs.gl/gl4/glBindTextures" rel="noreferrer"><code>glBindTextures</code></a> or <a href="http://docs.gl/gl4/glBindTextureUnit" rel="noreferrer"><code>glBindTextureUnit</code></a>.</p>

<p>For example, with <code>glBindTextureUnit</code>, do this:</p>

<pre><code>glBindTextureUnit(0, textureHandle);
</code></pre>

<p>The first parameter is the texture unit to bind to.</p>

<p>By the way, instead of using <code>glTextureImage2DEXT</code> (which is from the old and deprecated EXT_direct_state_access extension), it's probably better to stick with core OpenGL calls. You can initialize the texture by using <a href="http://docs.gl/gl4/glTexStorage2D" rel="noreferrer"><code>glTextureStorage2D</code></a> to allocate the memory and set the format, then <a href="http://docs.gl/gl4/glTexSubImage2D" rel="noreferrer"><code>glTextureSubImage2D</code></a> to upload the data.</p>

<p>(<a href="https://www.khronos.org/opengl/wiki/Direct_State_Access#Changes_from_EXT" rel="noreferrer">Here's an article with more on the differences</a> between EXT_direct_state_access and the newer core version of the functionality, if you're interested.)</p>

CC BY-SA 3.0
2017-01-06T01:11:18.870Z
"*You might want to convert your code to use that if possible*" His code *is using that*. `glCreateTextures` is specific to the ARB_DSA function. He's using an odd mixture of the two, likely because he couldn't find a `glTextureImage2D` in the ARB version (since the ARB wants to discourage non-immutable textures).
Nicol Bolas
CC BY-SA 3.0
2017-01-06T03:12:37.617Z
@NicolBolas Aha, thanks, I hadn't caught that. I've updated the answer again.
Nathan Reed
CC BY-SA 4.0
2022-12-30T15:25:09.000Z
hey please help, can i use gltexturesubimage2d without using gltexturestorage2d? because i need to re set data with different width and heights
ihsan
CC BY-SA 4.0
2022-12-30T23:21:17.887Z
@ihsan You can use `glTexImage2D` in that case.
Nathan Reed
CC BY-SA 3.0
2017-01-05T22:42:40.700Z
2017-01-06T03:12:18.397Z
2017-01-06T03:12:18.397Z
Nathan Reed
<p>How do you use textures with direct state access in OpenGL?</p>

<p>I have the following in my code, which seems to work:</p>

<pre><code>GLuint textureHandle;
glGenTextures(1, &amp;textureHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
</code></pre>

<p>However, when I replace it with the following everything just becomes black:</p>

<pre><code>GLuint textureHandle;
glActiveTexture(GL_TEXTURE0);
glCreateTextures(GL_TEXTURE_2D, 1, &amp;textureHandle);
glTextureImage2DEXT(textureHandle, GL_TEXTURE_2D, 0, GL_RGBA8, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTextureParameteri(textureHandle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
</code></pre>

<opengl><texture>
How to do texturing with OpenGL direct state access?
LinAGKar
# How to do texturing with OpenGL direct state access?

(Asked by: username_0 on 2017-01-05)

How do you use textures with direct state access in OpenGL?

I have the following in my code, which seems to work:

```
GLuint textureHandle;
glGenTextures(1, &textureHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

```

However, when I replace it with the following everything just becomes black:

```
GLuint textureHandle;
glActiveTexture(GL_TEXTURE0);
glCreateTextures(GL_TEXTURE_2D, 1, &textureHandle);
glTextureImage2DEXT(textureHandle, GL_TEXTURE_2D, 0, GL_RGBA8, imageW, imageH, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTextureParameteri(textureHandle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

```

**Tags:** opengl, texture


---

## 3 answers

### Answer by username_2 on 2017-01-05. Score: 12 | Accepted answer

You still have to bind the desired texture to the texture unit to use it for rendering. In your current code, you're not specifying which texture to use for rendering, so the GL driver doesn't know which one you want to use and is defaulting to "no texture".

There are a few ways to bind a texture. You can keep using `glActiveTexture`+`glBindTexture` as in your non-DSA code, or you can use either [`glBindTextures`](http://docs.gl/gl4/glBindTextures) or [`glBindTextureUnit`](http://docs.gl/gl4/glBindTextureUnit).

For example, with `glBindTextureUnit`, do this:

```
glBindTextureUnit(0, textureHandle);

```

The first parameter is the texture unit to bind to.

By the way, instead of using `glTextureImage2DEXT` (which is from the old and deprecated EXT\_direct\_state\_access extension), it's probably better to stick with core OpenGL calls. You can initialize the texture by using [`glTextureStorage2D`](http://docs.gl/gl4/glTexStorage2D) to allocate the memory and set the format, then [`glTextureSubImage2D`](http://docs.gl/gl4/glTexSubImage2D) to upload the data.

([Here's an article with more on the differences](https://www.khronos.org/opengl/wiki/Direct_State_Access#Changes_from_EXT) between EXT\_direct\_state\_access and the newer core version of the functionality, if you're interested.)

> **Comments:**
> **username_3**: "*You might want to convert your code to use that if possible*" His code *is using that*. `glCreateTextures` is specific to the ARB_DSA function. He's using an odd mixture of the two, likely because he couldn't find a `glTextureImage2D` in the ARB version (since the ARB wants to discourage non-immutable textures).  
> **username_2**: @username_3 Aha, thanks, I hadn't caught that. I've updated the answer again.  
> **username_4**: hey please help, can i use gltexturesubimage2d without using gltexturestorage2d? because i need to re set data with different width and heights  
> **username_2**: @username_4 You can use `glTexImage2D` in that case.  

---

### Answer by username_0 on 2017-01-07. Score: 8

I have now replaced it with the following, which works:

```
GLuint textureHandle;
glCreateTextures(GL_TEXTURE_2D, 1, &textureHandle);
glTextureStorage2D(textureHandle, 1, GL_RGBA8, imageW, imageH);
glTextureSubImage2D(textureHandle, 0, 0, 0, imageW, imageH, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glTextureParameteri(textureHandle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTextureUnit(0, textureHandle);

```


---

### Answer by username_1 on 2022-01-16. Score: 0

Just to show a 1:1 comparison to help people easily understand the new functions:  
`1). create 2). bind 3). allocate 4). upload`

```
1: glGenTextures(1,&tex);
2: glBindTexture(GL_TEXTURE_2D,tex);
3: glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w,h, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
4: glTexSubImage2D(GL_TEXTURE_2D, level, x,y,w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);

```

---

```
1: glCreateTextures(GL_TEXTURE_2D,1,&tex);
2: // glBindTextureUnit(unit, tex);
3: glTextureStorage2D(tex, levels, GL_RGBA8, w,h);
4: glTextureSubImage2D(tex, level, x,y,w,h, GL_BGRA, GL_UNSIGNED_BYTE, data);

```

Much cleaner. We don't need to bind. We just allocate our texture levels, then upload to them.

Also with `glBindTextureUnit` we don't need `glActiveTexture`.  
And the equivalent of `glTextureStorage2D` in the old code would actually be:

```
for(int i=0; i<levels; i++) glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, max(1,w>>i),max(1,h>>i), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);

```

Of course you'd still need such a loop if you are uploading different levels manually.

Also here's some other dsa texture functions to use instead:  
`glTextureParameteri` and `glGenerateTextureMipmap`


---

