2012-10-07 145 views
2

每个例子中,我遇到渲染阵列数据类似于下面的代码,其中,在绘图循环中,您第一次呼叫glEnableClientState你会使用什么,当你完成你打电话glDisableClientState:是否需要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;也许当程序关闭时?

此外,可以这样做吗?有没有什么我失踪,因为其他人启用和禁用每帧?

回答

6

一旦你设置了一些OpenGL状态,它仍然会被设置。每次画画时不需要设置它。

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

4

良好的性能和良好的例子不一定是同一件事。存在示例代码来向您展示如何做某件事,清楚地解释事情是如何工作的。好的例子告诉你如何最大限度地减少代码中出现错误的几率。等等。

表现通常是由于做事“有风险”,但因为你做的一切都是正确的,所以它会成功。

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

然后,对于简单的启用/禁用,它可能不会。虽然很坦率,但是您从客户端内存中取出顶点而不是缓冲区对象,并且您在此过程中没有使用glDrawRangeElements,这可能会对性能造成比一些额外的启用/禁用更大的阻力。

总之:不要担心。