I'm learning GLES. There are many pair functions like glClientActiveTexture/glActiveTexture.
What's the difference between them? (Especially the case of glClientActiveTexture)
From the openGL documentation:
On one hand, glClientActiveTexture is used to control subsequent glTexCoordPointer calls (with vertex arrays). On the other hand glActiveTexture affects subsequent calls to glTexCoord calls (used by display lists or immediate mode (non existent in OpenGL ES (AFAIK)).
Adding to Kenji's answer, here's a bit more detail (and bearing in mind that not everything in OpenGL is available in ES).
But first some quick terminology to try to prevent confusion between all the texturish things (oversimplified for the same reason).
GL_TEXTURE_2D). It is activated via glActiveTextureglBindTexture.glGenTextures, and it is actually instantiated via (first call to) glBindTexture with its name.Summary: A texture unit has texture targets that are bound to textures.
In order to have multitexturing with 2D textures (for example), wherein more than one 2D texture must be bound simultaneously for the draw, you use different texture units - bind one texture on one unit's 2D target, and bind the next on another unit's 2D target. glActiveTexture is used to specify which texture unit the subsequent call to glBindTexture will apply to, and glBindTexture is used to specify which texture is bound to which target on the active texture unit.
Since you have multiple textures, you're likely to also have multiple texcoords. Therefore you need some way to communicate to OpenGL/GLSL that one set of texcoords is for one texture/unit, and another set of texcoords is for another. Usually you can do this by just having multiple texcoord attributes in your vertex and corresponding shader. If you're using older rendering techniques that rely on pre-defined vertex attributes in the shader, then you have to do something different, which is where glClientActiveTexture comes in. The confusion happens because it takes an argument for a texture unit, but it does not have the same implications as glActiveTexture of activating a texture unit in the state machine, but rather it designates which pre-defined gl_MultiTexCoord attribute (in the shader) will source the texcoords described in the subsequent call to glTexCoordPointer.
In a nutshell, glActiveTexture is for texture changes, and glClientActiveTexture is for texcoord changes. Which API calls you use depends on which rendering technique you use:
glActiveTexture sets which texture unit will be affected by subsequent context state calls, such as glBindTexture. It does not affect glMultiTexCoord, glTexCoord, or glTexCoordPointer, because those have to do with texcoords, not textures.glClientActiveTexture sets which texture unit subsequent vertex array state calls apply to, such as glTexCoordPointer. It does not affect glBindTexture, because that has to do with textures, not texcoords.
glMultiTexCoord which uses DSA to select a texture unit via its target parameter, nor does it affect glTexCoord, which targets texture unit 0 (GL_TEXTURE0). This pretty much just leaves glTexCoordPointer as the thing it affects, and glTexCoordPointer is deprecated in favor of glVertexAttribPointer, which doesn't need glClientActiveTexture. As you can see, glClientActiveTexture isn't the most useful, and is thusly deprecated along with the related glWhateverPointer calls.glActiveTexture + glBindTexture with all techniques to bind each texture on a specific texture unit. You'll additionally use glClientActiveTexture + glTexCoordPointer when you're using DrawArrays/DrawElements without glVertexAttribPointer.As OpenGL has evolved over the years, there are many ways in which to implement multitextured draws. Here are some of the most common:
glBegin/glEnd pairs) with GLSL shaders targeted for version 130 or older, and use glMultiTexCoord calls to specify the texcoords.glBindVertexArray and glBindBuffer + glDrawArrays/glDrawElements to specify vertex data, and calls to glVertexPointer, glNormalPointer, glTexCoordPointer, etc., to specify vertex attributes during the draw routine.glBindVertexArray + glDrawArrays/glDrawElements to specify vertex data, with calls to glVertexAttribPointer to specify vertex attributes during the init routine.Here are some examples of the API flow for multitexturing with two 2D textures using each of these techniques (trimmed for brevity):
Using immediate mode:
Using DrawElements but not VertexAttribPointer:
Using DrawElements and VertexAttribPointer:
glMultiTexCoord populates unused coords as 0,0,0,1.
e.g. glMultiTexCoord2f == s,t,0,1GL_TEXTURE0 + i, not just i.GL_TEXTURE0 + i, i must be within 0 - GL_MAX_TEXTURE_COORDS-1.GL_MAX_TEXTURE_COORDS is implementation-dependent, but must be at least two, and is at least 80 as of OpenGL 4.0.glMultiTexCoord is supported on OpenGL 1.3+, or with ARB_multitextureglActiveTexture or glBindTexture between glBegin and glEnd. Rather, bind all needed textures to all needed texture units before the draw call.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With