Using openGL fragment shaders is an elegant way to draw shapes.

In this case it works by simply drawing a GL_QUAD (A simple unit square), but applying the shader on it to only selectively give certain coordinates in it color.

An openGL shader comes in two parts, a vertex shader and a fragment shader.

This is the vertex shader:

#version 120 // (c) 2013 Joost Yervante Damad // License: GPL // scale unit square to our rect size // and move to it's origin // input: (provided by calling program) uniform vec2 size; // size in x and y direction uniform vec2 move; // location // output: (towards fragment shader) varying vec2 pos2; // adjusted position varying vec2 size2; // size in x and y direction void main() { gl_FrontColor = gl_Color; vec4 vert = gl_Vertex; vert.x = vert.x * size.x; vert.y = vert.y * size.y; vec4 vert2 = vert; vert2.x += move.x; vert2.y += move.y; gl_Position = gl_ModelViewProjectionMatrix * vert2; pos2 = vec2(vert); size2 = size; }

The role of the vertex shader is mainly to move to quad to the wanted coordinates and scale it to the size wanted. After that it is projected on our model.

And this is the fragment shader:

#version 120 // (c) 2013 Joost Yervante Damad // License: GPL

// input provided by vertex shader varying vec2 pos2; // position varying vec2 size2; // size in x and y direction void main() { // r: mininum size of straight side float q = sqrt(2.0)-1.0; float rx = size2.x * q; float ry = size2.y * q; float r = min(rx, ry); float shortest_size = min(size2.x, size2.y); float corner_size = (shortest_size - r) / 2; // a: minimum value where we want to cut off a corner float ax = (size2.x / 2) - corner_size; float ay = (size2.y / 2) - corner_size; // if we are in a corner zone: if (abs(pos2.x) > ax && abs(pos2.y) > ay) { // abs position within corner float x = abs(pos2.x) - ax; float y = abs(pos2.y) - ay; # are we inside the triangle ? if (x + y < corner_size) { gl_FragColor = gl_Color; } // else we're in a normal square zone: } else { glFragColor = gl_Color; } }The fragment shader is where it is decided for individual coordinates if they should be drawn or not. The example here draws a nice rectangle with octagon style cut-off corners.