【问题标题】:OpenGL - texelFetch fetches nothingOpenGL - texelFetch 什么都不获取
【发布时间】:2014-07-12 13:57:05
【问题描述】:

我正在尝试按照 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,但没有。

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

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

【问题讨论】:

  • texelFetch 中的第二个参数应该介于 0 和 1 之间。gl_FragCoord 为您提供 0 和屏幕分辨率之间的像素坐标。
  • @dari ivec2 不代表整数向量吗?
  • @dari 无论如何,如果我将 gl_FragCoord 坐标除以屏幕尺寸,我仍然一无所获。
  • 尝试使用 texture() 代替 texelFetch() 和 vec2 代替 ivec2
  • @broncoAbierto:你的glActiveTexture() 调用来晚了,你必须在绑定纹理之前做。但只有在代码中的其他位置切换活动纹理单元时,这才是罪魁祸首。

标签: opengl glsl


【解决方案1】:

我终于解决了这个问题,虽然还不清楚到底是什么问题。

我使用 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);

我仍然需要弄清楚为什么会这样,但至少我让它工作了。

【讨论】:

  • 可以解释为什么它不适用于这些参数。 glTexStorage2D() 不接受未调整大小的内部格式,因此传递 GL_RGBA 是错误的。您需要像GL_RGBA8 这样的大小格式。我不明白为什么它在您的原始代码中不起作用,因为 GL_RGBA32F 是一个有效的参数。您是否尝试在原始代码中使用glGetError(),看看它是否抱怨什么?
  • 我明白了。我没有从glGetError() 得到任何错误,但我会摆弄glTexStorage2D() 并尝试使用该组功能使其工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多