Hello comunity,
I have some really weird problems with this (very simple) GLSL fragment shader. The purpose of this is to “rotate” point sprites.
I’m developing an old school shoot-em-up game and wanted to use point sprites for the bullets and similar stuff. But since I needed rotation for some of the bullets (missiles) I came up with these shaders to modify the point-sprite’s texture coordinates depending on the projectile’s flight direction.
Since the game logic is 2D I send the position and direction as one 4D vertex to the GPU (vec4=(pos_x,pos_y,dir_x,dir_y)). Additonally vertex colors are transmitted.
The vertex shader extracts the rotation information, “repairs” the position (z=0, w=1) and retrieves the vertex color.
The fragment shader then uses the rotation information to modify gl_PointCoord, does the texture look-up and adds the vertex color.
Nothing fancy at all, I’d say. But:
-
when I use a user-defined varying mat4 to transmit the rotation info to the fragment shader, the values get somehow interpolated on its way. Interpolated with what I keep asking myself? It’s just one vertex.
Anyway: I could “solve” this problem using a vec2 instead. Better anyway. -
Now the really funny part: on my Radeon HD3850 (last week’s driver) the texture-lookup is totally corupted whenever I access gl_Color in the fragment shader. If I don’t use it, all is fine. It looks like as if the driver does wrong optimizations. Reformulating the code doesn’t make any difference.
Here are the shaders. It works even on an old Radeon 9600 (though the texture accessed is flipped…) and a Geforce 8400M.
Vertex-shader:
varying vec2 v_rot;
void main(void) {
gl_FrontColor=gl_Color;
vec4 l_position=gl_Vertex;
v_rot=normalize(l_position.zw);
l_position.z=0.0;
l_position.w=1.0;
gl_Position=gl_ModelViewProjectionMatrix*l_position;
}
Fragment-shader:
uniform sampler2D tex;
varying vec2 v_rot;
void main(void) {
vec4 l_uv=vec4(0.0,0.0,gl_PointCoord.xy);
l_uv.zw-=vec2(0.5,0.5);
l_uv.x=l_uv.z*v_rot.x;
l_uv.y=l_uv.w*v_rot.x;
l_uv.x-=l_uv.w*v_rot.y;
l_uv.y+=l_uv.z*v_rot.y;
l_uv.xy+=vec2(0.5,0.5);
// remove *gl_Color from the next line
// and it'll work on HD3850 (of course no different colors anymore)
gl_FragColor=texture2D(tex,l_uv.xy)*gl_Color;
}
Here’s how it should look:
And here’s the HD3850’s output:
Anyone any idea?