私は簡単なテスト目的でこのプログラムを持っています。プログラムは 2 つの 1-D テクスチャを作成し、シェーダーに渡します。フラグメント シェーダーは非常に単純です。最初のテクスチャのインデックス 4 のテクセルを取り出し、そのテクセルをカラー フラグメントにします。
#extension GL_EXT_gpu_shader4 : enable
uniform sampler1D firstTexture;
uniform sampler1D secondTexture;
uniform int max_index;
void main()
{
vec4 texel = texture1D( firstTexture, float(4.0) / float(max_index));
gl_FragColor = texel;
}
正方形を描いています。最初のテクスチャのインデックス 4 のテクセルには、赤色の <1.0, 0.0, 0.0, 1.0> が含まれています。したがって、上記のシェーダーの結果は赤い四角です。問題は、2 番目の 1-D テクスチャを作成してシェーダーに渡すときに発生します。なんらかの理由で、シェーダーが気に入らず、機能しなくなり、赤い正方形の代わりに黒い正方形が描画されます。C++ コードは次のとおりです (関数 "makeGLTexture" 内のコードは下にあります)。
// =========================================
// Set up the first 1-D texture.
// =========================================
firstTexture.allocateTexels(10);
firstTexture.fullyPopulateTexture();
glActiveTexture(GL_TEXTURE0);
firstTextureID = firstTexture.makeGLTexture();
// =========================================
// Set up the second 1-D texture.
// =========================================
secondTexture.allocateTexels(10);
secondTexture.fullyPopulateTexture();
glActiveTexture(GL_TEXTURE1);
secondTextureID = secondTexture.makeGLTexture();
// Set up some parameters.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// ========================================
// Create the Shaders and Get Them Running.
// ========================================
#if defined (_WIN32)
const char* vertexShaderSource = textFileRead("Vertex.vs");
const char* fragmentShaderSource = textFileRead("Fragment.fs");
#else
const char* vertexShaderSource = textFileRead("../../Vertex.vs");
const char* fragmentShaderSource = textFileRead("../../Fragment.fs");
#endif
GLuint vertexShader = createShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader = createShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint shaderProgram = createProgram(vertexShader, fragmentShader);
if (shaderProgram != 0) glUseProgram(shaderProgram);
delete vertexShaderSource;
delete fragmentShaderSource;
// ===================================================
// Pass the information of the textures to the shader.
// ===================================================
// Pass the texture unit of the first texture to the shaders.
GLuint location = glGetUniformLocation(shaderProgram,"firstTexture");
glUniform1i ( location, 0 );
// Pass the texture unit of the second texture to the shaders.
location = glGetUniformLocation(shaderProgram,"secondTexture");
glUniform1i ( location, 1 );
// Pass the maximum number of texels in the 1D texture.
location = glGetUniformLocation(shaderProgram,"max_index");
glUniform1i ( location, 9 );
テクスチャバインディングは関数「makeGLTexture」で行います。中のコードはこちら。
// Define an array that stores the texture's information.
Texel* const texelArray = new Texel[texels.size()];
// Copy information from the vector of texels into the array of texels.
for (unsigned int index = 0; index < texels.size(); index++)
texelArray[index] = texels[index];
/* ====================
* Generate the texture.
* ====================*/
// ID of the texture.
GLuint textureID;
// Generate a texture object ID for this texture.
glGenTextures( 1, &textureID );
// Bind the texture object to the texture identifier.
glBindTexture( GL_TEXTURE_1D, textureID );
// Define the texture image.
glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, texels.size(), 0, GL_RGBA, GL_FLOAT, texelArray );
// ===================== //
// Free the memory allocated for the texture array (array of texels).
delete[] texelArray;
// Return the texture ID.
return textureID;
奇妙なことに、2 番目のテクスチャを作成した直後にアクティブなテクスチャ ユニットを最初のテクスチャのテクスチャ ユニットに切り替えると、プログラムが再び動作し、赤い四角が描画されます。
/* =========================================
* Set up the second one-dimensional texture.
* =========================================*/
...
**glActiveTexture(GL_TEXTURE0);**
その後、プログラムは再び動作します。
私の質問は、なぜこれが起こっているのですか? シェーダはテクスチャユニットから独立していませんか? テクスチャ ユニットをサンプラー変数に渡すだけでいいのではないですか? この場合、シェーダーを再度実行するためにテクスチャ ユニットをテクスチャ ユニット ゼロに戻さなければならないのはなぜですか? 何が起こっている?