+static void draw_numbers( v3f coord, int number )
+{
+ v3f pos;
+ v3_copy( coord, pos );
+ int digits[8]; int i = 0;
+
+ while( number > 0 && i < 8 )
+ {
+ digits[i ++] = number % 10;
+ number = number / 10;
+ }
+
+ for( int j = 0; j < i; j ++ )
+ {
+ glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, pos );
+ draw_mesh( MESH_NUMBERS_OFFSETS[digits[i-j-1]][0], MESH_NUMBERS_OFFSETS[digits[i-j-1]][1] );
+ pos[0] += pos[2] * 0.75f;
+ }
+}
+
+void vg_render(void)
+{
+ glViewport( 0,0, vg_window_x, vg_window_y );
+
+ glDisable( GL_DEPTH_TEST );
+ glClearColor( 0.369768f, 0.3654f, 0.42f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ v4f const colour_default = {1.0f, 1.0f, 1.0f, 1.0f};
+ v4f const colour_selected = {0.90f, 0.92f, 1.0f, 1.0f};
+
+ // TILE SET RENDERING
+ // todo: just slam everything into a mesh...
+ // when user modifies a tile the neighbours can be easily uploaded to gpu mem
+ // in ~3 subBuffers
+ // Currently we're uploading a fair amount of data every frame anyway.
+ // NOTE: this is for final optimisations ONLY!
+ // ======================================================================
+
+ use_mesh( &world.tile );
+
+ // Draw background
+
+ if(1){
+
+ SHADER_USE( shader_background );
+ glUniformMatrix3fv( SHADER_UNIFORM( shader_background, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, world.background_data );
+ glUniform1i( SHADER_UNIFORM( shader_background, "uTexMain" ), 0 );
+
+ glUniform3f( SHADER_UNIFORM( shader_background, "uOffset" ), -16, -16, 64 );
+ glUniform1f( SHADER_UNIFORM( shader_background, "uVariance" ), 0.02f );
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, world.random_samples );
+ glUniform1i( SHADER_UNIFORM( shader_background, "uSamplerNoise" ), 1 );
+
+ draw_mesh( 0, 2 );
+
+ }
+
+
+ SHADER_USE( shader_tile_main );
+
+ m2x2f subtransform;
+ m2x2_identity( subtransform );
+ glUniformMatrix2fv( SHADER_UNIFORM( shader_tile_main, "uSubTransform" ), 1, GL_FALSE, (float *)subtransform );
+ glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_main, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+ glUniform1f( SHADER_UNIFORM( shader_tile_main, "uGhost" ), 0.0f );
+ glUniform1f( SHADER_UNIFORM( shader_tile_main, "uForeground" ), 0.0f );
+