我正在尝试按照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.0
,255.0
,但没有。
这本书没有提到某些东西,或者我错过了一些愚蠢的东西。为什么纹理拒绝在平面上显示?
编辑:我在绘图部分添加了一些代码。我绘制的其余几何图形(使用不同的着色器)显示完美。它们都不使用纹理。
答案 0 :(得分:0)
我终于解决了这个问题,虽然目前尚不清楚问题究竟是什么。
我使用glTexImage2D
代替glTexStorage2D
和glTexSubImage2D
来显示纹理。
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);
我仍然要弄清楚为什么会这样,但至少我让它发挥作用。