是否需要glDisableClientState?

Sha*_*awn 2 opengl

我为渲染数组数据而遇到的每个例子都类似于下面的代码,在你的绘图循环中,你首先调用glEnableClientState来表示你将要使用的内容,当你完成后你调用glDisableClientState:

void drawScene(void) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindTexture(GL_TEXTURE_2D, texturePointerA);
    glTexCoordPointer(2, GL_FLOAT, 0,textureCoordA);
    glVertexPointer(3, GL_FLOAT, 0, verticesA);
    glDrawElements(GL_QUADS, numPointsDrawnA, GL_UNSIGNED_BYTE, drawIndicesA);

    glBindTexture(GL_TEXTURE_2D, texturePointerB);
    glTexCoordPointer(2, GL_FLOAT, 0,textureCoordB);
    glVertexPointer(3, GL_FLOAT, 0, verticesB);
    glDrawElements(GL_QUADS, numPointsDrawnB, GL_UNSIGNED_BYTE, drawIndicesB);

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}
Run Code Online (Sandbox Code Playgroud)

在我的程序中,我总是使用纹理坐标和顶点数组,所以我认为每帧继续启用和禁用它们毫无意义.我将glEnableClientState移动到循环之外,如下所示:

bool initGL(void) {
    //...
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
void drawScene(void) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, texturePointerA);
    glTexCoordPointer(2, GL_FLOAT, 0,textureCoordA);
    glVertexPointer(3, GL_FLOAT, 0, verticesA);
    glDrawElements(GL_QUADS, numPointsDrawnA, GL_UNSIGNED_BYTE, drawIndicesA);

    glBindTexture(GL_TEXTURE_2D, texturePointerB);
    glTexCoordPointer(2, GL_FLOAT, 0,textureCoordB);
    glVertexPointer(3, GL_FLOAT, 0, verticesB);
    glDrawElements(GL_QUADS, numPointsDrawnB, GL_UNSIGNED_BYTE, drawIndicesB);
}
Run Code Online (Sandbox Code Playgroud)

它似乎工作正常.我的问题是:

我需要在某处调用glDisableClientState; 也许当程序关闭?

还有,这样做可以吗?有没有我缺少的东西,因为其他人启用和禁用每个帧?

Tom*_*don 6

一旦设置了一些OpenGL状态,它就会保持设置状态.每次绘制时都不需要设置它.

尽可能少地手动设置状态可能容易出错 - 这可能是许多人不这样做的原因.


Nic*_*las 5

好的表现和好的榜样并不一定是一回事。示例代码向您展示如何做某事,清楚地解释事情是如何工作的。好的示例向您展示如何最大程度地减少代码中出现错误的可能性。等等。

绩效通常来自于做一些“有风险”的事情,但既然你做的每件事都是正确的,那么它就会成功。

最好在当时设置您需要的任何状态(在合理范围内),并在完成后取消设置该状态。这可以最大限度地减少搞砸事情的可能性。但这可能会以牺牲一些性能为代价。

话又说回来,对于简单的启用/禁用,它可能不会。坦率地说,您从客户端内存而不是缓冲区对象中提取顶点,并且glDrawRangeElements在执行此操作时没有使用顶点,这一事实可能比某些额外的启用/禁用对性能造成更大的拖累。

简而言之:不用担心。