0

私は簡単なテスト目的でこのプログラムを持っています。プログラムは 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);**

その後、プログラムは再び動作します。

私の質問は、なぜこれが起こっているのですか? シェーダはテクスチャユニットから独立していませんか? テクスチャ ユニットをサンプラー変数に渡すだけでいいのではないですか? この場合、シェーダーを再度実行するためにテクスチャ ユニットをテクスチャ ユニット ゼロに戻さなければならないのはなぜですか? 何が起こっている?

4

1 に答える 1

0

索引付けコードが少し心配です。IIRCテクセルの正確な値が必要な場合は、左端ではなく中央にヒットする必要があります。基本的に、ピクセル境界でサンプリングしています。あなたはもっと好きなことをしたい

 vec4 texel = texture1D( firstTexture, float(4.0 + 0.5) / float(max_index + 1));

max_index は、カウントではなく、テクスチャへの最大の有効なインデックスであると想定しています。

GL_NEAREST を使用していますが、現在テクセル 3 とテクセル 4 の境界でサンプリングしています。そのため、代わりにテクセル 3 を選択している可能性があります。

于 2011-12-22T19:28:56.913 に答える