是否需要glDisableClientState?

时间:2012-10-07 21:27:30

标签: 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);
}

在我的程序中,我总是使用纹理坐标和顶点数组,所以我认为每帧继续启用和禁用它们毫无意义。我将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);
}

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

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

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

2 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:4)

良好的性能和良好的示例不一定是一回事。示例代码用于向您展示如何执行某些操作,以清楚地解释事物的工作原理。好的例子向您展示了如何最大限度地减少代码中出错的可能性。等等。

性能往往是由于做“有风险”的事情,但是既然你做的一切都是正确的,那就很有效。

优良作法是设置当时需要的任何状态(在合理范围内),并在完成后取消设置状态。这最大限度地减少了搞砸的可能性。但它可能会以某种表现为代价。

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

简而言之:不要担心。