glClient和gl之间有什么区别?(这是一个关于IT技术的问题)

3

我正在学习GLES。有许多成对的函数,例如glClientActiveTexture/glActiveTexture。 它们之间有什么区别?(特别是glClientActiveTexture的情况)

2个回答

5

根据 OpenGL文档:

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

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


谢谢!我可以问一下文档中“客户端”和“服务器”的含义有什么区别吗? - eonil
1
OpenGL的设计目的是可以在网络上运行,类似于X11等协议。运行程序的机器可能不是执行渲染的机器。但这种情况通常不多见了。 - geofftnz

3

补充Kenji的回答,以下是更详细的说明(需要注意的是并非所有OpenGL功能在ES中都可用)。

术语

首先介绍一些术语,以尝试防止所有纹理相关事物(为了相同的原因而过于简化)之间的混淆。

  • 纹理单元:一个包含纹理目标(例如GL_TEXTURE_2D)的集合。通过glActiveTexture激活它。
  • 纹理目标:纹理绑定点。它指定纹理类型(例如2D)。通过glBindTexture设置。
  • 纹理:包含纹素(图像数据,例如像素)和参数(例如包裹方式和过滤模式)的东西,它们组成了一个纹理图像。它由键/名称/ID确定,可以通过glGenTextures获取新的,通过(对其名称的)glBindTexture调用实例化。

总结:纹理单元具有绑定到纹理的纹理目标。

纹理单元激活

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

由于您有多个纹理,很可能还有多个纹理坐标系。因此,您需要一种方式向OpenGL/GLSL通信,以使其知道一个纹理/单元的一组纹理坐标系,另一个纹理/单元的另一组纹理坐标系。通常可以通过在您的顶点和相应的着色器中具有多个纹理坐标属性来完成此操作。如果您正在使用依赖于着色器中预定义的顶点属性的旧渲染技术,则必须执行不同的操作,这就是glClientActiveTexture发挥作用的地方。混淆之处在于它接受一个纹理单元参数,但它没有glActiveTexture激活状态机中纹理单元的相同影响,而是指定了预定义的gl_MultiTexCoord属性(在着色器中)将源于后续对glTexCoordPointer描述的纹理坐标。

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

  • glActiveTexture用于设置将受到后续上下文状态调用(例如glBindTexture)影响的纹理单元。它不会影响glMultiTexCoordglTexCoordglTexCoordPointer,因为它们与纹理坐标有关,而不是纹理。
  • glClientActiveTexture用于设置后续顶点数组状态调用所应用的纹理单元,例如glTexCoordPointer。它不会影响glBindTexture,因为它与纹理有关,而不是纹理坐标。
    • 它也不会影响使用DSA通过其target参数选择纹理单元的glMultiTexCoord,也不会影响目标为0号纹理单元(GL_TEXTURE0)的glTexCoord。这基本上只剩下glTexCoordPointer需要受到其影响,而glTexCoordPointer已被弃用,推荐使用glVertexAttribPointer,后者不需要glClientActiveTexture。如您所见,glClientActiveTexture并不是最有用的,因此与相关的glWhateverPointer调用一起被弃用。
  • 您将在所有技术中使用glActiveTexture+glBindTexture将每个纹理绑定到特定的纹理单元上。当您使用DrawArrays/DrawElements而没有使用glVertexAttribPointer时,您还将使用glClientActiveTexture+glTexCoordPointer

多重纹理示例

随着OpenGL的发展,有许多实现多重纹理绘制的方法。以下是最常见的几种:

  1. 使用旧版GLSL着色器针对版本130或更早版本的即时模式(glBegin/glEnd对)并使用glMultiTexCoord调用来指定纹理坐标。
  2. 使用glBindVertexArrayglBindBuffer+glDrawArrays/glDrawElements来指定顶点数据,并在绘制过程中调用glVertexPointerglNormalPointerglTexCoordPointer等来指定顶点属性。
  3. 使用glBindVertexArray+glDrawArrays/glDrawElements来指定顶点数据,并在初始化过程中调用glVertexAttribPointer来指定顶点属性。

以下是使用这些技术之一绘制两个2D纹理的多重纹理API流程示例(为简洁起见进行了裁剪):

  1. 使用立即模式:

  2. 使用DrawElements但不使用VertexAttribPointer:

  3. 使用DrawElements和VertexAttribPointer:

其他说明

  • glMultiTexCoord用0,0,0,1填充未使用的坐标。例如:glMultiTexCoord2f表示s,t,0,1。
  • 总是使用GL_TEXTURE0+i,而不仅仅是i
  • 当使用GL_TEXTURE0+i时,i必须在0-GL_MAX_TEXTURE_COORDS-1之间。
  • GL_MAX_TEXTURE_COORDS是实现相关的,但至少为两个,在OpenGL 4.0中至少为80。
  • glMultiTexCoord支持OpenGL 1.3+或ARB_multitexture。
  • 不要在glBeginglEnd之间调用glActiveTextureglBindTexture。相反,在绘制之前将所有需要的纹理绑定到所有需要的纹理单元。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接