2012-10-07 249 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,這可能會對性能造成比一些額外的啓用/禁用更大的阻力。

總之:不要擔心。