Reputation:
I'm trying to use a shader program that consists of two shaders.
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);
}
glGetAttribLocation
is returning -1 for TextureCoord
and LightMapCoord
. I've read about instances where the compiler optimizes away attributes that aren't used, but in this example you can see that they are clearly used. Is there something about the OpenGL state (glEnable
, etc.) that is required in order to enable samplers? I'm not sure what else could be wrong here. Any help is appreciated.
Upvotes: 0
Views: 108
Reputation: 54642
Attributes cannot go directly into the fragment shader. Their full name is vertex attributes, which means that they provide values per vertex, and are inputs to the vertex shader.
Fragment shaders can have in
variables, but they do not correspond to vertex attributes. They need to match up with out
variables of the vertex shader.
So what you need to do to get this working is to define the attributes as inputs to the vertex shader, and then pass the values from the vertex shader to the fragment shader. In the vertex shader, this could look like this:
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;
}
Then in the fragment shader, you declare in
variables that match the out
variables of the fragment shader. These variables will receive the per-fragment interpolated values of the what you wrote to the corresponding out
variables in the vertex shader:
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);
}
Having to receive the attribute values in the vertex shader, and explicitly passing the exact same values through to the fragment shader, may look cumbersome. The important thing to realize is that this is just a special case of a much more generic mechanism. Instead of simply passing the attribute value directly to the out
variable in the vertex shader, you can obviously apply any kind of computation to calculate the values of the out
values, which is often necessary in more complex shaders.
Upvotes: 1