davidkomer
davidkomer

Reputation: 3098

Texture units for preparing textures

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

Upvotes: 1

Views: 654

Answers (1)

BDL
BDL

Reputation: 22175

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.

Upvotes: 2

Related Questions