【发布时间】:2014-01-23 10:16:58
【问题描述】:
我一直在尝试将一些旧的 OpenGL 代码转换为使用着色器,但在让我的片段着色器在立方体上绘制纹理时遇到了问题。然而,我看到的只是一个灰色的立方体。我已经调试了我的 .obj 加载器代码,并且我知道 UV 正在正确加载,并且我知道纹理正在从磁盘加载并正确放置在 GPU 上。经过大量测试后,我发现我的 UV 值没有在每个三角形的面上进行插值。也就是说,看起来每个片段的 uv 值都是 0.0,0.0(这是我缓冲区中的第一个 uv 值)有什么想法吗?
这是我的片段着色器:
#version 430 core
in vec3 color;
in vec2 uv;
uniform sampler2D tex;
out vec3 frag_color;
void main()
{
//frag_color = color;
frag_color = texture(tex,uv).rgb;
}
还有我的顶点着色器:
#version 430 core
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv;
uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
attribute vec3 lightPos;
out vec3 color;
out vec2 uv_out;
void main()
{
uv_out = uv;
vec3 modelViewVertex = vec3(mvMatrix * vec4(pos,1.0));
vec3 modelViewNormal = vec3(mvMatrix * vec4(normal,0.0));
vec3 modelViewLightPos = vec3(mvMatrix * vec4(lightPos,1.0));
vec3 lightVector = normalize(lightPos - pos);
float diffuse = clamp(dot(normal,lightVector),0,1);
gl_Position = mvpMatrix * vec4(pos,1.0);
color = vec3(diffuse,0.0,0.0);
}
这里是我设置缓冲区的地方:
glGenVertexArrays(1, &vertexBufferObjectID);
glBindVertexArray(vertexBufferObjectID);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), &vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size()*sizeof(vec3), &normals[0], GL_STATIC_DRAW);
glGenBuffers(1, &UVBuffer);
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(vec2), &uvs[0], GL_STATIC_DRAW);
最后,这是我的渲染循环:
glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureID, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;
glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, &mvpMatrix[0][0]);
mvMatrix = viewMatrix * modelMatrix;
glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, &mvMatrix[0][0]);
glVertexAttrib3fv(lightposID, &lightpos[0]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
再一次,根据我的阅读内容,一切看起来都是正确的。有什么不对劲的地方吗?
【问题讨论】:
-
你从
glGetError()得到什么了吗? -
这甚至不应该编译,你的
#version指令中间有一些无效的空格,使它成为# version。您还应该在核心 GLSL 3.30 着色器中使用texture (...)而不是texture2D (...)(已弃用)。 -
@zero: 当我调用 glVertexAttrib3fv(lightposID, &lightpos[0]); 时 glGetError() 返回错误但是,当我重新启用顶点照明时,它就消失了。错误是“lightposID”没有正确初始化(我猜着色器优化了它,因为我没有使用它)除此之外,什么都没有。
-
@Andon,我根据您的建议(见上文)修改了代码,但仍然没有。不知道为什么即使我有语法错误它仍然在编译,我猜 Nvidia 的驱动程序是相当宽松的
-
好吧,还有另一个问题:
glTexImage2D(GL_TEXTURE_2D, 0, 3, surf->w, surf->h, 0, GL_BGR, GL_UNSIGNED_BYTE, surf->pixels)。假设这是一个核心配置文件上下文,将您希望图像具有的通道数作为内部格式传递给glTexImage2D (...)不再可接受,您需要使用实际格式枚举(例如GL_RGB8而不是 3)。由于我们讨论的是 3 分量纹理,因此完全没有必要这样做:vec4 (texture (...).rgb, 1.0),因为当您对 3 分量纹理进行采样时,GL 会自动为.a填充 1.0。
标签: opengl glsl texture-mapping texture2d