Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL:碎片着色器中未插值的UV值_Opengl_Glsl_Texture Mapping_Texture2d - Fatal编程技术网

OpenGL:碎片着色器中未插值的UV值

OpenGL:碎片着色器中未插值的UV值,opengl,glsl,texture-mapping,texture2d,Opengl,Glsl,Texture Mapping,Texture2d,我一直在尝试将一些旧的OpenGL代码转换为使用着色器,但在让片段着色器在立方体上绘制纹理时遇到了问题。然而,我看到的只是一个灰色的立方体。我已经调试了我的.obj加载程序代码,我知道UV正在正确加载,我知道纹理正在从磁盘加载并正确地放在GPU上。经过大量测试后,我发现我的UV值并没有在每个三角形的面上插值。也就是说,看起来每个片段都会得到uv值0.0,0.0(这是我缓冲区中的第一个uv值),知道为什么吗 这是我的片段着色器: #version 430 core in vec3 color;

我一直在尝试将一些旧的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);

同样,根据我所读的,一切看起来都是正确的。有什么不对劲吗?

您必须将从顶点到碎片着色器的
uv
交给用户。在“顶点”和“片段”着色器中,不能有同名的
in
属性。相反,您必须在顶点着色器中具有一些
in
属性,然后将该属性传递给一个
out
,该属性与片段着色器中相应的
in
具有相同的名称

在您的情况下,顶点着色器已经有一个
out
可变
uv\u out
。因此,片段着色器也需要命名为
uv\u out
,即在片段着色器中

in vec2 uv_out

当然,名称
uv\u out
有点误导。

您必须将
uv
从顶点到片段着色器进行切换。在“顶点”和“片段”着色器中,不能有同名的
in
属性。相反,您必须在顶点着色器中具有一些
in
属性,然后将该属性传递给一个
out
,该属性与片段着色器中相应的
in
具有相同的名称

在您的情况下,顶点着色器已经有一个
out
可变
uv\u out
。因此,片段着色器也需要命名为
uv\u out
,即在片段着色器中

in vec2 uv_out

当然,名称<代码> UVIOUT 有点误导。

您从代码> GLGETError()/代码>中得到了什么?这甚至不应该编译,在您的<代码>版本> 指令的中间有一些无效的空白,使它成为<代码>版本> /代码>。您还应该在核心GLSL 3.30着色器中使用
texture(…)
而不是
texture2D(…)
(已弃用)。@zero:glGetError()在调用glVertexAttrib3fv(lightposID,&lightpos[0])时返回错误;但是,当我重新启用顶点照明时,这种情况就消失了。错误是“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组分纹理的主题,所以完全没有必要这样做:
vec4(纹理(…).rgb,1.0)
,因为当您对3组分纹理进行采样时,GL会自动为
.a
填充1.0。您从
glGetError()
中得到什么吗?这甚至不应该编译,在您的<代码>版本指令中间有无效的空白,使其成为代码>版本> /代码>。您还应该在核心GLSL 3.30着色器中使用
texture(…)
而不是
texture2D(…)
(已弃用)。@zero:glGetError()在调用glVertexAttrib3fv(lightposID,&lightpos[0])时返回错误;但是,当我重新启用顶点照明时,这种情况就消失了。错误是“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组分纹理的主题,因此完全没有必要这样做:
vec4(纹理(…).rgb,1.0)
,因为当您对3组分纹理进行采样时,GL会自动为
.a
填充1.0。这非常有效,我不敢相信我忘记了:)谢谢!这很好,我不敢相信我竟然忘了:)谢谢!