Fishy glGetAttribLocation返回-1

时间:2014-11-08 02:42:23

标签: opengl glsl

我尝试使用由两个着色器组成的着色器程序。

Ortho.vert:

uniform vec2 ViewOrigin;
uniform vec2 ViewSize;

in vec2 Coord;

void main ()
{
  gl_Position = vec4((Coord.x - ViewOrigin.x) / ViewSize.x,
                     1.0f - (Coord.y - ViewOrigin.y) / ViewSize.y,
                     0.0f, 1.0f);
}

Tiles.frag:

uniform sampler2D Texture;
uniform sampler2D LightMap;

in vec2 TextureCoord;
in vec2 LightMapCoord;

void main ()
{
  vec4 textureColor  = texture2D(Texture, TextureCoord);
  vec4 lightMapColor = texture2D(LightMap, LightMapCoord);

  gl_FragColor = vec4(textureColor.rgb * lightMapColor.rgb, 1.0f);
}

glGetAttribLocationTextureCoordLightMapCoord返回-1。我已经读过有关编译器优化掉未使用的属性的实例,但在本例中您可以看到它们已被清楚地使用。是否有关于启用采样器所需的OpenGL状态(glEnable等)?我不确定这里还有什么不对的。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

属性不能直接进入片段着色器。它们的全名是顶点属性,这意味着它们为每个顶点提供值,并且是顶点着色器的输入。

片段着色器可以包含in个变量,但它们与顶点属性不对应。它们需要与顶点着色器的out变量匹配。

因此,您需要做的是将属性定义为顶点着色器的输入,然后将值从顶点着色器传递到片段着色器。在顶点着色器中,这可能如下所示:

uniform vec2 ViewOrigin;
uniform vec2 ViewSize;

in vec2 Coord;
in vec2 TextureCoord;
in vec2 LightMapCoord;

out FragTextureCoord;
out FragLightMapCoord;

void main ()
{
    gl_Position = vec4((Coord.x - ViewOrigin.x) / ViewSize.x,
                       1.0f - (Coord.y - ViewOrigin.y) / ViewSize.y,
                       0.0f, 1.0f);
    FragTextureCoord = TextureCoord;
    FragLightMapCoord = LightMapCoord;
}

然后在片段着色器中,声明与片段着色器的in变量匹配的out个变量。这些变量将接收您在顶点着色器中写入相应out变量的内容的每片段插值:

uniform sampler2D Texture;
uniform sampler2D LightMap;

in vec2 FragTextureCoord;
in vec2 FragLightMapCoord;

void main ()
{
    vec4 textureColor  = texture2D(Texture, FragTextureCoord);
    vec4 lightMapColor = texture2D(LightMap, FragLightMapCoord);

    gl_FragColor = vec4(textureColor.rgb * lightMapColor.rgb, 1.0f);
}

必须在顶点着色器中接收属性值,并将完全相同的值显式传递给片段着色器,可能看起来很麻烦。要意识到的重要一点是,这只是一个更通用机制的特例。您可以使用任何类型的计算来计算out值的值,而不是简单地将属性值直接传递给顶点着色器中的out变量,这在更复杂的着色器中通常是必需的。