OpenGL - texelFetch什么都不提取

时间:2014-07-12 13:57:06

标签: opengl glsl

我正在尝试按照OpenGL SuperBible第6版绘制纹理平面。但由于某种原因,我失败了。

这是我的纹理初始化代码。

GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
int w = 256;
int h = 256;
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, w, h);
float * data = new float[w * h * 4];
//This just creates some image data
generateTexture(data, w, h);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_FLOAT, data);
delete [] data;

这是飞机物体。对象本身是绘制的,只是没有纹理。

glGenBuffers(1, &planeBuffer);
glBindBuffer(GL_ARRAY_BUFFER, planeBuffer);
glBufferData(GL_ARRAY_BUFFER,
             sizeof(planePositions),
             planePositions,
             GL_STATIC_DRAW);

这些是我的顶点和片段着色器。

#version 430 core
layout (location = 0) in vec3 position;
uniform mat4 proj, view;
void main(void){      
      gl_Position = proj * view * vec4 (position, 1.0);      
}


#version 430 core
uniform sampler2D s;
out vec4 frag_color;
void main () {
    frag_color = texelFetch(s, ivec2(gl_FragCoord.xy), 0);
};

我画得像这样

glUseProgram(textureProgram);

GLuint projLocation = glGetUniformLocation (textureProgram, "proj");
glUniformMatrix4fv (projLocation, 1, GL_FALSE, projectionSource);

GLuint viewLocation = glGetUniformLocation (textureProgram, "view");
glUniformMatrix4fv (viewLocation, 1, GL_FALSE, viewSource);

glBindBuffer(GL_ARRAY_BUFFER, planeBuffer);
GLuint positionLocation = glGetAttribLocation(textureProgram, "position");
glVertexAttribPointer (positionLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);               
glEnableVertexAttribArray (positionLocation);

glActiveTexture(GL_TEXTURE0);    
glBindTexture(GL_TEXTURE_2D, texture);                 
GLuint ts = glGetUniformLocation (textureProgram, "s");
glUniform1i(ts, 0);

glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray (positionLocation);                           

//Afterwards I draw more geometry with other shaders. This shows correctly
glUseProgram(shaderProgram);
//Bind buffers, matrices, drawarrays, etc

但我只是得到一架黑色无纹理的飞机。如果我之后通过添加另一行来覆盖frag_color作业,就像这样

frag_color = vec4(1.0);

它有效,即我得到一个白色平面,因此着色器似乎正常工作。

我从glGetError()收到任何错误。

兼容性:

OpenGL version supported: 4.2.12337 Compatibility Profile Context 13.101
GLSL version supported: 4.30

data数组确实包含介于0和1之间的值。我还尝试将一些随机坐标硬编码到texelFetch()函数中,但我总是得到一个黑色平面。看起来好像sampler2D只包含零。我还尝试将data中包含的值硬编码为1.0255.0,但没有。

这本书没有提到某些东西,或者我错过了一些愚蠢的东西。为什么纹理拒绝在平面上显示?

编辑:我在绘图部分添加了一些代码。我绘制的其余几何图形(使用不同的着色器)显示完美。它们都不使用纹理。

1 个答案:

答案 0 :(得分:0)

我终于解决了这个问题,虽然目前尚不清楚问题究竟是什么。

我使用glTexImage2D代替glTexStorage2DglTexSubImage2D来显示纹理。

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, data);

我还必须明确设置参数,即使我使用texelFetch()

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

没有必要明确地绑定制服。

奇怪的是,根据文档,glTexStorage2D等同于:

for (i = 0; i < levels; i++) {
    glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
    width = max(1, (width / 2));
    height = max(1, (height / 2));
}

然而,这种组合不起作用。

glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA, w, h);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_FLOAT, data);

我仍然要弄清楚为什么会这样,但至少我让它发挥作用。

相关问题