2011-12-22 6 views
0

私は簡単なテスト目的のためにこのプログラムを持っています。プログラムは2つの1次元テクスチャを作成し、シェーダに渡します。フラグメントシェーダは非常にシンプルです。それはちょうど色のフラグメントを最初のテクスチャのインデックス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次元テクスチャを作成してシェーダに渡すと発生します。何らかの未知の理由のために、シェイダーはそれを気に入らず、もはや機能しません。赤の代わりに黒い四角形が描かれます。以下は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);** 

次に、プログラムが再び機能します。

私の質問はなぜこれが起こっているのですか?シェーダはテクスチャユニットから独立していませんか?テクスチャユニットをサンプラ変数に渡すだけで済むわけではありません。この場合、シェーダを再度実行するには、テクスチャユニットをテクスチャユニット0に戻す必要がありますか?何が起こっている?

+0

これは、同じ次元の2つのテクスチャ(両方とも1-D)でマルチテクスチャを実行する場合にのみ発生すると私はおそらく追加する必要があります。 3-Dおよび1-Dテクスチャはうまく動作するようです。私は2-Dテクスチャについては知らない。 – Einiosaurus

+0

いくつかの種類のドライババグのように聞こえます。どのハードウェアとドライバのバージョンを使用していますか? –

答えて

0

インデックス作成のコードが少し心配です。 IIRCテクセルの正確な値が必要な場合は、左端ではなく中央でヒットする必要があります。基本的にピクセル境界でサンプリングしています。あなたはより多くの

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

ような何かをしたい私はMAX_INDEXはテクスチャではなく、数への最高の有効な指標であると仮定しています。

GL_NEARESTを使用していますが、テクセル3とテクセル4の境界ですぐにサンプリングしています。だから、代わりにテクセル3をピックアップしているかもしれません。

関連する問題