int main(void)
{

My Blog

Posted 02/15/12 @ 5:13pm - By Ross

Dashed Lines!

So I recently have been playing around with shaders on my Android project and with the removal of stippling from the OpenGL I thought that I had found the perfect opportunity to use a shader. With some thoughts in mind I decided to search the interwebs to see if I was thinking along the right lines. Unfortunately there isn’t much out there on OpenGL ES 2.0 yet. So it fell to me to come up with something that would work, and work it does!

The basic premise was pretty simple. Find out the world coordinates of each fragment and then, using that, determine it’s length from the line origin. Then plug that into a cosine function and alternate drawing it based off if the value returned is negative or positive.

The key to the whole thing is sourcePoint being passed in as the origin of the line. It’s also worth noting that I pass in the modelview matrix and multiply it with the vertex to determine where it is in world space. The use of position as a varying variable is also important since it is interpolated based off all the vertices that affect it. This allows for the position variable in the fragment shader to be the actual position of the fragment in world space.

With all this, I determine the distance between those two points and then use the cosine function (modified based off how I want the dashes to look) to decide to draw it or not.

So without further ado, here is my vertex shader:

1
2
3
4
5
6
7
8
9
10
11
12
uniform mat4 u_modelViewProjectionMatrix;
uniform mat4 mv;
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
varying vec4 position;

void main() {
  gl_Position = u_modelViewProjectionMatrix * a_position;
  position = mv * a_position;
  v_color = a_color;
}

and the fragment shader:

1
2
3
4
5
6
7
8
9
10
11
12
precision mediump float;
uniform vec2 sourcePoint;
varying vec4 v_color;
varying vec4 position;

void main() {
  if (cos(0.1*abs(distance(sourcePoint.xy, position.xy))) + 0.5 > 0.0) {
    gl_FragColor = vec4(0,0,0,0);
  } else {
    gl_FragColor = v_color;
  }
}

return 0;

}