【发布时间】: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.0、255.0,但没有。
要么这本书没有提到什么,要么我错过了一些愚蠢的东西。为什么纹理拒绝在平面上显示?
编辑:我在绘图部分添加了一些代码。我绘制的其余几何图形(使用不同的着色器)完美显示。没有一个使用纹理。
【问题讨论】:
-
texelFetch 中的第二个参数应该介于 0 和 1 之间。gl_FragCoord 为您提供 0 和屏幕分辨率之间的像素坐标。
-
@dari
ivec2不代表整数向量吗? -
@dari 无论如何,如果我将 gl_FragCoord 坐标除以屏幕尺寸,我仍然一无所获。
-
尝试使用 texture() 代替 texelFetch() 和 vec2 代替 ivec2
-
@broncoAbierto:你的
glActiveTexture()调用来晚了,你必须在绑定纹理之前做。但只有在代码中的其他位置切换活动纹理单元时,这才是罪魁祸首。