2017-04-12 42 views
0

我注意到,有些選擇將默認紋理綁定到每個渲染循環期間使用的每個紋理單元。這是常見的/最佳做法嗎?OpenGL - 綁定到默認紋理的練習?

僞例:

Tick() { 

    glUseProgram(someProgram); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, imgTexture1); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, imgTexture2); 

    . 
    . 
    . 

    //Is the following really necessary: ??? 

    glUseProgram(0); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, 0); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, 0); 

} 

如果它在這裏不需要,那麼應該這樣的調用資源之前做出被釋放?

+0

你的目標是什麼OpenGL版本? – tambre

+0

@tambre - 總體上詢問最佳實踐。如果這個問題的答案是依賴於版本的,那麼哪個版本和如何? – perrelet

回答

2

這不是刪除對象所必需的。刪除一個對象時,它會自動從每個綁定點解除綁定。這只是發佈glDelete*命令的上下文才是真實的;其他共享訪問該對象的上下文不會解除綁定。如果該對象被連接到另一個對象(例如附加到幀緩衝區的紋理),那麼這也不會被解除。

清理自己後,主要是爲了避免錯誤,這不是一個壞主意。如果着色器試圖訪問具有綁定內容的紋理單元,它可能會「工作」,從而隱藏錯誤。而如果它試圖訪問一個沒有任何約束的單位,它很可能會明顯失敗。

當然,這主要是爲了調試,所以你可以在#ifdef這樣的代碼中將它在發佈版本中刪除。

但是,上面假定您在完成渲染後基本上解除了紋理綁定。我提出這個問題是因爲你顯示的代碼從每個紋理單元中解開的代碼是不正確。爲什麼?

因爲每個紋理單元都有多個綁定點,每個類型的紋理都有。因此,如果您將紋理綁定到GL_TEXTURE_CUBE_MAP,則調用glBindTexture(GL_TEXTURE2D, 0)不會對綁定到立方體貼圖目標的紋理執行任何操作。

所以,如果你打算寫一個從每一個紋理單元紋理解除綁定代碼,你必須調用glBindTextureevery texture target that exists

void UnbindFromTextureUnit(int unit) 
{ 
    static const GLenum allTargets[] = {/*Every texture target that exists*/}; 

    glActiveTexture(GL_TEXTURE0 + unit); 
    for(auto target : allTargets) 
    glBindTexture(target, 0); 
} 

或者你可以使用multibind glBindTextures from GL 4.4。或直接訪問4.5 glBindTextureUnit()

+0

非常清楚,很好的答案 - 謝謝你的清晰度。確實 - 我給出的例子假設一個程序只能生成'GL_TEXTURE2D'綁定。此外,通過預處理語句簡單地刪除這些代碼以便發佈是個好主意。 +1 – perrelet