Surface rendering

15 Oct 2014

I spent some time integrating the triangulation algorithm into the renderer, finally making some use of it, to render the planet as a solid mass instead of line tracing its surface.

The planet

First thing I did was to swap the planet surface I had been using up to now, modeled after the first planet of the original game, for something more interesting. The first planet has a pretty boring topology, and doesn’t really stress the triangulation algorithm. So I reproduced the second planet from the original game, which I’ll refer to as ‘planet 1’ from now on (in typical CS nerd fashion, I start counting from 0 ;-). This is what planet 1 looks like in the original game:

Rendering planet 1

The polygon triangulation algorithm returns a set of vertex indices defined on the vertices of the input polygon, which are perfectly suited for rendering using vertex-, and index buffer objects using glDrawElements. None of this is rocket science, so I’ll keep it short.

The input polygon is created by connecting the left and right endpoints of the planet surface (a line) using 3 new edges (left, bottom, right) to form a counter-clockwise polygon. The vertex coordinates are stored in a vertex buffer object (VBO), and the triangle indices in an index buffer object (IBO). Rendering the VBO and IBO is just a matter of binding the buffers, enabling the VBO as a vertex attribute array for the vertex position attribute using glVertexAttribPointer, then calling glDrawElements to render the whole thing using a single draw call.

For additional eye-candy, I quickly hacked together a texture to apply to the surface polygon, by cropping a 32x32 pixel region from the planet image above. Using the GLKit GLTextureLoader class, loading and binding the texture from a PNG file was a breeze, and applying the texture to the surface polygon was just a matter of using the vertex x and y coordinates as texture coordinates and enabling repeating the texture in both directions. The vertex and fragment shaders are almost the equivalent of a ‘Hello World’ program for shaders, but just for laughs I’ll quote them here:

Vertex shader

attribute vec4 a_position;
attribute vec2 a_texcoords;

uniform mat4 u_projection;
uniform mat4 u_model_view;

varying vec2 v_texcoords;

void main()
{
  gl_Position = u_projection * u_model_view * a_position;
  
  v_texcoords = vec2(a_position.x, a_position.y);
}

Fragment shader

varying lowp vec2 v_texcoords;

uniform lowp vec4 u_color;
uniform sampler2D u_texture;

void main()
{
  lowp vec4 texel = texture2D(u_texture, v_texcoords);
  
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0) * texel;
}

Video

Next steps

I want to write some simple sprite-like interface that can be used to render K14Entity instances as textured quads instead of single-colored blocks. Initially, I’ll stick with single, static textures, but eventually I want to add animation capabilities using sprite frames, and textures that can be generated at run-time using paths.

Development scoreboard

It only took me about 3 hours to hook the triangulation algorithm into the renderer, and modify it to render the planet surface using textured triangles. The total development time is now at about 91 hours. SLOC count is now 1267.