2015-10-04 49 views
1

我使用OpenGL在幾個不同的對象中繪製數組。每個對象都繪製不同的數據,但對於每個對象,數據的容器/位置在程序的整個生命週期內保持不變。 OpenGL的告訴我,我有很多冗餘狀態的呼叫:冗餘狀態調用OpenGL

  • glBindFramebuffer
  • glUniformMatrix4fv
  • glUniform4fv
  • glBindRenderbuffer
的這些,我只顯式調用glUniformMatrix4fv和glUniform4fv

。看到這個之後,我試着移動它們,以便在OpenGL的設置過程中只調用它們,但是數組並沒有被繪製。

這是目前的每次重繪什麼時間獲取調用示例:

glBindVertexArrayOES(_vertexArray); 
glUseProgram(_program); 
glUniformMatrix4fv(_mvpMatrixHandle,1,0,_mvpMatrix.m); 
glUniform4fv(_colorHandle,1,colors); 
glDrawArrays(GL_TRIANGLE_FAN,0,4); 




問題

  1. 由於變量的容器和位置我我傳遞給這些函數,每次爲給定對象繪製數組或者在開始時只繪製一次數組時,是否需要調用這些函數該節目的寧?如果是這樣,我該怎麼做?

  2. 如何消除這些我沒有明確調用的其他冗餘狀態調用?

回答

1

如果該值沒有變化,則傳遞給着色器的任何數據都只能傳遞一次。雖然完全有可能,但我會建議你不要僅僅因爲這樣的代碼難以維護而這樣做。如果在某些時候你選擇改變矩陣,那麼它會給你重組帶來麻煩。所以,只有在非常晚期的發展狀態下才會這樣做,而只有在需要獲得業績的時候(不過這並不會造成很大的差別)。還有其他的方法來處理這些東西,但冷杉...

如果移動矩陣調用時不繪製對象,然後矩陣不正確設置或更多可能的情況是你忘記使用着色器程序之前電話。 (glUseProgram(_program);

既然你說你自己沒有綁定緩衝區,仍然可以使用一些更高級別的工具,比如GLKView(控制器),它可以在內部爲你做。你將無法失去這些警告,我建議你根本不要使用這些工具。從GLKit中唯一有用的是我的經驗中的矩陣和一些矢量操作。

那麼關於你的多餘通話和「其他方式」。有些人做的是檢查發送到着色器的當前狀態,並比較新值是否與當前值不同。這並不像看起來那麼容易,因爲一些值應該是每着色器和一些每個上下文。例如,如果啓用alpha混合,它將影響所有着色器,您應該檢查並分配上下文對象的值。另一方面,如果您要設置矩陣等制服,則應該檢查並將其分配到正在使用的着色器上。這需要一些工作,但值得它來獲得一個漂亮的乾淨的代碼:您應該爲着色器對象和上下文對象創建包裝。這些也應該分配前進行的某些參數的狀態,他們被分配時,檢查新值:

- (void)setMatrix:(GLKMatrix4)matrix 
{ 
    if(memcmp(currentMatrix.m, matrix.m, sizeof(matrix.m)) != 0) { // will return 0 if they are the same 
     memcpy(currentMatrix.m, matrix.m, sizeof(matrix.m)); // copy the new data 
     glUniformMatrix4fv(_mvpMatrixHandle, 1, 0, matrix.m); // send data to shader 
    } 
} 

這應該那麼對你正在使用的所有調用來完成。即使每次調用它都會阻止任何多餘的調用,但由於內存比較,會在CPU上產生小的開銷。這仍然是非常小的開銷。

+0

太棒了,謝謝。這是一個很好的解釋。 –