OpenGL的glEnableClientState和glDisableClientState函数是什么?

17
OpenGL中的glEnableClientState和glDisableClientState是什么意思?到目前为止,我发现这些函数是用来启用或禁用一些客户端能力。

好吧,这里的客户端或服务器到底是什么?我在PC上运行我的OpenGL程序,所以这是指什么?我们为什么需要禁用某些能力?还有更令人着迷的是与某种数组相关的事情?

整个画面对我来说非常模糊。

4个回答

14

原始术语来自X11符号表示法,其中服务器是实际的图形显示系统:

  • 一个服务器程序提供对某种显示设备的访问

  • 客户端连接到服务器以在其提供的显示设备上绘制

glEnableClientStateglDisableClientState 设置客户端部分的状态。顶点数组曾经位于客户端进程内存中,因此使用顶点数组进行绘制是客户端本地处理过程。

今天我们有缓冲区对象,将数据放置在服务器内存中,使得顶点数组的整个客户端术语变得不直观。像我们处理帧缓冲对象和纹理一样,通过常规的glEnable/glDisable函数丢弃客户端状态并启用/禁用顶点数组会更有意义。


3
好的回答,比我的更准确。顺便说一下,由于固定语义顶点数组已经被弃用,通用顶点数组使用 gl[En/Dis]ableVertexAttribArray,因此客户端状态函数也已经被弃用了。所以,语义冲突在将来不再是那么大的问题了。 - Christian Rau
现在,我应该避免使用顶点数组和客户端服务器机制吗? - Quazi Irfan
相反!如果你真的需要高性能,顶点数组是唯一的选择。请不要被同样的误解所迷惑,即服务器/客户端机制会导致性能损失;很多人认为X11因为是客户端/服务器机制而变慢。然而,我经常发现写得好的X11程序在性能上超过了它们的Windows和MacOS X对应程序,有时甚至相差数个数量级。 - datenwolf
好的,这就是为什么引入了gl[En/Dis]ableVertexAttribArray吗?对吧?我只需要避免使用旧命令,即gl[En/Dis]ableClientState部分。对吧? - Quazi Irfan
1
@iamcreasy:不要被gl{En,Dis}ableClientState函数的命名所迷惑,如果应用于VBOs上,它并不比gl{En,Dis}ableVertexAttribArray函数更昂贵。请记住,客户端/服务器并不一定意味着对带宽产生任何影响。在现代操作系统上,写入回环套接字(即与127.0.0.1通信)几乎没有开销:网络堆栈只需设置发送到COW的页面,然后仅传递网络堆栈内的指针。最终效果是,回环套接字变成了共享内存! - datenwolf

7
如果您通过将缓冲区传递给OpenGL(glVertexPointer()等)来绘制图形,而不是直接调用(glVertex3f()),则需要告诉OpenGL使用哪些缓冲区。
因此,您需要创建缓冲区,绑定它们,并使用glVertexPointer和glNormalPointer指向您的数据。然后,调用glDrawElements(或类似函数)将使用这些缓冲区进行绘制。但是,还有一个必需的步骤是告诉OpenGL驱动程序您实际想要使用哪些缓冲区,这就是glEnableClientState()发挥作用的地方。
这都很模糊。您需要阅读顶点缓冲对象并尝试它们。

您不需要使用缓冲区来使用顶点数组。实际上,“客户端状态”语义在缓冲区出现之前就已经开发了,而且与缓冲区没有太多关联,因为缓冲区是由驱动程序控制而不是客户端控制的。 - Christian Rau
1
对我来说,@chris-mennie的解释根据这个教程是有道理的。但是,@christian-rau,抱歉,我不明白你在说什么。 - Quazi Irfan
@iamcreasy,Christian提到,除非您使用的是核心OpenGL 3.2或更高版本(该教程是为此编写的),否则您不必为顶点数组使用缓冲区对象。您可以使用在CPU上正常分配的内存。实际上,这就是为什么OpenGL函数被称为glVertexPointer的原因;因为它们过去只接受指针。后来这些函数被重载以接受缓冲区对象偏移量。 - Nicol Bolas
2
@iamcrasy,你需要启用/禁用数组的原因是没有其他方法可以表达“我以前使用过这个数组,但现在不想再使用它了”。OpenGL是一个状态机,因此它以你上次离开的形式保存所有状态。你不能使用glColorPointer来表示“不要获取这个颜色的数据”。所以,你可以使用glEnable/DisableClientState告诉OpenGL从哪些数组中提取数据,哪些不提取。 - Nicol Bolas
1
@iamcreasy OpenGL不像D3D,每个主要版本都会经历根本性的API变化。即使是D3D也不再如此,因为D3D11与D3D10非常接近。OpenGL 4.0从OpenGL 3.3中删除了任何内容。唯一的删除发生在3.0到3.1的边界上;从那时起,它只增加了功能。因此,如果您编写3.3核心代码,它将在4.0核心或4.1核心上运行。 - Nicol Bolas
显示剩余5条评论

4
在OpenGL术语中,客户端是指您的应用程序,而服务器是指显卡(或驱动程序),我想。仅客户端能力是顶点数组,因为它们存储在CPU内存中,因此在客户端或更具体地说,它们由您的应用程序控制(分配和释放),而不是由驱动程序控制。
顶点缓冲对象则是另一回事。它们可以用作顶点数组,但由驱动程序控制,因此在使用缓冲区时,“客户端状态”这个词就没那么有意义了。

2

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