glClient *** gl ***有什么区别?

时间:2010-02-09 08:25:15

标签: opengl-es

我正在学习GLES。有许多配对函数,例如glClientActiveTexture / glActiveTexture。 他们之间有什么区别? (特别是glClientActiveTexture

的情况

2 个答案:

答案 0 :(得分:4)

来自openGL documentation

  • glActiveTexture glActiveTexture选择后续纹理状态调用将影响哪个纹理单元。
  • glClientActiveTexture选择要由glTexCoordPointer修改的顶点数组客户端状态参数。

一方面,glClientActiveTexture用于控制后续的glTexCoordPointer调用(使用顶点数组)。另一方面,glActiveTexture会影响对glTexCoord调用的后续调用(由显示列表或立即模式使用(在OpenGL ES(AFAIK)中不存在)。

答案 1 :(得分:1)

添加Kenji的答案,这里有更多细节(请记住,并非所有OpenGL都可用于ES)。

术语

但首先是一些快速的术语,试图防止所有纹理事物之间的混淆(出于同样的原因而过度简化)。

  • 纹理单位:一组纹理目标(例如GL_TEXTURE_2D)。它通过glActiveTexture
  • 激活
  • 纹理目标:纹理的绑定点。它指定一种纹理(例如2D)。它是通过glBindTexture设置的。
  • 纹理包含纹理像素(图像数据,例如像素)和包含纹理图像的参数(例如包裹和滤镜模式)的东西。它由一个键/名称/ ID标识,您可以通过glGenTextures获得一个新的名称/ ID,它实际上是通过(第一次调用)glBindTexture及其名称实例化的。

摘要:纹理单元具有绑定到纹理的纹理目标。

纹理单元激活

为了使2D纹理具有多重纹理(例如),其中必须同时绑定多个2D纹理以进行绘制,您使用不同的纹理单元 - 将一个纹理绑定在一个单元的2D目标上,以及在另一个单位的2D目标上绑定下一个。 glActiveTexture用于指定后续调用glBindTexture将应用于哪个纹理单元,glBindTexture用于指定哪个纹理绑定到活动纹理单元上的哪个目标。

由于你有多个纹理,你可能还有多个texcoords。因此,您需要某种方式与OpenGL / GLSL进行通信,一组texcoords用于一个纹理/单元,另一组texcoords用于另一个。通常你可以通过在顶点和相应的着色器中使用多个texcoord属性来完成此操作。如果你正在使用依赖于着色器中预定义顶点属性的旧渲染技术,那么你必须做一些不同的事情,这就是glClientActiveTexture所在的地方。混乱发生是因为它需要一个参数一个纹理单元,但它与激活状态机中纹理单元的glActiveTexture没有相同的含义,而是指定哪个预定义的gl_MultiTexCoord属性(在着色器中)将获取texcoords在随后的glTexCoordPointer调用中描述。

简而言之,glActiveTexture用于纹理更改,glClientActiveTexture用于texcoord更改。您使用哪些API调用取决于您使用的渲染技术:

  • glActiveTexture 设置受后续上下文状态调用影响的纹理单元,例如glBindTexture。它不会影响glMultiTexCoordglTexCoordglTexCoordPointer,因为这些与texcoords有关,而不是纹理。
  • glClientActiveTexture 设置后续顶点数组状态调用应用于哪个纹理单元,例如glTexCoordPointer。它不会影响glBindTexture,因为这与纹理有关,而与纹理有关。
    • 它也不会影响使用DSA通过其目标参数选择纹理单元的glMultiTexCoord,也不会影响glTexCoord,它会定位纹理单元0({ {1}})。这几乎只留下GL_TEXTURE0作为它影响的内容,并且glTexCoordPointer已弃用,而不是glTexCoordPointer,这不需要glVertexAttribPointer。正如您所看到的,glClientActiveTexture并不是最有用的,因此不推荐使用相关的glWhateverPointer调用。
  • 您将glClientActiveTexture + glActiveTexture所有技术结合使用,以绑定特定纹理单元上的每个纹理。当您在没有glBindTexture的情况下使用DrawArrays / DrawElements时,您还会使用glClientActiveTexture + glTexCoordPointer

多纹理示例

随着OpenGL多年来的发展,有很多方法可以实现多纹理绘制。以下是一些最常见的内容:

  1. 使用针对130或更早版本的GLSL着色器的即时模式(glVertexAttribPointer / glBegin对),并使用glEnd调用来指定texcoords。
  2. 使用glMultiTexCoordglBindVertexArray + glBindBuffer / glDrawArrays指定顶点数据,并调用glDrawElementsglVertexPointer,{{1在绘图例程期间指定顶点属性。
  3. 使用glNormalPointer + glTexCoordPointer / glBindVertexArray指定顶点数据,调用glDrawArrays以在init例程中指定顶点属性。
  4. 以下是使用这些技术中的两个2​​D纹理进行多纹理的API流程的一些示例(为简洁而修剪):

    1. 使用即时模式:

    2. 使用DrawElements但不使用VertexAttribPointer:

    3. 使用DrawElements和VertexAttribPointer:

    4. 混杂。备注

      • glDrawElements将未使用的坐标填充为0,0,0,1。 例如glVertexAttribPointer == s,t,0,1
      • 始终使用glMultiTexCoord + i ,而不只是 i
      • 使用glMultiTexCoord2f + i 时,我必须在0 - GL_TEXTURE0 - 1之内。
      • GL_TEXTURE0依赖于实现,但必须至少为2,并且至少是OpenGL 4.0中的80。
      • OpenGL 1.3+或ARB_multitexture支持
      • GL_MAX_TEXTURE_COORDS
      • 请勿在{{1​​}}和GL_MAX_TEXTURE_COORDS之间致电glMultiTexCoordglActiveTexture。而是在绘制调用之前将所有需要的纹理绑定到所有需要的纹理单元。