0

我有这个程序用于简单的测试目的。该程序创建两个 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>,它是红色的。因此,上面着色器的结果是一个红色方块。当我创建第二个一维纹理并将其传递给着色器时,问题就出现了。由于某种未知的原因,着色器不喜欢它,它不再起作用,并且绘制了一个黑色方块而不是红色方块。这是 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;

奇怪的是,如果我在创建第二个纹理后立即将活动纹理单元切换到第一个纹理的纹理单元,那么程序会再次运行,并绘制一个红色方块。

/* =========================================
 * 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,但您现在正在对 texel 3 和 texel 4 的边界进行采样。所以它可能会选择 texel 3。

于 2011-12-22T19:28:56.913 回答