2017-04-12 12 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などのコードを使用できます。

しかし、上の説明では、レンダリングが完了した後に本質的にテクスチャのバインドを解除すると仮定しています。すべてのテクスチャユニットからバインド解除されたコードは、が正しくないため、です。どうして?

各テクスチャユニットは、複数結合点、テクスチャの各タイプための1つを有しているからです。テクスチャをGL_TEXTURE_CUBE_MAPにバインドした場合、glBindTexture(GL_TEXTURE2D, 0)を呼び出すと、キューブマップターゲットにバインドされたテクスチャに何も行われません。

あなたはすべてのテクスチャユニットからテクスチャをバインドを解除コードを記述するつもりであれば、あなたはevery texture target that existsglBindTextureを呼び出す必要があり:

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

関連する問題