2016-08-14 20 views
0

OpenGLでは、1つのテクスチャーを2つ(またはそれ以上)の異なるユニフォームサンプラーにバインドすることは可能ですか? それはこのように書き二つの異なるテクスチャとレンダリング:私は2つの異なるテクスチャユニットに1つのテクスチャオブジェクトをバインドしようとすると、それは、2つの異なるユニフォームサンプラーに1つのテクスチャーをバインドする

//Initial shader program setup. 
glLinkProgram(program); 

GLuint texture1Loc = glGetUniformLocation(program, "texture1"); 
GLuint texture2Loc = glGetUniformLocation(program, "texture2"); 

glUseProgram(program); 
glUniform1i(texture1Loc, 0); //Texture unit 0 is for texture1 sampler. 
glUniform1i(texture2Loc, 1); //Texture unit 1 is for texture2 sampler. 

//When rendering an object with this program. 
glActiveTexture(GL_TEXTURE0 + 0); 
glBindTexture(GL_TEXTURE_2D, texture1); 
glActiveTexture(GL_TEXTURE0 + 1); 
glBindTexture(GL_TEXTURE_2D, texture2); 

//Render stuff 
glDraw*(); 

しかし:

シェーダ:

uniform sampler2D texture1; 
uniform sampler2D texture2; 
.... 

クライアント最初にバインドされたユニットがアンバインドされたままであるように思われる:

glActiveTexture(GL_TEXTURE0 + 0); 
glBindTexture(GL_TEXTURE_2D, texture1); // bind texture1 
glActiveTexture(GL_TEXTURE0 + 1); 
glBindTexture(GL_TEXTURE_2D, texture1); // bind texture1 - again, but to another unit 

もちろん、両方のサンプラーに同じユニットを設定することは可能ですが、時々、同じテクスチャーオブジェクトを両方のサンプラーに設定するだけでなく、異なるテクスチャーにもシェーダーを使用したいと思っています。

このソリューションは実際にはうまく機能しますが、私にはこのようなニーズはありません。 バインディングの直前にサンプラーのテクスチャユニットを変更することもできますが、それは私にとってはクリーンな解決策ではないようです。

glUniform1i(texture1Loc, 0); //Texture unit 0 is for texture1 sampler. 
glActiveTexture(GL_TEXTURE0 + 0); 
glBindTexture(GL_TEXTURE_2D, texture1); 


glUniform1i(texture2Loc, 1); //Texture unit 1 is for texture2 sampler 
glActiveTexture(GL_TEXTURE0 + 1); 
glBindTexture(GL_TEXTURE_2D, texture2); 

.... 

glUniform1i(texture1Loc, 0); //Texture unit 0 is for texture1 sampler. 
glUniform1i(texture2Loc, 0); //Texture unit 0 is for texture2 sampler. 
glActiveTexture(GL_TEXTURE0 + 0); 
glBindTexture(GL_TEXTURE_2D, texture1); 

解決策はありますか?おそらく最初のアプローチは正しいかもしれませんが、私は何か間違っていますか? 1つのテクスチャを多くのユニットにバインドすることは可能ですか?

+1

ユニフォームが実際に使用されている(フラグメント?)シェーダのセクション '...'が見つかりませんか?コンパイルされリンクされたプログラムでユニフォームがどのように使用されているかを見ずに問題を診断するのは難しいです。つまり、シェーダの残りの部分を実際に表示することが重要であることを意味します。また、一部のGLSLコンパイラでは2パスで作業するため、他のシェーダステージも同様です。コンパイラがcodepathが何らかの形で死んでいると判断した場合、定数式の削除/置換が開始されます。 –

答えて

2

同じテクスチャを2つの異なるテクスチャユニットにバインドし、両方のテクスチャユニットをシェーダで使用すると、完全にうまくいくはずです。あなたのコードには別の問題、または使用しているOpenGL実装の問題があります。

このエラー:私は見つけることができる

ザのみ幾分関連するエラー状態が「2.11頂点シェーダ」セクションの下のサブセクション「検証」で、OpenGLの3.3仕様のページ82上に、以下のとおりでありますGLに頂点を転送する任意のコマンドによって生成された場合:[..]現在のプログラムオブジェクト内の任意の2つのアクティブなサンプラーは、異なるタイプのものであるが、同一のテクスチャ画像部を参照し、[..]

しかし、それはあなたがやっていることではなく、同じテクスチャをバインドして複数のルテクスチャユニット。そのような制限が存在するならば、私はそれが上に引用されたものと同じセクションにあることを期待し、そこにそのようなものは指定されていません。

+0

また、このような制限は、サンプラーオブジェクトの使用を無意味にします(複数のテクスチャユニットにバインドされた同じテクスチャ、異なるサンプラーがアクティブな各テクスチャユニット)。 – peppe

+0

私はOpenGLとGLSLの両方のエラーをチェックしました。非存在であり、記述どおりに動作します。私はインターネットとOGLの両方のドキュメントでこの例に関する情報を見つけることができません。私は、OpenGL 3.3.11672、GLSL 330、Windows 7 x64上のRadeon 4650mを使用しています。 – Krzycho

+0

試してみることができる別の設定がありますか?特に、別のベンダーのGPUを使用していますか? –

関連する問題