1

In a straightforward procedure of using textures in WebGL (and I believe OpenGL), it makes sense to do something like the following:

  1. Activate the texture unit w/ gl.activeTexture()
  2. Bind the texture w/ gl.bindTexture()
  3. Setup the parameters w/ gl.texParameteri() and friends
  4. Upload the data w/ gl.texImage2D()
  5. Assign the correct unit to the sampler w/ gl.uniform1i()
  6. Draw

This is also the approach taken by various books and tutorials for learning the technique.

However - in more advanced usage where a texture may be re-used for different shaders or it's desirable to have a split between loading and rendering, it seems like step 1 (assigning the texture unit) might be unnecessary until render time.

Does the texture unit really affect the setup of the texture itself?

In other words - is the following approach ok?

PREP (for each texture, before any render calls)

  1. Do not activate the texture unit (will always be default 0 here)
  2. Bind the texture w/ gl.bindTexture()
  3. Setup the parameters w/ gl.texParameteri() and friends
  4. Upload the data w/ gl.texImage2D()

RENDER (on each tick)

  1. Activate the desired texture unit w/ gl.activeTexture()
  2. Bind the texture w/ gl.bindTexture()
  3. Assign the correct unit to the sampler w/ gl.uniform1i()
  4. Draw
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
davidkomer
  • 3,020
  • 2
  • 23
  • 58
  • 2
    You're correct, There's generally no reason to call `gl.activeTexture` at init time and [it's normal to bind textures to different texture units at render time](https://webglfundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html). https://stackoverflow.com/a/20850791/128511 – gman Mar 11 '18 at 15:26

1 Answers1

2

The active texture unit does, in general, not have any influence on the texture preparation process. You just have to make sure that the same texture unit is set during the whole process.

This can also be seen by the OpenGL 4.5 Direct State Access API where you don't have to bind the texture at all for preparation.

Note, that you could also avoid setting the sampler uniform (gl.uniform1i) in each frame unless you are using the same shader with different texture units. In todays OpenGL, I would also advice to use layout (binding = x) in the shader instead of setting the sampler uniform from application code.

Edit: To explain what was meant by "make sure that the same texture unit is set during the whole process":

The chosen texture unit does not have a direct influence. But all commands like texParameteri or texImage2D operate on the current texture unit. What you shouldn't do is something like this:

gl.activeTexture(X)
gl.bindTexture(T1);
gl.texParameteri(...)

gl.activeTexture(Y);
gl.texImage2D(...);

because gl.texImage2D would not operate on the T1 texture anymore since T1 is only bound to texture unit X, but not to texture unit Y. Basically, you can choose any texture unit X you want for the setup process, but you should not change the texture unit (without rebinding the texture) in between.

BDL
  • 21,052
  • 22
  • 49
  • 55
  • 2
    Curious why this was downvoted - seems like a sensible answer? Can you elaborate a little more on "same texture unit set during the whole process" though? E.g. if it has no influence, how does changing it break things? – davidkomer Mar 11 '18 at 10:14
  • What does this answer have to do with WebGL? – gman Mar 11 '18 at 15:25
  • @gman: The behavior is exactly the same in webgl. (Except for the DSA paragraph). The difference in code would be `gl.Active...` instead of `glActive...` and so on. Also note, that at the point of writing the answer, the question was tagged with both, webgl and opengl. – BDL Mar 11 '18 at 15:33
  • 1
    Except it's not. It's only confusing since someone asking the question has no knowledge of DSA or OpenGL. WebGL has doesn't have `layout` settings in shaders (WebGL2 does but support is still rather low). Also there's a pretty common informal rule here on SO that question don't get tagged with both WebGL and OpenGL since it only leads to confusing and since they are both programmed in different languages. You'll notice Nicol removed the tag which he has on just about every double tagged question – gman Mar 11 '18 at 15:38
  • @gman: I updated the code-sample to webgl, if you think that it makes the answer easier to understand, I can remove the second and third paragraph (which, as already said, have been added because the question was tagged opengl and webgl when I answered). I'm not sure if removing the tag (not done by me or op) was a good thing in this case. – BDL Mar 11 '18 at 15:40
  • Remove the DSA and the layout stuff. WebGL2 has the layout keyword but you can not bind texture units with it in WebGL2. Both of those parts of your answer will likely just confuse a new WebGL programmer. I also agree with david's comment that "same texture unit set during the whole process" has no meaning either. Actually even the rest of your answer about not switching texture units is pretty confusing. – gman Mar 11 '18 at 15:46
  • "Also there's a pretty common informal rule here on SO that question don't get tagged with both WebGL and OpenGL since it only leads to confusing and since they are both programmed in different languages." - did not know that! I'll keep it in mind for the future, thanks! – davidkomer Mar 11 '18 at 15:59