first sorta working port
authorhgn <hgodden00@gmail.com>
Wed, 27 Dec 2023 02:32:15 +0000 (02:32 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 27 Dec 2023 02:32:15 +0000 (02:32 +0000)
17 files changed:
build.c
fishladder_resources_vg1.h
fishladder_vg1.c
input.h [new file with mode: 0644]
marblecomp.c
shaders/background.h [new file with mode: 0644]
shaders/ball.h [new file with mode: 0644]
shaders/button.h [new file with mode: 0644]
shaders/buttons.h [new file with mode: 0644]
shaders/post_blur.h [new file with mode: 0644]
shaders/post_comp.h [new file with mode: 0644]
shaders/post_darken.h [new file with mode: 0644]
shaders/sprite.h [new file with mode: 0644]
shaders/tile_colour.h [new file with mode: 0644]
shaders/tile_main.h [new file with mode: 0644]
shaders/wire.h [new file with mode: 0644]
vg_config.h

diff --git a/build.c b/build.c
index 882748959c8e396470b435840c9f4abd10358577..bf4173ec72c2d61694abda553019f0cca8ef54ac 100644 (file)
--- a/build.c
+++ b/build.c
@@ -15,7 +15,9 @@ u32 optimize_test_compile = 0;
 void build_game_content(void){
    const char *project_name = vg_build.project_name.buffer;
    vg_low( "Building game content structure\n" );
-   vg_symlink( "textures", "textures" );
+   vg_symlink( "textures_qoi", "textures" );
+   vg_symlink( "maps", "maps" );
+   vg_symlink( "sound", "sound" );
    vg_syscall( "mkdir -p bin/%s/cfg", project_name );
 }
 
@@ -117,5 +119,14 @@ void build_shaders(void){
    vg_shader_set_include_dir( "shaders" );
 
    /* Scene */
-   //_S( "scene_standard",            "scene.vs", "scene_standard.fs" );
+   _S( "tile_colour", "tile_colour.vs.glsl", "tile_colour.fs.glsl" );
+       _S( "tile_main", "tile_main.vs.glsl", "tile_main.fs.glsl" );
+       _S( "ball", "ball.vs.glsl", "ball.fs.glsl" );
+       _S( "background", "background.vs.glsl", "background.fs.glsl" );
+       _S( "wire", "wire.vs.glsl", "wire.fs.glsl" );
+       _S( "button", "button.vs.glsl", "button.fs.glsl" );
+       _S( "sprite", "sprite.vs.glsl", "sprite.fs.glsl" );
+   _S( "post_darken", "post_darken.vs.glsl", "post_darken.fs.glsl" );
+   _S( "post_comp", "post_comp.vs.glsl", "post_comp.fs.glsl" );
+   _S( "post_blur", "post_blur.vs.glsl", "post_blur.fs.glsl" );
 }
index 196f0e5d5ccbeb6d4185bc870e2496154a8d5f09..7d0ea2fc7c69bb016dce114add3fd48e4b6dc107 100644 (file)
@@ -1,3 +1,30 @@
+#include "shaders/tile_colour.h"
+#include "shaders/tile_main.h"
+#include "shaders/ball.h"
+#include "shaders/background.h"
+#include "shaders/wire.h"
+#include "shaders/button.h"
+#include "shaders/sprite.h"
+#include "shaders/post_darken.h"
+#include "shaders/post_comp.h"
+#include "shaders/post_blur.h"
+
+/* FIXME */
+#define UI_GLYPH_SPACING_X 8
+
+void _mc_vg1_register(void){
+   shader_tile_colour_register();
+   shader_tile_main_register();
+   shader_ball_register();
+   shader_background_register();
+   shader_wire_register();
+   shader_button_register();
+   shader_sprite_register();
+   shader_post_darken_register();
+   shader_post_comp_register();
+   shader_post_blur_register();
+}
+
 // TEXTURES
 // ===========================================================================================================
 
@@ -112,7 +139,7 @@ static void *load_and_play_bgm( void *_inf )
 
 #define INIT_AUDIO( X ) audio_clip_loadn( X, vg_list_size(X), NULL );
 
-static void resource_load_main(void){
+static void _mc_resource_load_main(void){
        // Textures // UI
    for( u32 i=0; i<vg_list_size(texture_list); i ++ ){
       struct vg1_tex2d *tex = texture_list[i];
@@ -133,462 +160,6 @@ static void resource_load_main(void){
 #endif
 }
 
-// SHADERS
-// ===========================================================================================================
-
-SHADER_DEFINE( shader_tile_colour,
-
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform mat3 uPv;"
-       "uniform vec3 uOffset;"
-       ""
-       "void main()"
-       "{"
-               "gl_Position = vec4( uPv * vec3( a_co * uOffset.z + uOffset.xy, 1.0 ), 1.0 );"
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       "uniform vec4 uColour;"
-       ""
-       "void main()"
-       "{"
-               "FragColor = uColour;"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uOffset", "uColour" })
-)
-
-SHADER_DEFINE( shader_ball,
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform vec3 uOffset;"
-       "uniform mat3 uPv;"
-       ""
-       "out vec4 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               // Vertex transform
-               "vec3 worldpos = vec3( (a_co * 0.5 - 0.25) * uOffset.z + uOffset.xy, 1.0 );"
-               "gl_Position = vec4( uPv * worldpos, 1.0 );"
-
-               // Create texture coords
-               "aTexCoords = vec4( a_co, worldpos.xy );"
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       ""
-       "uniform sampler2D uTexMain;"
-       "uniform vec3 uColour;"
-       "uniform vec2 uTexOffset;"
-       ""
-       "in vec4 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec2 center_coords = aTexCoords.xy - 0.5;"
-               "vec2 center_coords_sqr = center_coords*center_coords;"
-               "float circle_factor = smoothstep( 0.07, 0.0625, center_coords_sqr.x+center_coords_sqr.y );"
-               
-               "float bulge_amt = center_coords_sqr.x+center_coords_sqr.y;"
-               "vec2 warped_coords = aTexCoords.zw+uTexOffset - center_coords;"
-               "vec4 noise_sample = texture( uTexMain, warped_coords );"
-               
-               "float rim_light = (center_coords_sqr.x+center_coords_sqr.y)*15.0;"
-               
-               "vec2 shadow_coords = center_coords + vec2(0.02,0.07);"
-               "vec2 shadow_coords_sqr = shadow_coords*shadow_coords;"
-               "float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);"
-               
-               "vec3 marble_comp = uColour*0.6 + (noise_sample.x*2.7+pow(rim_light,3.0)*2.0) * 0.1;"
-               //"vec4 colour_comp = mix( vec4(0.74,0.53,0.34,shadow), vec4(marble_comp,1.0), circle_factor );"
-               "vec4 colour_comp = mix( vec4(0.0,0.0,0.0,shadow), vec4(marble_comp,1.0), circle_factor );"
-               
-               "FragColor = colour_comp;"
-       "}"
-       ,
-       UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv", "uTexOffset" })
-)
-
-SHADER_DEFINE( shader_tile_main,
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform vec4 uOffset;" // Tile x/y, uv x/y
-       "uniform mat3 uPv;"
-       "uniform mat2 uSubTransform;"
-       "uniform float uVisibility;"
-       ""
-       "out vec4 aTexCoords;"
-       "out vec2 aWorldCoords;"
-       ""
-       "vec2 hash22(vec2 p)"
-       "{"
-               "vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));"
-               "p3 += dot(p3, p3.yzx+33.33);"
-               "return fract((p3.xx+p3.yz)*p3.zy);"
-       "}"
-       ""
-       "void main()"
-       "{"
-               "vec2 hash_val = hash22(uOffset.xy);"
-               "float scaling_factor = smoothstep( hash_val.x, hash_val.x+1.0, uVisibility );"
-
-               // Vertex transform
-               "vec2 subtransform = uSubTransform * (a_co-0.5) * scaling_factor + 0.5;"
-               "vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );"
-               "gl_Position = vec4( uPv * worldpos, 1.0 );"
-
-               // Create texture coords
-               "vec2 random_offset = floor(hash_val * 4.0) * 0.25;"
-               "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
-               "aTexCoords = vec4((edge_safe_coords + uOffset.zw) * 0.25, edge_safe_coords * 0.25 + random_offset );"
-               "aWorldCoords = worldpos.xy;"           
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       ""
-       "uniform sampler2D uTexGlyphs;"
-   "uniform sampler2D uTexGlow;"
-       "uniform sampler2D uTexWood;"
-       "uniform float uGhost;"
-       "uniform float uForeground;"
-       "uniform vec2 uMousePos;"
-       "uniform vec4 uColour;"
-   "uniform vec3 uShadowing;"
-   "uniform vec3 uGlowA;"
-   "uniform vec3 uGlowB;"
-       ""
-       "in vec4 aTexCoords;"
-       "in vec2 aWorldCoords;"
-       ""
-       "void main()"
-       "{"
-               //"vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 ) * 0.97;"
-               //"vec3 shadowing_colour = vec3( 0.8, 0.8, 0.8 );"
-
-               "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );"
-      "vec4 glyph_glow = texture( uTexGlow, aTexCoords.xy );"
-               "vec4 wood = texture( uTexWood, aTexCoords.zw );"
-               "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );"
-               "vec3 wood_comp = mix( wood_secondary.rgb * uShadowing, wood.rgb, clamp( glyph.b*2.0-1.0, 0.0, 1.0 ) );"
-               
-               //"vec3 shadows = mix( vec3( 0.85, 0.7344, 0.561 ), vec3(1.0,1.0,1.0), glyph.r );"
-               "vec3 shadows = mix( uShadowing, vec3(1.0,1.0,1.0), glyph.r );"
-               
-               "vec4 output_regular = vec4( wood_comp * shadows, mix( glyph.a, glyph.b, uForeground ) );"
-               
-               "float ghost_dist = clamp( 1.5 - distance(uMousePos, aWorldCoords), 0.0, 1.0 );"
-               "vec4 output_ghost = vec4( 1.0, 1.0, 1.0, glyph.g*ghost_dist );"
-      "vec4 glow_comp = vec4(glyph_glow.b*uGlowA+glyph_glow.g*uGlowB,0.0);"
-               
-               "FragColor = mix( output_regular, output_ghost, uGhost )*uColour + glow_comp;"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", 
-         "uColour", "uForeground", "uVisibility", "uShadowing", "uTexGlow",
-         "uGlowA", "uGlowB" })
-)
-
-SHADER_DEFINE( shader_background,
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform mat3 uPv;"
-       "uniform vec3 uOffset;"
-       ""
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec2 world_pos = a_co * uOffset.z + uOffset.xy;"
-               "gl_Position = vec4( uPv * vec3( world_pos, 1.0 ), 1.0 );"
-               "aTexCoords = a_co;"
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       ""
-       "uniform sampler2D uTexMain;"
-       "uniform sampler2D uSamplerNoise;"
-       "uniform float uVariance;"
-       "uniform float uVisibility;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec4 data_this_tile = texture( uTexMain, aTexCoords );"
-
-               "float ao_accum = 0.0;"
-
-      "vec2 random_noise;"
-
-               "for( int i=0; i<10; ++i )"
-               "{"
-                       "random_noise = (texture( uSamplerNoise, aTexCoords * 10.0 + float(i) * 0.2 ).xy - vec2( 0.5, 0.5 )) * uVariance;"
-                       "vec4 background = texture( uTexMain, aTexCoords + random_noise );"
-         "float height_diff = min(data_this_tile.r - background.r,0.0);"
-
-                       "ao_accum += height_diff * clamp((1.0 - length( random_noise )), 0.0, 1.0);"
-               "}"
-               "ao_accum *= 0.15;"
-               
-#if 0
-               "vec3 colour_main = mix( vec3( 0.369768, 0.3654, 0.42 ), vec3( 0.275, 0.388, 0.553 ), data_this_tile.g * uVisibility );"
-#endif
-
-               "vec2 square_coords = fract( aTexCoords * 64.0 );"
-               "vec2 grid_coords = abs( square_coords - 0.5 );"
-      "float gridline = step( 0.49, max(grid_coords.x,grid_coords.y) );"
-
-               "vec3 colour_main = mix( vec3( 0.14 ) + random_noise.x*0.5, vec3( 0.1 ) + gridline*0.02, data_this_tile.g * uVisibility );"
-               "FragColor = vec4( colour_main + ao_accum*0.05, 1.0 );"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uOffset", "uTexMain", "uVariance", "uSamplerNoise", "uVisibility" })
-)
-
-SHADER_DEFINE( shader_wire,
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform vec3 uStart;"
-       "uniform vec3 uEnd;"
-       "uniform mat3 uPv;"
-       "uniform float uCurve;"
-       ""
-       "out vec2 aTexCoords;"
-       ""
-       "vec3 sample_curve_time( float t )"
-       "{"
-               "vec3 line_coord = mix( uStart, uEnd, t );"
-
-               "float curve_amt = 1.0-(pow((t*2.0-1.0),2.0));"
-               "return vec3( line_coord.x, line_coord.y - curve_amt*uCurve, line_coord.z );"
-       "}"
-       ""
-       "void main()"
-       "{"
-               // Vertex transform
-               "vec3 p0 = sample_curve_time( a_co.x );"
-               "vec3 p1 = sample_curve_time( a_co.x + 0.025 );"
-               
-               "vec2 line_tangent = normalize(p1.xy-p0.xy);"
-               "vec2 line_normal = vec2( -line_tangent.y, line_tangent.x );"
-               
-               "vec2 worldfinal = p0.xy + line_normal*a_co.y*p0.z;"
-               
-               "gl_Position = vec4( uPv * vec3(worldfinal, 1.0), 1.0 );"
-
-               // Create texture coords (todo: include stretch adjusted coords?)
-               "aTexCoords = vec2( a_co.x, a_co.y + 0.5 );"
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       ""
-       "uniform sampler2D uTexMain;"
-       "uniform vec4 uColour;"
-       "uniform float uTime;"
-       "uniform float uGlow;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               // Compute shadowing
-               "float shadow = 1.0 - abs(aTexCoords.y - 0.5) * 2.0;"
-               "float masking = smoothstep( 0.5, 0.8, shadow );"
-               
-               "vec3 colour_comp = mix( vec3(0.0,0.0,0.0), uColour.rgb, masking );"
-               
-               "float flow_thing = fract( aTexCoords.x + uTime );"
-               "vec3 final_comp = colour_comp + flow_thing * uGlow;"
-               
-               "FragColor = vec4( final_comp, max( shadow* 0.2, masking ) * uColour.a );"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uColour", "uTexMain", "uStart", "uEnd", "uCurve", "uTime", "uGlow" })
-)
-
-SHADER_DEFINE( shader_buttons,
-       // VERTEX
-       "layout (location=0) in vec2 a_co;"
-       "uniform vec4 uOffset;" // Tile x/y, uv x/y
-       "uniform mat3 uPv;"
-       ""
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               // Vertex transform
-               "vec3 worldpos = vec3( a_co + uOffset.xy, 1.0 );"
-               "gl_Position = vec4( uPv * worldpos, 1.0 );"
-
-               // Create texture coords
-               "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
-               "aTexCoords = (edge_safe_coords + uOffset.zw) * 0.25;"  
-       "}",
-       
-       // FRAGMENT
-       "out vec4 FragColor;"
-       ""
-       "uniform sampler2D uTexMain;"
-       "uniform vec4 uColour;" // rgb, light amount
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec4 glyph = texture( uTexMain, aTexCoords.xy );"
-               
-               "FragColor = vec4( uColour.rgb * (mix(glyph.r, glyph.g, uColour.a)+0.02)*2.6 + glyph.b * 0.4, glyph.a );"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uOffset", "uTexMain", "uColour" })
-)
-
-SHADER_DEFINE( shader_sprite,
-
-       // VERTEX
-       "layout (location=0) in vec2 a_co;" // quad mesh
-       "uniform vec4 uUv;"
-       "uniform vec3 uPos;"
-       ""
-       "uniform mat3 uPv;"
-       ""
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec2 vertex_world = uUv.zw * (a_co-0.5) * uPos.z + uPos.xy;"
-               "gl_Position = vec4( uPv * vec3( vertex_world, 1.0 ), 1.0 );"
-               "aTexCoords = uUv.xy + a_co*uUv.zw;"
-       "}",
-       
-       // FRAGMENT
-       "uniform sampler2D uTexMain;"
-       "out vec4 FragColor;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec4 texture_sample = texture( uTexMain, aTexCoords );"
-               "FragColor = texture_sample;"
-       "}"
-       ,
-       UNIFORMS({ "uPv", "uTexMain", "uUv", "uPos" })
-)
-
-SHADER_DEFINE( shader_post_darken,
-   "layout (location=0) in vec2 a_co;"
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );"
-               "aTexCoords = a_co;"
-       "}",
-
-       "uniform sampler2D uTexMain;"
-       "out vec4 FragColor;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec4 texture_sample = texture( uTexMain, aTexCoords );"
-               "FragColor = vec4(pow(texture_sample.rgb,vec3(2.2)), 1.0);"
-       "}"
-   ,
-   UNIFORMS({"uTexMain"})
-)
-
-SHADER_DEFINE( shader_post_blur,
-   "layout (location=0) in vec2 a_co;"
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );"
-               "aTexCoords = a_co;"
-       "}",
-
-       "uniform sampler2D uTexMain;"
-   "uniform vec2 uDir;"
-       "out vec4 FragColor;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-      "vec4 colour = vec4(0.0);"
-
-      "vec2 off1 = vec2(1.411764705882353)  * uDir;"
-      "vec2 off2 = vec2(3.2941176470588234) * uDir;"
-      "vec2 off3 = vec2(5.176470588235294)  * uDir;"
-      "colour += texture2D( uTexMain, aTexCoords ) * 0.1964825501511404;"
-      "colour += texture2D( uTexMain, aTexCoords + off1 ) * 0.2969069646728344;"
-      "colour += texture2D( uTexMain, aTexCoords - off1 ) * 0.2969069646728344;"
-      "colour += texture2D( uTexMain, aTexCoords + off2 ) * 0.09447039785044732;"
-      "colour += texture2D( uTexMain, aTexCoords - off2 ) * 0.09447039785044732;"
-      "colour += texture2D( uTexMain, aTexCoords + off3 ) * 0.010381362401148057;"
-      "colour += texture2D( uTexMain, aTexCoords - off3 ) * 0.010381362401148057;"
-               "FragColor = colour;"
-       "}"
-   ,
-   UNIFORMS({"uTexMain","uDir"})
-)
-
-SHADER_DEFINE( shader_post_comp,
-   "layout (location=0) in vec2 a_co;"
-       "out vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );"
-               "aTexCoords = a_co;"
-       "}",
-
-       "uniform sampler2D uTexMain;"
-   "uniform sampler2D uTexBloom;"
-   "uniform vec2 uComp;" /* x: bloom, y: vignette */
-       "out vec4 FragColor;"
-       ""
-       "in vec2 aTexCoords;"
-       ""
-       "void main()"
-       "{"
-               "vec4 texture_sample = texture( uTexMain, aTexCoords );"
-      "vec4 bloom_sample = texture( uTexBloom, aTexCoords );"
-      
-      "vec2 vigCoord = aTexCoords - 0.5;"
-      "float vig = pow(1.0 - dot( vigCoord, vigCoord ), 2.0);"
-      
-               "FragColor = (texture_sample + bloom_sample*0.3*uComp.x)"
-                  " * max(uComp.y, vig);"
-       "}"
-   ,
-   UNIFORMS({"uTexMain", "uTexBloom", "uComp"})
-)
-
-void vg_register(void)
-{
-       SHADER_INIT( shader_tile_colour );
-       SHADER_INIT( shader_tile_main );
-       SHADER_INIT( shader_ball );
-       SHADER_INIT( shader_background );
-       SHADER_INIT( shader_wire );
-       SHADER_INIT( shader_buttons );
-       SHADER_INIT( shader_sprite );
-   SHADER_INIT( shader_post_darken );
-   SHADER_INIT( shader_post_comp );
-   SHADER_INIT( shader_post_blur );
-}
-
 /*
        0000 0   | 0001 1   | 0010 2   | 0011 3
                           |          |    |     |    |
index 003505ba00d377750211da47293d5722b2a0898d..ddd2687407faf1e366ee1640fc53fdb360878731 100644 (file)
@@ -188,7 +188,9 @@ static struct world
                float lvl_load_time;
 
                float world_transition;
+#if 0
       ui_ctx world_text;
+#endif
 
       GLuint framebuffer,
              colourbuffer,
@@ -364,13 +366,6 @@ static int console_save_map( int argc, char const *argv[] );
 static int console_load_map( int argc, char const *argv[] );
 static int console_changelevel( int argc, char const *argv[] );
 
-void vg_render(void);
-void vg_ui(void);
-void vg_update(void);
-void vg_start(void);
-void vg_free(void);
-int main( int argc, char *argv[] );
-
 /*
  * Globals -- runtime
  */
@@ -386,7 +381,9 @@ static float music_volume = 1.0f;
 
 static void music_volume_update(void)
 {
+#if 0
    sfx_vol_fset( &audio_volume_music, music_volume );
+#endif
 }
 
 static v3f colour_sets[][4] =
@@ -413,7 +410,7 @@ static struct world_theme
    const char *name;
    v3f col_shadow;
 
-   vg_tex2d *tex_tiles;
+   vg1_tex2d *tex_tiles;
 }
 world_themes[] =
 {
@@ -518,8 +515,7 @@ static const int random_noise[] = {
        return random_noise[ (random_noise[p[1] & 1023] + p[0]) & 1023 ] & umod;
 }
 
-static void init_mesh( struct mesh *m, float const *tris, u32 length )
-{
+static void init_mesh( struct mesh *m, float const *tris, u32 length ){
        m->elements = length/3;
        glGenVertexArrays( 1, &m->vao );
        glGenBuffers( 1, &m->vbo );
@@ -530,23 +526,18 @@ static void init_mesh( struct mesh *m, float const *tris, u32 length )
        
        glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 );
        glEnableVertexAttribArray( 0 );
-       
-       VG_CHECK_GL();
 }
 
-static void free_mesh( struct mesh *m )
-{
+static void free_mesh( struct mesh *m ){
        glDeleteVertexArrays( 1, &m->vao );
        glDeleteBuffers( 1, &m->vbo );
 }
 
-static void draw_mesh( int const start, int const count )
-{
+static void draw_mesh( int const start, int const count ){
        glDrawArrays( GL_TRIANGLES, start*3, count*3 );
 }
 
-static void use_mesh( struct mesh *m )
-{
+static void use_mesh( struct mesh *m ){
        glBindVertexArray( m->vao );
 }
 
@@ -702,6 +693,7 @@ static void map_reclassify( v2i start, v2i end, int update_texbuffer )
 
 static void gen_level_text(void)
 {
+#if 0
    ui_px const unit_scale_px = 4*UI_GLYPH_SPACING_X;
    ui_begin( &world.st.world_text, world.w*unit_scale_px, 
          world.h*unit_scale_px );
@@ -763,6 +755,7 @@ static void gen_level_text(void)
    }
 
    ui_resolve( &world.st.world_text );
+#endif
 }
 
 /* Usually for ignoring windows crap */
@@ -1449,7 +1442,6 @@ static void career_reset_level( struct cmp_level *lvl )
 
 static void career_load(void)
 {
-       i64 sz;
        struct dcareer_state encoded;
 
        /* Blank save state */
@@ -1462,7 +1454,8 @@ static void career_load(void)
     * without crashing. Old saves will load fine, too new saves will lose data,
     * such a situation should rarely (never) happen with the steam version.
     */
-       void *cr = vg_asset_read_s( "sav/game.sv2", &sz );
+       u32 sz;
+       void *cr = vg_file_read( NULL, "sav/game.sv2", &sz );
        
        if( cr )
        {
@@ -1563,7 +1556,9 @@ static void simulation_stop(void)
        
        io_reset();
        
+#if 0
        sfx_system_fadeout( &audio_system_balls_rolling, 44100 );
+#endif
        
        clear_animation_flags();
        
@@ -1573,15 +1568,17 @@ static void simulation_stop(void)
 static void simulation_start(void)
 {
        vg_success( "Starting simulation!\n" );
-                               
-       sfx_set_playrnd( &audio_rolls, &audio_system_balls_rolling, 0, 1 );
+   audio_lock();
+   audio_oneshot( &audio_rolls[ vg_randu32(&vg.rand) % 2 ], 1.0f, 0.0f );
+   audio_unlock();
        
        world.num_fishes = 0;
        world.sim_frame = 0;
        world.sim_run = 0;
        
-       world.sim_delta_speed = world.st.buttons[ k_world_button_speedy ].state? 10.0f: 2.5f;
-       world.sim_delta_ref = vg_time;
+       world.sim_delta_speed = world.st.buttons[ k_world_button_speedy ].state? 
+                           10.0f: 2.5f;
+       world.sim_delta_ref = vg.time;
        world.sim_internal_ref = 0.0f;
        world.sim_internal_time = 0.0f;
        world.pause_offset_target = 0.0f;
@@ -1698,14 +1695,14 @@ static int cell_interactive( v2i co )
        return 1;
 }
 
-static void vg_update(void)
+static void _mc_vg1_update(void)
 {
        // Async events
        if( world.st.lvl_to_load )
        {
-               world.st.world_transition = (world.st.lvl_load_time-vg_time) * 4.0f;
+               world.st.world_transition = (world.st.lvl_load_time-vg.time) * 4.0f;
 
-               if( vg_time > world.st.lvl_load_time )
+               if( vg.time > world.st.lvl_load_time )
                {       
                        if( console_changelevel( 1, &world.st.lvl_to_load->map_name ) )
                        {
@@ -1718,13 +1715,13 @@ static void vg_update(void)
        }
        else
        {
-               world.st.world_transition = vg_minf( 1.0f, (vg_time-world.st.lvl_load_time) * 4.0f );
+               world.st.world_transition = vg_minf( 1.0f, (vg.time-world.st.lvl_load_time) * 4.0f );
        }
 
        // Camera
        // ========================================================================================================
        
-       float r1 = (float)vg_window_y / (float)vg_window_x,
+       float r1 = (float)vg.window_y / (float)vg.window_x,
                        r2 = (float)world.h / (float)world.w,
                        size;
        
@@ -1750,40 +1747,42 @@ static void vg_update(void)
        v2_add( origin, result_view, vt_target );
 
        // Lerp towards target
-       size_current = vg_lerpf( size_current, size - world.st.zoom, vg_time_delta * 6.0f );
-       v2_lerp( origin_current, vt_target, vg_time_delta * 6.0f, origin_current ); 
+       size_current = vg_lerpf( size_current, size - world.st.zoom, vg.time_delta * 6.0f );
+       v2_lerp( origin_current, vt_target, vg.time_delta * 6.0f, origin_current ); 
        
        m3x3_projection( m_projection, -size_current, size_current, -size_current*r1, size_current*r1 );
        m3x3_identity( m_view );
        m3x3_translate( m_view, origin_current );
-       m3x3_mul( m_projection, m_view, vg_pv );
+       m3x3_mul( m_projection, m_view, vg.pv );
+
+#if 0
        vg_projection_update();
+#endif
 
    if( world.st.state == k_game_state_update )
       return;
        
        // Mouse input
        // ========================================================================================================
-       v2_copy( vg_mouse_ws, world.tile_pos );
-       
+   v2_copy( marblecomp.mouse_ws, world.tile_pos );
        world.tile_x = floorf( world.tile_pos[0] );
        world.tile_y = floorf( world.tile_pos[1] );
+   v2f vg_mouse = { vg.mouse_pos[0], vg.mouse_pos[1] };
 
        // Camera dragging
        {
                static v2f drag_origin; // x/y pixel
 
-               if( vg_get_button_down( "tertiary" ) )
-                       v2_copy( vg_mouse, drag_origin );
-               else if( vg_get_button( "tertiary" ) )
-               {
+               if( button_down( k_srbind_tertiary ) ){
+         v2_copy( vg_mouse, drag_origin );
+      }
+               else if( button_press( k_srbind_tertiary ) ){
                        // get offset
                        v2_sub( vg_mouse, drag_origin, drag_offset );
-                       v2_div( drag_offset, (v2f){ vg_window_x, vg_window_y }, drag_offset );
+                       v2_div( drag_offset, (v2f){ vg.window_x, vg.window_y }, drag_offset );
                        v2_mul( drag_offset, (v2f){ size_current*2.0f, -size_current*r1*2.0f }, drag_offset );
                }
-               else
-               {
+               else{
                        v2_copy( result_view, view_point );
                        v2_copy( (v2f){0.0f,0.0f}, drag_offset );
                }
@@ -1799,10 +1798,10 @@ static void vg_update(void)
 
                rsize = size-world.st.zoom;
 
-               v2_div( vg_mouse, (v2f){ vg_window_x*0.5f, vg_window_y*0.5f }, mview_local );
+               v2_div( vg_mouse, (v2f){ vg.window_x*0.5f, vg.window_y*0.5f }, mview_local );
                v2_add( (v2f){ -rsize, -rsize*r1 }, (v2f){ mview_local[0]*rsize, (2.0f-mview_local[1])*rsize*r1 }, mview_cur );
 
-               world.st.zoom = vg_clampf( world.st.zoom + vg_mouse_wheel[1], 0.0f, size - 4.0f );
+               world.st.zoom = vg_clampf( world.st.zoom + vg.mouse_wheel[1], 0.0f, size - 4.0f );
 
                // Recalculate new position
                rsize = size-world.st.zoom;
@@ -1815,9 +1814,8 @@ static void vg_update(void)
        
        // Tilemap
        // ========================================================================================================
-       if( !is_simulation_running() && !gui_want_mouse() )
-       {
-               v2_copy( vg_mouse_ws, world.drag_to_co );
+       if( !is_simulation_running() ){
+               v2_copy( marblecomp.mouse_ws, world.drag_to_co );
                
                if( cell_interactive( (v2i){ world.tile_x, world.tile_y } ))
                {
@@ -1828,33 +1826,37 @@ static void vg_update(void)
                
                        if( !(cell_ptr->state & FLAG_EMITTER) )
                        {
-                               if( vg_get_button_down("primary") )
+                               if( button_down(k_srbind_primary) )
                                        modify_state = (cell_ptr->state & FLAG_CANAL) ^ FLAG_CANAL;
                                
-                               if( vg_get_button("primary") && ((cell_ptr->state & FLAG_CANAL) != modify_state) )
+                               if( button_press(k_srbind_primary) && ((cell_ptr->state & FLAG_CANAL) != modify_state) )
                                {
                                        cell_ptr->state &= ~FLAG_CANAL;
                                        cell_ptr->state |= modify_state;
                                        
+                  audio_lock();
                                        if( cell_ptr->state & FLAG_CANAL )
                                        {
                                                cell_ptr->links[0] = 0;
                                                cell_ptr->links[1] = 0;
                                                
-                                               sfx_set_playrnd( &audio_tile_mod, &audio_system_sfx, 3, 6 );
+                  audio_oneshot( &audio_tile_mod[ vg_randu32(&vg.rand)%4+2 ],
+                                 1.0f, 0.0f );
                                                world.score ++;
                                        }
                                        else
-                                       {                                       
-                                               sfx_set_playrnd( &audio_tile_mod, &audio_system_sfx, 0, 3 );
+                                       {
+                  audio_oneshot( &audio_tile_mod[ vg_randu32(&vg.rand)%3 ],
+                                 1.0f, 0.0f );
                                                world.score --;
                                        }
+               audio_unlock();
 
                                        map_reclassify((v2i){ world.tile_x -2, world.tile_y -2 }, 
                                                                                (v2i){ world.tile_x +2, world.tile_y +2 }, 1 );
                                }
                                
-                               if( vg_get_button_down("secondary") && (cell_ptr->state & FLAG_CANAL) && !(cell_ptr->config == k_cell_type_split) )
+                               if( button_down(k_srbind_secondary) && (cell_ptr->state & FLAG_CANAL) && !(cell_ptr->config == k_cell_type_split) )
                                {
                                        world.id_drag_from = world.selected;
                                
@@ -1863,9 +1865,9 @@ static void vg_update(void)
                                }
                        }
                        
-                       float local_x = vg_mouse_ws[0] - (float)world.tile_x;
+                       float local_x = marblecomp.mouse_ws[0] - (float)world.tile_x;
                        
-                       if( vg_get_button_up("secondary") && world.id_drag_from == world.selected )
+                       if( button_up(k_srbind_secondary) && world.id_drag_from == world.selected )
                        {
                                u32 link_id = cell_ptr->links[ 0 ]? 0: 1;
                                
@@ -1891,7 +1893,7 @@ static void vg_update(void)
                                world.drag_to_co[0] = (float)world.tile_x + (local_x > 0.5f? 0.75f: 0.25f);
                                world.drag_to_co[1] = (float)world.tile_y + 0.25f;
 
-                               if( vg_get_button_up("secondary") )
+                               if( button_up( k_srbind_secondary) )
                                {
                                        struct cell *drag_ptr = &world.data[world.id_drag_from];
                                        u32 link_id = local_x > 0.5f? 1: 0;
@@ -1938,7 +1940,7 @@ static void vg_update(void)
                        world.selected = -1;
                }
                        
-               if( !(vg_get_button("secondary") && world.id_drag_from) )
+               if( !(button_press(k_srbind_secondary) && world.id_drag_from) )
                        world.id_drag_from = 0;
        }
        else
@@ -1954,9 +1956,9 @@ static void vg_update(void)
                float old_time = world.sim_internal_time;
        
                if( !world.st.buttons[ k_world_button_pause ].state )
-                       world.sim_internal_time = world.sim_internal_ref + (vg_time-world.sim_delta_ref) * world.sim_delta_speed;
+                       world.sim_internal_time = world.sim_internal_ref + (vg.time-world.sim_delta_ref) * world.sim_delta_speed;
                else
-                       world.sim_internal_time = vg_lerpf( world.sim_internal_time, world.sim_internal_ref + world.pause_offset_target, vg_time_delta*15.0f );
+                       world.sim_internal_time = vg_lerpf( world.sim_internal_time, world.sim_internal_ref + world.pause_offset_target, vg.time_delta*15.0f );
                world.sim_internal_delta = world.sim_internal_time-old_time;
                
                world.sim_target = (int)floorf(world.sim_internal_time);
@@ -1966,7 +1968,9 @@ static void vg_update(void)
                
                while( world.sim_frame < world.sim_target )
                {
-                       sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 8 );
+         audio_lock();
+         audio_oneshot( &audio_random[ vg_randu32(&vg.rand) % 8 ], 1.0f, 0.0f );
+         audio_unlock();
 
                        // Update splitter deltas
                        for( int i = 0; i < world.h*world.w; i ++ )
@@ -2083,7 +2087,9 @@ static void vg_update(void)
                                                                {
                                                                        if( fish->dir[0] == 0 )
                                                                        {
-                                                                               sfx_set_playrnd( &audio_splitter, &audio_system_balls_important, 0, 1 );
+                              audio_lock();
+                              audio_oneshot( &audio_splitter[0], 1.0f, 0.0f );
+                              audio_unlock();
                                                                                cell_next->state |= FLAG_FLIP_ROTATING;
                                                                                
                                                                                fish->flow_reversed = 0;
@@ -2357,7 +2363,7 @@ static void vg_update(void)
                                                world.num_fishes = 0;
                                                
                                                // Reset timing reference points
-                                               world.sim_delta_ref = vg_time;
+                                               world.sim_delta_ref = vg.time;
                                                world.sim_internal_ref = 0.0f;
                                                
                                                if( world.st.buttons[ k_world_button_pause ].state )
@@ -2390,7 +2396,9 @@ static void vg_update(void)
                                                        career_pass_level( world.pCmpLevel, world.score, 1 );
                                                }
                                                
-                                               sfx_set_play( &audio_tones, &audio_system_balls_extra, 9 );
+                  audio_lock();
+                  audio_oneshot( &audio_tones[9], 1.0f, 0.0f );
+                  audio_unlock();
                                                failure_this_frame = 0;
                                                success_this_frame = 0;
                                        }
@@ -2415,13 +2423,17 @@ static void vg_update(void)
                // Sounds
                if( failure_this_frame )
                {
-                       sfx_set_play( &audio_tones, &audio_system_balls_extra, 0 );
+         audio_lock();
+         audio_oneshot( &audio_tones[0], 1.0f, 0.0f );
+         audio_unlock();
                }
                else if( success_this_frame )
                {
                        static int succes_counter = 0;
                        
-                       sfx_set_play( &audio_tones, &audio_system_balls_extra, 1+(succes_counter++) );
+         audio_lock();
+         audio_oneshot( &audio_tones[1+(succes_counter++)], 1.0f, 0.0f );
+         audio_unlock();
                        
                        if( succes_counter == 7 )
                                succes_counter = 0;
@@ -2521,37 +2533,26 @@ static void render_tile( v2i pos, struct cell *ptr, v4f const regular_colour,
        uv[0] = ptr->config & 0x3;
        uv[1] = ptr->config >> 2;
        
-       glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), 
+   shader_tile_main_uOffset( (v4f){
                (float)pos[0], 
                (float)pos[1], 
                uv[0], 
                uv[1] 
-       );
+   });
    
-   if( with_glow )
-   {
-      glUniform3fv( SHADER_UNIFORM( shader_tile_main, "uGlowA" ), 
-            1, ptr->glow[0] );
-      glUniform3fv( SHADER_UNIFORM( shader_tile_main, "uGlowB" ), 
-            1, ptr->glow[1] );
+   if( with_glow ){
+      shader_tile_main_uGlowA( ptr->glow[0] );
+      shader_tile_main_uGlowB( ptr->glow[1] );
    }
-   else
-   {
-      glUniform3f( SHADER_UNIFORM( shader_tile_main, "uGlowA" ),
-            0.0f,
-            0.0f,
-            0.0f );
-      glUniform3f( SHADER_UNIFORM( shader_tile_main, "uGlowB" ),
-            0.0f,
-            0.0f,
-            0.0f );
+   else{
+      shader_tile_main_uGlowA( (v3f){0,0,0} );
+      shader_tile_main_uGlowB( (v3f){0,0,0} );
    }
 
-       if( selected )
-       {
-               glUniform4fv( SHADER_UNIFORM( shader_tile_main, "uColour" ), 1, selected_colour );
+       if( selected ){
+      shader_tile_main_uColour( selected_colour );
                draw_mesh( 0, 2 );
-               glUniform4fv( SHADER_UNIFORM( shader_tile_main, "uColour" ), 1, regular_colour );
+      shader_tile_main_uColour( regular_colour );
        }
        else                    
                draw_mesh( 0, 2 );
@@ -2586,7 +2587,7 @@ static void render_tile_block( v2i start, v2i end, v4f const regular_colour, v4f
 static void render_tiles( v4f const regular_colour, v4f const selected_colour, 
       int with_glow )
 {
-       glUniform4fv( SHADER_UNIFORM( shader_tile_main, "uColour" ), 1, regular_colour );
+   shader_tile_main_uColour( regular_colour );
 
        struct render_list
        {
@@ -2653,7 +2654,7 @@ static int world_button_exec( struct world_button *btn, v2f texture, v3f colour,
        v2i click_tile = { world.tile_x, world.tile_y };
 
        int triggered = 0;
-       int is_hovering = v2i_eq( click_tile, btn->position ) && !gui_want_mouse();
+       int is_hovering = v2i_eq( click_tile, btn->position );
 
        // Set up light targets before logic runs
        if( btn->state )
@@ -2661,15 +2662,15 @@ static int world_button_exec( struct world_button *btn, v2f texture, v3f colour,
        else
                btn->light_target = is_hovering? 0.2f: 0.0f;
 
-       if( vg_get_button( "primary" ) && is_hovering )
+       if( button_press( k_srbind_primary ) && is_hovering )
                btn->light_target = 1.0f;
        
        // Process click action
        if( is_hovering )
        {
-               if( vg_get_button_down( "primary" ) && is_hovering )
+               if( button_down( k_srbind_primary ) && is_hovering )
                        v2i_copy( click_tile, click_grab );
-               else if( v2i_eq( click_grab, click_tile ) && vg_get_button_up( "primary" ) )
+               else if( v2i_eq( click_grab, click_tile ) && button_up(k_srbind_primary))
                {
                        // Click event
                        *status = btn->state? k_world_button_on_disable: k_world_button_on_enable;
@@ -2677,7 +2678,9 @@ static int world_button_exec( struct world_button *btn, v2f texture, v3f colour,
                        if( btn->mode == k_world_button_mode_toggle )
                                btn->state ^= 0x1;
                        
-                       sfx_set_play( &audio_clicks, &audio_system_ui, btn->state? 1:0 );
+         audio_lock();
+         audio_oneshot( &audio_clicks[ btn->state?1:0 ], 1.0f, 0.0f );
+         audio_unlock();
                        triggered = 1;
                }
        }
@@ -2685,18 +2688,18 @@ static int world_button_exec( struct world_button *btn, v2f texture, v3f colour,
        // Drawing stage
        v4f final_colour;
        
-       btn->light = vg_lerpf( btn->light, btn->light_target + btn->extra_light, vg_time_delta*26.0f );
+       btn->light = vg_lerpf( btn->light, btn->light_target + btn->extra_light, vg.time_delta*26.0f );
 
        v3_copy( colour, final_colour );
        final_colour[3] = btn->light;
 
-       glUniform4f( SHADER_UNIFORM( shader_buttons, "uOffset" ),
+   shader_button_uOffset( (v4f){
                btn->position[0],
                btn->position[1],
                texture[0],
                texture[1]
-       );
-       glUniform4fv( SHADER_UNIFORM( shader_buttons, "uColour" ), 1, final_colour );
+   });
+   shader_button_uColour( final_colour );
        draw_mesh( 0, 2 );
 
        return triggered;
@@ -2718,7 +2721,7 @@ static void level_selection_buttons(void)
                        struct cmp_level *lvl = &grid->pack[ j ];
                                
                        if( world.pCmpLevel == lvl )
-                               lvl->btn.extra_light = 0.35f + fabsf(sinf( vg_time * 2.0f )) * 0.05f;   
+                               lvl->btn.extra_light = 0.35f + fabsf(sinf( vg.time * 2.0f )) * 0.05f;   
                        else lvl->btn.extra_light = 0.2f;
                        
                        if( lvl->completed_score )
@@ -2741,7 +2744,7 @@ static void level_selection_buttons(void)
        if( switch_level_to )
        {
                world.st.lvl_to_load = switch_level_to;
-               world.st.lvl_load_time = vg_time + 0.25f;
+               world.st.lvl_load_time = vg.time + 0.25f;
                world.st.world_transition = 1.0f;
 
                /*
@@ -2754,19 +2757,17 @@ static void level_selection_buttons(void)
        }
 }
 
-static void render_sprite( enum sprites_auto_combine_index id, v3f pos )
-{
+static void render_sprite( enum sprites_auto_combine_index id, v3f pos ){
        struct vg_sprite *sp = &sprites_auto_combine[ id ];
 
-       glUniform4fv( SHADER_UNIFORM( shader_sprite, "uUv" ), 1, sp->uv_xywh );
-       glUniform3f( SHADER_UNIFORM( shader_sprite, "uPos" )
-         pos[0], pos[1], pos[2] * world.st.world_transition );
-       
+   shader_sprite_uUv( sp->uv_xywh );
+   shader_sprite_uPos( (v3f){ pos[0]
+                              pos[1], 
+                              pos[2] * world.st.world_transition } );
        draw_mesh( 0, 2 );
 }
 
-static void vg_framebuffer_resize(int w, int h)
-{
+static void _mc_vg1_framebuffer_resize(int w, int h){
    glBindTexture( GL_TEXTURE_2D, world.st.colourbuffer );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 
          0, GL_RGB, GL_UNSIGNED_BYTE, NULL );
@@ -2780,14 +2781,13 @@ static void vg_framebuffer_resize(int w, int h)
    }
 }
 
-void vg_render(void)
-{
+static void _mc_vg1_render(void){
    if( enable_bloom || enable_vignette )
       glBindFramebuffer( GL_FRAMEBUFFER, world.st.framebuffer );
    else
       glBindFramebuffer( GL_FRAMEBUFFER, 0 );
 
-       glViewport( 0,0, vg_window_x, vg_window_y );
+       glViewport( 0,0, vg.window_x, vg.window_y );
 
        glDisable( GL_DEPTH_TEST );
        glClearColor( 0.14f, 0.14f, 0.14f, 1.0f );
@@ -2854,60 +2854,62 @@ void vg_render(void)
        // ========================================================================================================
        use_mesh( &world.shapes );
        
-       SHADER_USE( shader_background );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_background, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+   shader_background_use();
+   shader_background_uPv( vg.pv );
        
        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, world.background_data );
-       glUniform1i( SHADER_UNIFORM( shader_background, "uTexMain" ), 0 );
+   shader_background_uTexMain( 0 );
        
-       glUniform3f( SHADER_UNIFORM( shader_background, "uOffset" ), -16, -16, 64 );
-       glUniform1f( SHADER_UNIFORM( shader_background, "uVariance" ), 0.05f );
+   shader_background_uOffset( (v3f){ -16, -16, 64 } );
+   shader_background_uVariance( 0.05f );
        
        glActiveTexture( GL_TEXTURE1 );
        glBindTexture( GL_TEXTURE_2D, world.random_samples );
-       glUniform1i( SHADER_UNIFORM( shader_background, "uSamplerNoise" ), 1 );
-       glUniform1f( SHADER_UNIFORM( shader_background, "uVisibility" ), 1.0f ); //world.st.world_transition );
+   shader_background_uSamplerNoise( 1 );
+   shader_background_uVisibility( 1.0f );
 
        draw_mesh( 0, 2 );
        
        // TILESET BACKGROUND LAYER
        // ========================================================================================================
        use_mesh( &world.shapes );
-       SHADER_USE( shader_tile_main );
-
+   shader_tile_main_use();
        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 );
-       glUniform1f( SHADER_UNIFORM( shader_tile_main, "uVisibility" ), world.st.world_transition * 2.0f );
+   shader_tile_main_uSubTransform( subtransform );
+   shader_tile_main_uPv( vg.pv );
+   shader_tile_main_uGhost( 0.0f );
+   shader_tile_main_uForeground( 0.0f );
+   shader_tile_main_uVisibility( world.st.world_transition * 2.0f );
        
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBlendEquation(GL_FUNC_ADD);
        
        // rebind textures
-       vg_tex2d_bind( &tex_tile_data, 0 );
-       vg_tex2d_bind( theme->tex_tiles, 1 );
-   vg_tex2d_bind( &tex_tile_glow, 2 );
-   
-       glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexGlyphs" ), 0 );
-       glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexWood" ), 1 );
-       glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexGlow" ), 2 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_tile_data.name );
 
-   glUniform3fv( SHADER_UNIFORM( shader_tile_main, "uShadowing" ), 1, theme->col_shadow );
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, theme->tex_tiles->name );
 
+   glActiveTexture( GL_TEXTURE2 );
+   glBindTexture( GL_TEXTURE_2D, tex_tile_glow.name );
+   
+   shader_tile_main_uTexGlyphs(0);
+   shader_tile_main_uTexWood(1);
+   shader_tile_main_uTexGlow(2);
+   shader_tile_main_uShadowing( theme->col_shadow );
        render_tiles( colour_default, colour_default, 1 );
        
        // MARBLES
        // ========================================================================================================
-       SHADER_USE( shader_ball );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_ball, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
-       
-       vg_tex2d_bind( &tex_ball_noise, 0 );
-       glUniform1i( SHADER_UNIFORM( shader_ball, "uTexMain" ), 0 );
+   shader_ball_use();
+   shader_ball_uPv( vg.pv );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_ball_noise.name );
+   shader_ball_uTexMain( 0 );
        
        if( world.st.buttons[ k_world_button_sim ].state )
        {
@@ -2940,23 +2942,29 @@ void vg_render(void)
                        v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f };
                        colour_code_v3( fish->colour, dot_colour );
                        
-                       glUniform3fv( SHADER_UNIFORM( shader_ball, "uColour" ), 1, dot_colour );
-                       glUniform3fv( SHADER_UNIFORM( shader_ball, "uOffset" ), 1, render_pos );
-                       glUniform2f( SHADER_UNIFORM( shader_ball, "uTexOffset" ), (float)i * 1.2334, (float)i * -0.3579f );
+         shader_ball_uColour( dot_colour );
+         shader_ball_uOffset( render_pos );
+         shader_ball_uTexOffset( (v2f){ (f32)i*1.2334f, (f32)i*-0.3579f } );
                        draw_mesh( 0, 2 );
                }
        }
        
        // TILESET FOREGROUND LAYER
        // ========================================================================================================
-       SHADER_USE( shader_tile_main );
+   shader_tile_main_use();
 
        // Re Bind textures
-       vg_tex2d_bind( &tex_tile_data, 0 );
-       vg_tex2d_bind( theme->tex_tiles, 1 );
-   vg_tex2d_bind( &tex_tile_glow, 2 );
+   
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_tile_data.name );
+
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, theme->tex_tiles->name );
+
+   glActiveTexture( GL_TEXTURE2 );
+   glBindTexture( GL_TEXTURE_2D, tex_tile_glow.name );
        
-       glUniform1f( SHADER_UNIFORM( shader_tile_main, "uForeground" ), 1.0f );
+   shader_tile_main_uForeground(1.0f);
        render_tiles( colour_default, colour_selected, 0 );
 
        //      Draw splitters
@@ -2989,15 +2997,13 @@ void vg_render(void)
 
                        m2x2_create_rotation( subtransform, rotation );
 
-                       glUniformMatrix2fv( SHADER_UNIFORM( shader_tile_main,"uSubTransform" ), 
-               1, GL_FALSE, (float *)subtransform );
-
-                       glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), 
-                               (float)cmd->pos[0], 
-                               (float)cmd->pos[1] + 0.125f, 
+         shader_tile_main_uSubTransform( subtransform );
+         shader_tile_main_uOffset( (v4f){
+                               (f32)cmd->pos[0], 
+                               (f32)cmd->pos[1] + 0.125f, 
                                cell->state & FLAG_TARGETED? 3.0f: 2.0f, 
                                3.0f 
-                       );
+         });
                        draw_mesh( 0, 2 );
                }
        }
@@ -3013,10 +3019,9 @@ void vg_render(void)
                map_reclassify( new_begin, new_end, 0 );
                
                m2x2_identity( subtransform );
-               glUniform1f( SHADER_UNIFORM( shader_tile_main, "uGhost" ), 1.0f );
-               glUniformMatrix2fv( SHADER_UNIFORM( shader_tile_main, "uSubTransform" ), 1, GL_FALSE, (float *)subtransform );  
-               glUniform2fv( SHADER_UNIFORM( shader_tile_main, "uMousePos" ), 1, world.tile_pos );
-               
+      shader_tile_main_uGhost(1.0f);
+      shader_tile_main_uSubTransform( subtransform );
+      shader_tile_main_uMousePos( world.tile_pos );
                render_tile_block( new_begin, new_end, colour_default, colour_default );
                
                world.data[ world.selected ].state ^= FLAG_CANAL;
@@ -3025,11 +3030,12 @@ void vg_render(void)
        
        // BUTTONS
        // ========================================================================================================
-       SHADER_USE( shader_buttons );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_buttons, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
-       
-       vg_tex2d_bind( &tex_buttons, 0 );
-       glUniform1i( SHADER_UNIFORM( shader_buttons, "uTexMain" ), 0 );
+   shader_button_use();
+   shader_button_uPv( vg.pv );
+
+   glActiveTexture(GL_TEXTURE0);
+   glBindTexture( GL_TEXTURE_2D, tex_buttons.name );
+   shader_button_uTexMain(0);
        
        enum world_button_status stat;
        int world_paused = world.st.buttons[k_world_button_pause].state;
@@ -3067,7 +3073,7 @@ void vg_render(void)
        if( world_button_exec( &world.st.buttons[k_world_button_pause], (v2f){ 1.0f, 3.0f }, btn_dark_blue, &stat ))
        {
                world.sim_internal_ref = world.sim_internal_time;
-               world.sim_delta_ref = vg_time;
+               world.sim_delta_ref = vg.time;
 
                if( stat == k_world_button_on_enable )
                {
@@ -3084,7 +3090,7 @@ void vg_render(void)
                
                if( !world_paused )
                {
-                       world.sim_delta_ref = vg_time;
+                       world.sim_delta_ref = vg.time;
                        world.sim_internal_ref = world.sim_internal_time;
                }
        }
@@ -3097,15 +3103,15 @@ void vg_render(void)
 
        level_selection_buttons();
        
-       if( vg_get_button_up( "primary" ) )
+       if( button_up( k_srbind_primary ) )
                world_button_exec( NULL, NULL, NULL, NULL );
        
        // I/O ARRAYS
        // ========================================================================================================
        
        //glEnable(GL_BLEND);
-       SHADER_USE( shader_tile_colour );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+   shader_tile_colour_use();
+   shader_tile_colour_uPv( vg.pv );
 
        for( int i = 0; i < arrlen( world.io ); i ++ )
        {
@@ -3123,13 +3129,13 @@ void vg_render(void)
             {
                colour_code_v3( cell->emit[j], dot_colour );
                
-               glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 
+               shader_tile_colour_uOffset( (v3f){
                   term->pos[0] + 0.25f + (float)j * 0.5f, 
                   term->pos[1] + 0.25f,
                   0.12f
-               );
+               });
 
-               glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
+               shader_tile_colour_uColour( dot_colour );
                draw_mesh( filled_start, filled_count );
             }
          }
@@ -3151,7 +3157,7 @@ void vg_render(void)
                        {
                                if( k == world.sim_run )
                                {
-                                       float a = fabsf(sinf( vg_time * 2.0f )) * 0.075f + 0.075f;
+                                       float a = fabsf(sinf( vg.time * 2.0f )) * 0.075f + 0.075f;
                                        
                                        v4_copy( (v4f){ 1.0f, 1.0f, 1.0f, a }, bar_colour );
                                }
@@ -3172,20 +3178,20 @@ void vg_render(void)
                        
                        if( bar_draw )
                        {
-                               glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, bar_colour );
-                               glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 
-               (float)term->pos[0], y_position - 0.1f, 1.0f );
+            shader_tile_colour_uColour( bar_colour );
+            shader_tile_colour_uOffset( (v3f){ 
+               (float)term->pos[0], y_position - 0.1f, 1.0f });
 
                                draw_mesh( 2, 2 );
                        }
                        
                        for( int j = 0; j < term->runs[k].step_count; j ++ )
                        {
-                               glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 
+            shader_tile_colour_uOffset( (v3f){
                                        (float)term->pos[0] + 0.2f + 0.2f * (float)j, 
                                        y_position, 
                                        0.1f 
-                               );
+            });
                        
                                if( is_input )
                                {
@@ -3193,7 +3199,7 @@ void vg_render(void)
                                        if( colour != -1 )
                                        {                                       
                                                colour_code_v3( colour, dot_colour );
-                                               glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
+                  shader_tile_colour_uColour( dot_colour );
                                        
                                                // Draw filled if tick not passed, draw empty if empty
                                                if( (world.sim_frame > j && world.sim_run >= k) || world.sim_run > k )
@@ -3209,13 +3215,12 @@ void vg_render(void)
                                        {
                                                colour_code_v3( term->runs[k].recieved[j], dot_colour );
                                                v3_muls( dot_colour, 0.8f, dot_colour );
-                                               glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
-                                               
+                  shader_tile_colour_uColour( dot_colour );
                                                draw_mesh( filled_start, filled_count );
                                        }
                                        
                                        colour_code_v3( term->runs[k].steps[j], dot_colour );
-                                       glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, dot_colour );
+               shader_tile_colour_uColour( dot_colour );
                                        
                                        draw_mesh( empty_start, empty_count );
                                }
@@ -3225,14 +3230,14 @@ void vg_render(void)
 
        // SPRITES
        // ========================================================================================================
-       SHADER_USE( shader_sprite );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_sprite, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+   shader_sprite_use();
+   shader_sprite_uPv( vg.pv );
 
-       vg_tex2d_bind( &tex_sprites, 0 );
-       glUniform1i( SHADER_UNIFORM( shader_sprite, "uTexMain" ), 0 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_sprites.name );
+   shader_sprite_uTexMain(0);
        
-       for( int i = 0; i < world.tile_special_count; i ++ )
-       {
+       for( int i = 0; i < world.tile_special_count; i ++ ){
                struct render_cmd *cmd = &world.cmd_buf_specials[i];
                struct cell *cell = cmd->ptr;
 
@@ -3271,32 +3276,40 @@ void vg_render(void)
       1.0f 
    });
 
-   m3x3_mul( vg_pv, mvp_text, mvp_text );
+   m3x3_mul( vg.pv, mvp_text, mvp_text );
+
+   /* FIXME */
+#if 0
    ui_draw( &world.st.world_text, mvp_text );
+#endif
 
        // WIRES
        // ========================================================================================================
        glEnable(GL_BLEND);
 
-       SHADER_USE( shader_wire );
+   shader_wire_use();
        glBindVertexArray( world.wire.vao );
-
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_wire, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+   shader_wire_uPv(vg.pv);
        
        v4f const wire_left_colour = { 0.9f, 0.9f, 0.9f, 1.0f };
        v4f const wire_right_colour = { 0.5f, 0.5f, 0.5f, 1.0f };
        v4f const wire_drag_colour = { 0.3f, 0.3f, 0.3f, 0.6f };
        
-       glUniform1f( SHADER_UNIFORM( shader_wire, "uTime" ), world.frame_lerp );
-       glUniform1f( SHADER_UNIFORM( shader_wire, "uGlow" ), 0.0f );
+   shader_wire_uTime( world.frame_lerp );
+   shader_wire_uGlow( 0.0f );
        
        if( world.id_drag_from )
        {
-               glUniform4fv( SHADER_UNIFORM( shader_wire, "uColour" ), 1, wire_drag_colour );
-               glUniform1f( SHADER_UNIFORM( shader_wire, "uCurve" ), 0.4f );
-               glUniform3f( SHADER_UNIFORM( shader_wire, "uStart" ), world.drag_from_co[0], world.drag_from_co[1], 0.20f*world.st.world_transition );
-               glUniform3f( SHADER_UNIFORM( shader_wire, "uEnd" ), world.drag_to_co[0], world.drag_to_co[1], 0.20f*world.st.world_transition );
-               glDrawElements( GL_TRIANGLES, world.wire.em, GL_UNSIGNED_SHORT, (void*)(0) );
+      shader_wire_uColour( wire_drag_colour );
+      shader_wire_uCurve( 0.4f );
+      shader_wire_uStart( (v3f){ world.drag_from_co[0], 
+                                 world.drag_from_co[1], 
+                                 0.20f*world.st.world_transition } );
+      shader_wire_uEnd( (v3f){ world.drag_to_co[0], 
+                               world.drag_to_co[1], 
+                               0.20f*world.st.world_transition } );
+               glDrawElements( GL_TRIANGLES, world.wire.em, 
+                      GL_UNSIGNED_SHORT, (void*)(0) );
        }
        
        // Pulling animation
@@ -3339,16 +3352,22 @@ void vg_render(void)
                                        colour_code_v3( cmd->ptr->emit[j], wire_colour );
                                        wire_colour[3] = 1.0f;
 
-                                       glUniform4fv( SHADER_UNIFORM( shader_wire, "uColour" ), 1, wire_colour );
+               shader_wire_uColour( wire_colour );
                                }
                                else
-                                       glUniform4fv( SHADER_UNIFORM( shader_wire, "uColour" ), 1, j? wire_right_colour: wire_left_colour );
-
-                               glUniform1f( SHADER_UNIFORM( shader_wire, "uCurve" ), other_cell->state & FLAG_TRIGGERED? rp_x2 * 0.4f: 0.4f );
-                               glUniform1f( SHADER_UNIFORM( shader_wire, "uGlow" ), other_cell->state & FLAG_TRIGGERED? rp_xa: 0.0f );
-                               glUniform3f( SHADER_UNIFORM( shader_wire, "uEnd" ), startpoint[0], startpoint[1], 0.18f*world.st.world_transition );
-                               glUniform3f( SHADER_UNIFORM( shader_wire, "uStart" ), endpoint[0], endpoint[1], 0.18f*world.st.world_transition );
-                               glDrawElements( GL_TRIANGLES, world.wire.em, GL_UNSIGNED_SHORT, (void*)(0) );
+               shader_wire_uColour( j? wire_right_colour: wire_left_colour );
+            
+            shader_wire_uCurve( 
+                  other_cell->state & FLAG_TRIGGERED? rp_x2 * 0.4f: 0.4f );
+            shader_wire_uGlow(
+                                     other_cell->state & FLAG_TRIGGERED? rp_xa: 0.0f );
+                               shader_wire_uEnd( (v3f){ 
+                  startpoint[0], startpoint[1], 
+                  0.18f*world.st.world_transition } );
+            shader_wire_uStart( (v3f){ 
+                  endpoint[0], endpoint[1], 0.18f*world.st.world_transition } );
+                               glDrawElements( GL_TRIANGLES, world.wire.em, 
+                            GL_UNSIGNED_SHORT, (void*)(0) );
                        }
                }
        }
@@ -3356,7 +3375,7 @@ void vg_render(void)
        // WIRE ENDPOINTS
        // ========================================================================================================
        
-       SHADER_USE( shader_tile_colour );
+   shader_tile_colour_use();
        use_mesh( &world.shapes );
        
        for( int i = 0; i < world.tile_special_count; i ++ )
@@ -3395,18 +3414,18 @@ void vg_render(void)
                                        v3_muls( wire_colour, 0.8f, wire_colour );
                                        wire_colour[3] = 1.0f;
 
-                                       glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1, wire_colour );
+               shader_tile_colour_uColour( wire_colour );
                                }
                                else
-                                       glUniform4fv( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 1,j?wire_right_colour: wire_left_colour );
+               shader_tile_colour_uColour( 
+                     j?wire_right_colour: wire_left_colour );
                                
-                               for( int i = 0; i < 2; i ++ )
-                               {
-                                       glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 
+                               for( int i = 0; i < 2; i ++ ){
+               shader_tile_colour_uOffset( (v3f){
                                                pts[i][0],
                                                pts[i][1], 
                                                0.08f * world.st.world_transition
-                                       );
+               });
                                        draw_mesh( filled_start, filled_count );        
                                }
                        }
@@ -3437,10 +3456,10 @@ void vg_render(void)
        glBlendFunc(GL_ONE, GL_ONE);
        glBlendEquation(GL_FUNC_ADD);
        
-       SHADER_USE( shader_sprite );
-
-       vg_tex2d_bind( &tex_sprites, 0 );
-       glUniform1i( SHADER_UNIFORM( shader_sprite, "uTexMain" ), 0 );
+   shader_sprite_use();
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_sprites.name );
+   shader_sprite_uTexMain(0);
        
        for( int i = 0; i < world.tile_special_count; i ++ )
        {
@@ -3494,23 +3513,23 @@ void vg_render(void)
 
    /* Scale down image and remap colour values */
        glViewport( 0,0, 
-         vg_window_x/EFFECT_BUFFER_RATIO, vg_window_y/EFFECT_BUFFER_RATIO );
+         vg.window_x/EFFECT_BUFFER_RATIO, vg.window_y/EFFECT_BUFFER_RATIO );
    glBindFramebuffer( GL_FRAMEBUFFER, world.st.bloomframebuffer[0] );
    
-   SHADER_USE( shader_post_darken );
+   shader_post_darken_use();
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, world.st.colourbuffer );
-       glUniform1i( SHADER_UNIFORM( shader_post_darken, "uTexMain" ), 0 );
+   shader_post_darken_uTexMain(0);
    
    draw_mesh( 0, 2 );
 
    /* Two pass blur */
    v2f res_inv, blur_dir;
-   res_inv[0] = 1.0f / (float)( vg_window_x/EFFECT_BUFFER_RATIO );
-   res_inv[1] = 1.0f / (float)( vg_window_y/EFFECT_BUFFER_RATIO );
+   res_inv[0] = 1.0f / (float)( vg.window_x/EFFECT_BUFFER_RATIO );
+   res_inv[1] = 1.0f / (float)( vg.window_y/EFFECT_BUFFER_RATIO );
    
-   SHADER_USE( shader_post_blur );
-       glUniform1i( SHADER_UNIFORM( shader_post_blur, "uTexMain" ), 0 );
+   shader_post_blur_use();
+   shader_post_blur_uTexMain(0);
 
    for( int i=0; i<1; i++ )
    {
@@ -3518,7 +3537,7 @@ void vg_render(void)
       
       v2_mul( (v2f){ 1.0f*(float)(i+1), 0.0f }, res_inv, blur_dir );
 
-      glUniform2fv( SHADER_UNIFORM(shader_post_blur,"uDir"), 1, blur_dir );
+      shader_post_blur_uDir( blur_dir );
       glActiveTexture( GL_TEXTURE0 );
       glBindTexture( GL_TEXTURE_2D, world.st.bloomcolourbuffer[0] );
 
@@ -3527,42 +3546,44 @@ void vg_render(void)
       v2_mul( (v2f){ 0.0f, 1.0f*(float)(i+1) }, res_inv, blur_dir );
       
       glBindFramebuffer( GL_FRAMEBUFFER, world.st.bloomframebuffer[0] );
-      glUniform2fv( SHADER_UNIFORM(shader_post_blur,"uDir"), 1, blur_dir );
+      shader_post_blur_uDir( blur_dir );
       glBindTexture( GL_TEXTURE_2D, world.st.bloomcolourbuffer[1] );
       draw_mesh( 0, 2 );
    }
 
    /* Scene composite */
-       glViewport( 0,0, vg_window_x, vg_window_y );
+       glViewport( 0,0, vg.window_x, vg.window_y );
 
 image_composite:
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    
-   SHADER_USE( shader_post_comp );
+   shader_post_comp_use();
 
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, world.st.colourbuffer );
-       glUniform1i( SHADER_UNIFORM( shader_post_comp, "uTexMain" ), 0 );
+   shader_post_comp_uTexMain(0);
    
    glActiveTexture( GL_TEXTURE1 );
    glBindTexture( GL_TEXTURE_2D, world.st.bloomcolourbuffer[0] );
-       glUniform1i( SHADER_UNIFORM( shader_post_comp, "uTexBloom" ), 1 );
+   shader_post_comp_uTexBloom(1);
    
-   glUniform2f( SHADER_UNIFORM( shader_post_comp, "uComp" ), 
+   shader_post_comp_uComp( (v2f){
          enable_bloom? 1.0f: 0.0f,
-         enable_vignette? 0.0f: 1.0f );
+         enable_vignette? 0.0f: 1.0f
+   });
 
    draw_mesh( 0, 2 );
 }
 
-void vg_ui(void) 
-{
+void _mc_vg1_ui(void) {
    // Drawing world name
+#if 0
    if( world.pCmpLevel )
    {
-      gui_text( (ui_px [2]){ vg_window_x / 2, 4 }, world.pCmpLevel->title, 2, k_text_align_center );
-      gui_text( (ui_px [2]){ vg_window_x / 2, 28 }, world.pCmpLevel->description, 1, k_text_align_center );
+      gui_text( (ui_px [2]){ vg.window_x / 2, 4 }, world.pCmpLevel->title, 2, k_text_align_center );
+      gui_text( (ui_px [2]){ vg.window_x / 2, 28 }, world.pCmpLevel->description, 1, k_text_align_center );
    }
+#endif
 
 #if 0
    if( world.st.state == k_game_state_update )
@@ -3571,8 +3592,8 @@ void vg_ui(void)
 
       ui_global_ctx.cursor[2] = 458;
       ui_global_ctx.cursor[3] = 316;
-      ui_global_ctx.cursor[0] = vg_window_x / 2 - 229;
-      ui_global_ctx.cursor[1] = vg_window_y / 2 - 158;
+      ui_global_ctx.cursor[0] = vg.window_x / 2 - 229;
+      ui_global_ctx.cursor[1] = vg.window_y / 2 - 158;
 
       gui_new_node();
       {
@@ -3621,6 +3642,8 @@ void vg_ui(void)
    }
    else 
 #endif
+
+#if 0
    if( world.st.state == k_game_state_settings )
        {
                gui_group_id( 35 );
@@ -3845,112 +3868,8 @@ void vg_ui(void)
                }
                gui_end();
        }
-}
-
-#if STEAM_LEADERBOARDS
-void leaderboard_dispatch_score(void)
-{
-
-       sw_upload_leaderboard_score( 
-               ui_data.upload_request.level->steam_leaderboard, 
-               k_ELeaderboardUploadScoreMethodKeepBest,
-               ui_data.upload_request.score,
-               NULL,
-               0
-       );
-       
-       ui_data.upload_request.is_waiting = 0;
-       
-       vg_success( "Dispatched leaderboard score\n" );
-}
-
-void leaderboard_found( LeaderboardFindResult_t *pCallback )
-{
-       if( !pCallback->m_bLeaderboardFound )
-       {
-               vg_error( "Leaderboard could not be found\n" );
-               ui_data.steam_leaderboard = 0;
-       }
-       else
-       {
-               const char *recieved_name = sw_get_leaderboard_name( pCallback->m_hSteamLeaderboard );
-               
-               // Update UI state and request entries if this callback found the current UI level
-               if( ui_data.level_selected )
-               {
-                       if( !strcmp( recieved_name, ui_data.level_selected->map_name ) )
-                       {
-                               sw_download_leaderboard_entries( pCallback->m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, 0, 8 );
-                               ui_data.level_selected->steam_leaderboard = pCallback->m_hSteamLeaderboard;
-                       }
-               }
-               
-               // Dispatch the waiting request if there was one
-               if( ui_data.upload_request.is_waiting )
-               {
-                       if( !strcmp( recieved_name, ui_data.upload_request.level->map_name ) )
-                       {
-                               ui_data.upload_request.level->steam_leaderboard = pCallback->m_hSteamLeaderboard;
-                               leaderboard_dispatch_score();
-                       }
-               }
-       }
-}
-
-void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback )
-{
-       // Update UI if this leaderboard matches what we currently have in view
-       if( ui_data.level_selected->steam_leaderboard == pCallback->m_hSteamLeaderboard )
-       {
-               vg_info( "Recieved %d entries\n", pCallback->m_cEntryCount );
-               ui_data.leaderboard_count = VG_MIN( pCallback->m_cEntryCount, 8 );
-               
-               u64_steamid local_player = sw_get_steamid();
-               
-               for( int i = 0; i < ui_data.leaderboard_count; i ++ )
-               {
-                       LeaderboardEntry_t entry;
-                       sw_get_downloaded_entry( pCallback->m_hSteamLeaderboardEntries, i, &entry, NULL, 0 );
-                       
-                       struct leaderboard_player *player = &ui_data.leaderboard_players[i];
-
-                       player->id = entry.m_steamIDUser.m_unAll64Bits;
-                       strncpy( player->player_name, sw_get_friend_persona_name( player->id ), vg_list_size( player->player_name )-1 );
-                       player->score = entry.m_nScore;
-                       
-                       snprintf( player->score_text, vg_list_size(player->score_text), "%d", player->score );
-                       player->texture = sw_get_player_image( player->id );
-                       
-                       if( player->texture == 0 )
-                               player->texture = tex_unkown.name;
-                               
-                       player->is_local_player = local_player == player->id? 1: 0;
-               }
-               
-               if( ui_data.leaderboard_count )
-                       ui_data.leaderboard_show = 1;
-               else
-                       ui_data.leaderboard_show = 0;
-       }
-       else vg_warn( "Downloaded leaderboard does not match requested!\n" );
-}
-
-void leaderboard_set_score( struct cmp_level *cmp_level, u32 score )
-{
-       if( ui_data.upload_request.is_waiting )
-               vg_warn( "You are uploading leaderboard entries too quickly!\n" );
-               
-       ui_data.upload_request.level = cmp_level;
-       ui_data.upload_request.score = score;
-       ui_data.upload_request.is_waiting = 1;
-       
-       // If leaderboard ID has been downloaded already then just immediately dispatch this
-       if( cmp_level->steam_leaderboard )
-               leaderboard_dispatch_score();
-       else
-               sw_find_leaderboard( cmp_level->map_name );
-}
 #endif
+}
 
 // CONSOLE COMMANDS
 // ===========================================================================================================
@@ -4006,7 +3925,8 @@ static int console_load_map( int argc, char const *argv[] )
                strcat( map_path, argv[0] );
                strcat( map_path, ".map" );
        
-               char *text_source = vg_textasset_read( map_path );
+      u32 sz;
+               char *text_source = vg_file_read_text( NULL, map_path, &sz );
                
                if( !text_source )
                {
@@ -4014,7 +3934,7 @@ static int console_load_map( int argc, char const *argv[] )
                        strcat( map_path, argv[0] );
                        strcat( map_path, ".map" );
                        
-                       text_source = vg_textasset_read( map_path );
+                       text_source = vg_file_read_text( NULL, map_path, &sz );
                }
                
                if( text_source )
@@ -4072,14 +3992,14 @@ static int console_changelevel( int argc, char const *argv[] )
 #define TRANSFORM_TRI_2D( S, OX, OY, X1, Y1, X2, Y2, X3, Y3 ) \
        X1*S+OX, Y1*S+OY, X2*S+OX, Y2*S+OY, X3*S+OX, Y3*S+OY 
 
-void vg_start(void)
-{
+void _mc_vg1_start(void){
        // Steamworks callbacks
        #ifdef STEAM_LEADERBOARDS
        sw_leaderboard_found = &leaderboard_found;
        sw_leaderboard_downloaded = &leaderboard_downloaded;
        #endif
 
+#if 0
        vg_function_push( (struct vg_cmd){
                .name = "_map_write",
                .function = console_save_map
@@ -4143,6 +4063,7 @@ void vg_start(void)
       .persistent = 1,
       .update = music_volume_update
    });
+#endif
 
        // Combined quad, long quad / empty circle / filled circle mesh
        {
@@ -4229,8 +4150,6 @@ void vg_start(void)
                glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 );
                glEnableVertexAttribArray( 0 );
                
-               VG_CHECK_GL();
-               
                mw->em = vg_list_size( wire_indices );
        }
        
@@ -4239,7 +4158,8 @@ void vg_start(void)
                glGenTextures( 1, &world.background_data );
                glBindTexture( GL_TEXTURE_2D, world.background_data );
                glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
-               vg_tex2d_nearest();
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        }
        
        // Create random smaples texture
@@ -4251,18 +4171,21 @@ void vg_start(void)
                glGenTextures( 1, &world.random_samples );
                glBindTexture( GL_TEXTURE_2D, world.random_samples );
                glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, 512, 512, 0, GL_RG, GL_UNSIGNED_BYTE, data );
-               vg_tex2d_nearest();
-               vg_tex2d_repeat();
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
                
                free( data );
        }
-       
-       resource_load_main();
 
    // Init world text
+   /* FIXME */
+#if 0
    {
       ui_init_context( &world.st.world_text, 15000 );
    }
+#endif
 
        // Restore gamestate
        career_local_data_init();
@@ -4274,7 +4197,7 @@ void vg_start(void)
 
    glGenTextures( 1, &world.st.colourbuffer );
    glBindTexture( GL_TEXTURE_2D, world.st.colourbuffer );
-   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 
+   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg.window_x, vg.window_y, 
          0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
 
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
@@ -4292,9 +4215,10 @@ void vg_start(void)
 
       glBindTexture( GL_TEXTURE_2D, world.st.bloomcolourbuffer[i] );
       glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
-            vg_window_x/EFFECT_BUFFER_RATIO, vg_window_y/EFFECT_BUFFER_RATIO, 
+            vg.window_x/EFFECT_BUFFER_RATIO, vg.window_y/EFFECT_BUFFER_RATIO, 
             0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-      vg_tex2d_clamp();
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
 
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -4303,6 +4227,7 @@ void vg_start(void)
    }
 }
 
+/* FIXME: run this at vg exit */
 void vg_free(void)
 {
 #ifdef VG_STEAM
@@ -4311,25 +4236,4 @@ void vg_free(void)
 
        console_save_map( 0, NULL );
        career_serialize();
-
-       resource_free_main();
-
-       glDeleteTextures( 1, &world.background_data );
-       glDeleteTextures( 1, &world.random_samples );
-
-       glDeleteVertexArrays( 1, &world.wire.vao );
-       glDeleteBuffers( 1, &world.wire.vbo );
-       glDeleteBuffers( 1, &world.wire.ebo );
-
-       free_mesh( &world.shapes );
-       
-   ui_context_free( &world.st.world_text );
-
-       map_free();
-}
-
-int main( int argc, char *argv[] )
-{
-       vg_init( argc, argv, "Marble Computing" );
-       return 0;
 }
diff --git a/input.h b/input.h
new file mode 100644 (file)
index 0000000..787a61b
--- /dev/null
+++ b/input.h
@@ -0,0 +1,179 @@
+#ifndef INPUT_H
+#define INPUT_H
+
+#define VG_GAME
+#include "vg/vg.h"
+#include "vg/vg_platform.h" 
+#include "vg/vg_console.h"
+#include "vg/vg_input.h"
+#include "vg/vg_m.h"
+
+enum sr_bind{
+   k_srbind_primary = 0,
+   k_srbind_secondary,
+   k_srbind_tertiary,
+   k_srbind_go,
+   k_srbind_max,
+};
+
+enum sr_joystick{
+   k_srjoystick_max
+};
+
+enum sr_axis{
+   k_sraxis_max
+};
+
+
+#define INPUT_BASIC( KB, JS ) \
+   (vg_input_op[]){vg_keyboard, KB, vg_joy_button, JS, vg_end}
+
+static vg_input_op *input_button_list[] = {
+[k_srbind_primary] = (vg_input_op[]){
+   vg_mouse, SDL_BUTTON_LEFT, vg_end
+},
+[k_srbind_secondary] = (vg_input_op[]){
+   vg_mouse, SDL_BUTTON_RIGHT, vg_end
+},
+[k_srbind_tertiary] = (vg_input_op[]){
+   vg_mouse, SDL_BUTTON_MIDDLE, vg_end
+},
+[k_srbind_go] = (vg_input_op[]){
+   vg_keyboard, SDLK_SPACE, vg_end
+},
+[k_srbind_max]=NULL
+};
+
+static vg_input_op *input_axis_list[] = {
+[k_sraxis_max]=NULL
+};
+
+static vg_input_op *input_joy_list[] = {
+[k_srjoystick_max]=NULL
+};
+
+struct {
+   float axis_states[ k_sraxis_max ][2];
+   v2f joystick_states[ k_srjoystick_max ][2];
+   u8 button_states[ k_srbind_max ][2];
+
+   enum input_state {
+      k_input_state_enabled,
+      k_input_state_resume,
+      k_input_state_resuming,
+      k_input_state_pause
+   }
+   state;
+}
+static srinput;
+
+static int input_filter_generic(void){
+   if( (srinput.state != k_input_state_enabled) || vg_console.enabled )
+      return 1;
+   else 
+      return 0;
+}
+
+static int buttons_filter_fixed(void){
+   if( input_filter_generic() ) 
+      return 1;
+
+   if( vg.engine_stage == k_engine_stage_update_fixed )
+      if( vg.fixed_iterations > 0 )
+         return 1;
+
+   return 0;
+}
+
+/* Rising edge of button */
+static int button_down( enum sr_bind button ){
+   if( buttons_filter_fixed() ) return 0;
+   
+   if(  srinput.button_states[ button ][0] && 
+       !srinput.button_states[ button ][1] )
+      return 1;
+   else
+      return 0;
+}
+
+/* Falling edge of button */
+static int button_up( enum sr_bind button ){
+   if( buttons_filter_fixed() ) return 0;
+   
+   if( !srinput.button_states[ button ][0] && 
+        srinput.button_states[ button ][1] )
+      return 1;
+   else
+      return 0;
+}
+
+/* State of button */
+static int button_press( enum sr_bind button ){
+   if( input_filter_generic() )
+      return 0;
+   return 
+      srinput.button_states[ button ][0];
+}
+
+static void joystick_state( enum sr_joystick joystick, v2f state ){
+   if( input_filter_generic() )
+      v2_zero( state );
+   else
+      v2_copy( srinput.joystick_states[ joystick ][0], state );
+}
+
+static float axis_state( enum sr_axis axis ){
+   if( input_filter_generic() )
+      return 0.0f;
+   else 
+      return srinput.axis_states[axis][0];
+}
+
+static void skaterift_preupdate_inputs(void){
+   if( srinput.state == k_input_state_resuming )
+      srinput.state = k_input_state_enabled;
+
+   if( srinput.state == k_input_state_resume )
+      srinput.state = k_input_state_resuming;
+
+   for( u32 i=0; i<k_srbind_max; i++ ){
+      srinput.button_states[i][1] = srinput.button_states[i][0];
+      srinput.button_states[i][0] = 0;
+   }
+
+   for( u32 i=0; i<k_srjoystick_max; i++ ){
+      v2_copy( srinput.joystick_states[i][0], srinput.joystick_states[i][1] );
+      v2_zero( srinput.joystick_states[i][0] );
+   }
+
+   for( u32 i=0; i<k_sraxis_max; i++ ){
+      srinput.axis_states[i][1] = srinput.axis_states[i][0];
+      srinput.axis_states[i][0] = 0.0f;
+   }
+
+   for( int i=0; i<k_srbind_max; i++ ){
+      vg_input_op *prog = input_button_list[i];
+      if( prog ){
+         vg_exec_input_program( k_vg_input_type_button_u8, prog,
+                                &srinput.button_states[i][0] );
+      }
+   }
+
+   for( int i=0; i<k_sraxis_max; i++ ){
+      vg_input_op *prog = input_axis_list[i];
+      if( prog ){
+         vg_exec_input_program( k_vg_input_type_axis_f32, prog,
+                                &srinput.axis_states[i][0] );
+      }
+   }
+
+   for( int i=0; i<k_srjoystick_max; i++ ){
+      vg_input_op *prog = input_joy_list[i];
+      if( prog ){
+         vg_exec_input_program( k_vg_input_type_joy_v2f, prog,
+                                srinput.joystick_states[i][0] );
+      }
+   }
+}
+
+#endif /* INPUT_H */
index d9f8cd8f0504306b5c9f3f4b8c01db830c5a7933..07dbd7c5514d80f2535e92f3de939d5964ca2ac3 100644 (file)
 
 #define SDL_MAIN_HANDLED
 
+#define STB_DS_IMPLEMENTATION
+#include "vg/submodules/stb/stb_ds.h"
+
 #include "vg/vg.h"
-#include "fishladder_vg1.c"
+
 
 struct {
    enum mc_op {
@@ -19,9 +22,14 @@ struct {
       k_mc_op_clientloading
    }
    op;
+
+   v3f mouse_ws;
 }
 static marblecomp = { .op = k_mc_op_clientloading };
 
+#include "input.h"
+#include "fishladder_vg1.c"
+
 int main( int argc, char *argv[] ){
    vg_mem.use_libc_malloc = 0;
    vg_set_mem_quota( 80*1024*1024 );
@@ -44,17 +52,40 @@ vg_info("            '        ' '--' [] '----- '----- '     ' '---'  "
 }
 
 static void async_call_ready( void *payload, u32 size ){
+   _mc_vg1_start();
    marblecomp.op = k_mc_op_none;
 }
 
 static void vg_load(void){
    /* --------------------- */
+   _mc_vg1_register();
+       _mc_resource_load_main();
    vg_bake_shaders();
    vg_async_call( async_call_ready, NULL, 0 );
 }
 
+void _mc_vg1_projection_update(void){
+   /*
+    * Reproject screenspace mouse into world
+    */
+
+   marblecomp.mouse_ws[0] =  ((vg.mouse_pos[0]/(f32)vg.window_x)-0.5f)*2.0f;
+   marblecomp.mouse_ws[1] = -((vg.mouse_pos[1]/(f32)vg.window_y)-0.5f)*2.0f;
+   marblecomp.mouse_ws[2] = 1.0f;
+   
+   m3x3f inverse;
+   m3x3_inv( vg.pv, inverse ); 
+   m3x3_mulv( inverse, marblecomp.mouse_ws, marblecomp.mouse_ws );
+
+   vg_info( "VG %f %f\n", vg.mouse_pos[0], vg.mouse_pos[1] );
+   vg_info( "WS %f %f\n", marblecomp.mouse_ws[0], marblecomp.mouse_ws[1] );
+}
+
+
 static void vg_pre_update(void){
    if( marblecomp.op == k_mc_op_clientloading ) return;
+   skaterift_preupdate_inputs();
+   _mc_vg1_update();
 }
 
 static void vg_fixed_update(void){
@@ -63,9 +94,11 @@ static void vg_fixed_update(void){
 
 static void vg_post_update(void){
    if( marblecomp.op == k_mc_op_clientloading ) return;
+   _mc_vg1_projection_update();
 }
 
 static void vg_framebuffer_resize( int w, int h ){
+   _mc_vg1_framebuffer_resize(w,h);
 }
 
 static void vg_render(void){
@@ -81,8 +114,7 @@ static void vg_render(void){
 
    glClearColor( 0.0f, 0.3f, 0.5f, 0.0f );
    glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-
-   m4x4_identity( vg.pv );
+   _mc_vg1_render();
 
    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
@@ -91,4 +123,6 @@ static void vg_render(void){
 
 static void vg_gui(void){
    if( marblecomp.op == k_mc_op_clientloading ) return;
+   vg_ui.wants_mouse = 1;
+   _mc_vg1_ui();
 }
diff --git a/shaders/background.h b/shaders/background.h
new file mode 100644 (file)
index 0000000..9300213
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef SHADER_background_H
+#define SHADER_background_H
+static void shader_background_link(void);
+static void shader_background_register(void);
+static struct vg_shader _shader_background = {
+   .name = "background",
+   .link = shader_background_link,
+   .vs = 
+{
+.orig_file = "shaders/background.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform mat3 uPv;\n"
+"uniform vec3 uOffset;\n"
+"\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"   vec2 world_pos = a_co * uOffset.z + uOffset.xy;\n"
+"   gl_Position = vec4( uPv * vec3( world_pos, 1.0 ), 1.0 );\n"
+"   aTexCoords = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/background.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uSamplerNoise;\n"
+"uniform float uVariance;\n"
+"uniform float uVisibility;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"   vec4 data_this_tile = texture( uTexMain, aTexCoords );\n"
+"\n"
+"   float ao_accum = 0.0;\n"
+"   vec2 random_noise;\n"
+"\n"
+"   for( int i=0; i<10; ++i ){\n"
+"      random_noise = (texture( uSamplerNoise, \n"
+"                               aTexCoords*10.0 + float(i)*0.2 ).xy - vec2(0.5)) \n"
+"                               * uVariance;\n"
+"      vec4 background = texture( uTexMain, aTexCoords + random_noise );\n"
+"      float height_diff = min(data_this_tile.r - background.r,0.0);\n"
+"      ao_accum += height_diff * clamp((1.0 - length( random_noise )), 0.0, 1.0);\n"
+"   }\n"
+"   ao_accum *= 0.15;\n"
+"\n"
+"   vec2 square_coords = fract( aTexCoords * 64.0 );\n"
+"   vec2 grid_coords = abs( square_coords - 0.5 );\n"
+"   float gridline = step( 0.49, max(grid_coords.x,grid_coords.y) );\n"
+"\n"
+"   vec3 colour_main = mix( vec3( 0.14 ) + random_noise.x*0.5, \n"
+"                           vec3( 0.1 ) + gridline*0.02, \n"
+"                           data_this_tile.g * uVisibility );\n"
+"   FragColor = vec4( colour_main + ao_accum*0.05, 1.0 );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_background_uPv;
+static GLuint _uniform_background_uOffset;
+static GLuint _uniform_background_uTexMain;
+static GLuint _uniform_background_uSamplerNoise;
+static GLuint _uniform_background_uVariance;
+static GLuint _uniform_background_uVisibility;
+static void shader_background_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_background_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_background_uOffset(v3f const v){
+   glUniform3fv(_uniform_background_uOffset,1,v);
+}
+static void shader_background_uTexMain(int i){
+   glUniform1i(_uniform_background_uTexMain,i);
+}
+static void shader_background_uSamplerNoise(int i){
+   glUniform1i(_uniform_background_uSamplerNoise,i);
+}
+static void shader_background_uVariance(float f){
+   glUniform1f(_uniform_background_uVariance,f);
+}
+static void shader_background_uVisibility(float f){
+   glUniform1f(_uniform_background_uVisibility,f);
+}
+static void shader_background_register(void){
+   vg_shader_register( &_shader_background );
+}
+static void shader_background_use(void){ glUseProgram(_shader_background.id); }
+static void shader_background_link(void){
+   _uniform_background_uPv = glGetUniformLocation( _shader_background.id, "uPv" );
+   _uniform_background_uOffset = glGetUniformLocation( _shader_background.id, "uOffset" );
+   _uniform_background_uTexMain = glGetUniformLocation( _shader_background.id, "uTexMain" );
+   _uniform_background_uSamplerNoise = glGetUniformLocation( _shader_background.id, "uSamplerNoise" );
+   _uniform_background_uVariance = glGetUniformLocation( _shader_background.id, "uVariance" );
+   _uniform_background_uVisibility = glGetUniformLocation( _shader_background.id, "uVisibility" );
+}
+#endif /* SHADER_background_H */
diff --git a/shaders/ball.h b/shaders/ball.h
new file mode 100644 (file)
index 0000000..a7373ed
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef SHADER_ball_H
+#define SHADER_ball_H
+static void shader_ball_link(void);
+static void shader_ball_register(void);
+static struct vg_shader _shader_ball = {
+   .name = "ball",
+   .link = shader_ball_link,
+   .vs = 
+{
+.orig_file = "shaders/ball.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform vec3 uOffset;\n"
+"uniform mat3 uPv;\n"
+"\n"
+"out vec4 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"  // Vertex transform\n"
+"  vec3 worldpos = vec3( (a_co * 0.5 - 0.25) * uOffset.z + uOffset.xy, 1.0 );\n"
+"  gl_Position = vec4( uPv * worldpos, 1.0 );\n"
+"\n"
+"  // Create texture coords\n"
+"  aTexCoords = vec4( a_co, worldpos.xy );\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/ball.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uColour;\n"
+"uniform vec2 uTexOffset;\n"
+"\n"
+"in vec4 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec2 center_coords = aTexCoords.xy - 0.5;\n"
+"      vec2 center_coords_sqr = center_coords*center_coords;\n"
+"      float circle_factor = smoothstep( 0.07, 0.0625, \n"
+"                                     center_coords_sqr.x+center_coords_sqr.y );\n"
+"      \n"
+"      float bulge_amt = center_coords_sqr.x+center_coords_sqr.y;\n"
+"      vec2 warped_coords = aTexCoords.zw+uTexOffset - center_coords;\n"
+"      vec4 noise_sample = texture( uTexMain, warped_coords );\n"
+"      \n"
+"      float rim_light = (center_coords_sqr.x+center_coords_sqr.y)*15.0;\n"
+"      \n"
+"      vec2 shadow_coords = center_coords + vec2(0.02,0.07);\n"
+"      vec2 shadow_coords_sqr = shadow_coords*shadow_coords;\n"
+"      float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);\n"
+"      \n"
+"      vec3 marble_comp = uColour*0.6 + \n"
+"                        (noise_sample.x*2.7+pow(rim_light,3.0)*2.0) * 0.1;\n"
+"      vec4 colour_comp = mix( vec4(0.0,0.0,0.0,shadow), \n"
+"                           vec4(marble_comp,1.0), circle_factor );\n"
+"      FragColor = colour_comp;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_ball_uOffset;
+static GLuint _uniform_ball_uPv;
+static GLuint _uniform_ball_uTexMain;
+static GLuint _uniform_ball_uColour;
+static GLuint _uniform_ball_uTexOffset;
+static void shader_ball_uOffset(v3f const v){
+   glUniform3fv(_uniform_ball_uOffset,1,v);
+}
+static void shader_ball_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_ball_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_ball_uTexMain(int i){
+   glUniform1i(_uniform_ball_uTexMain,i);
+}
+static void shader_ball_uColour(v3f const v){
+   glUniform3fv(_uniform_ball_uColour,1,v);
+}
+static void shader_ball_uTexOffset(v2f const v){
+   glUniform2fv(_uniform_ball_uTexOffset,1,v);
+}
+static void shader_ball_register(void){
+   vg_shader_register( &_shader_ball );
+}
+static void shader_ball_use(void){ glUseProgram(_shader_ball.id); }
+static void shader_ball_link(void){
+   _uniform_ball_uOffset = glGetUniformLocation( _shader_ball.id, "uOffset" );
+   _uniform_ball_uPv = glGetUniformLocation( _shader_ball.id, "uPv" );
+   _uniform_ball_uTexMain = glGetUniformLocation( _shader_ball.id, "uTexMain" );
+   _uniform_ball_uColour = glGetUniformLocation( _shader_ball.id, "uColour" );
+   _uniform_ball_uTexOffset = glGetUniformLocation( _shader_ball.id, "uTexOffset" );
+}
+#endif /* SHADER_ball_H */
diff --git a/shaders/button.h b/shaders/button.h
new file mode 100644 (file)
index 0000000..3cfdc79
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef SHADER_button_H
+#define SHADER_button_H
+static void shader_button_link(void);
+static void shader_button_register(void);
+static struct vg_shader _shader_button = {
+   .name = "button",
+   .link = shader_button_link,
+   .vs = 
+{
+.orig_file = "shaders/button.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform vec4 uOffset; // Tile x/y, uv x/y\n"
+"uniform mat3 uPv;\n"
+"\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      // Vertex transform\n"
+"      vec3 worldpos = vec3( a_co + uOffset.xy, 1.0 );\n"
+"      gl_Position = vec4( uPv * worldpos, 1.0 );\n"
+"\n"
+"      // Create texture coords\n"
+"      vec2 edge_safe_coords = a_co * 0.98 + 0.01;\n"
+"      aTexCoords = (edge_safe_coords + uOffset.zw) * 0.25;    \n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/button.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour; // rgb, light amount\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec4 glyph = texture( uTexMain, aTexCoords.xy );\n"
+"      \n"
+"      FragColor = vec4( uColour.rgb * \n"
+"                     (mix(glyph.r,glyph.g,uColour.a)+0.02)*2.6 + glyph.b * 0.4, \n"
+"                     glyph.a );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_button_uOffset;
+static GLuint _uniform_button_uPv;
+static GLuint _uniform_button_uTexMain;
+static GLuint _uniform_button_uColour;
+static void shader_button_uOffset(v4f const v){
+   glUniform4fv(_uniform_button_uOffset,1,v);
+}
+static void shader_button_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_button_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_button_uTexMain(int i){
+   glUniform1i(_uniform_button_uTexMain,i);
+}
+static void shader_button_uColour(v4f const v){
+   glUniform4fv(_uniform_button_uColour,1,v);
+}
+static void shader_button_register(void){
+   vg_shader_register( &_shader_button );
+}
+static void shader_button_use(void){ glUseProgram(_shader_button.id); }
+static void shader_button_link(void){
+   _uniform_button_uOffset = glGetUniformLocation( _shader_button.id, "uOffset" );
+   _uniform_button_uPv = glGetUniformLocation( _shader_button.id, "uPv" );
+   _uniform_button_uTexMain = glGetUniformLocation( _shader_button.id, "uTexMain" );
+   _uniform_button_uColour = glGetUniformLocation( _shader_button.id, "uColour" );
+}
+#endif /* SHADER_button_H */
diff --git a/shaders/buttons.h b/shaders/buttons.h
new file mode 100644 (file)
index 0000000..5f0bd8a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SHADER_buttons_H
+#define SHADER_buttons_H
+static void shader_buttons_link(void);
+static void shader_buttons_register(void);
+static struct vg_shader _shader_buttons = {
+   .name = "buttons",
+   .link = shader_buttons_link,
+   .vs = 
diff --git a/shaders/post_blur.h b/shaders/post_blur.h
new file mode 100644 (file)
index 0000000..dec41e9
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef SHADER_post_blur_H
+#define SHADER_post_blur_H
+static void shader_post_blur_link(void);
+static void shader_post_blur_register(void);
+static struct vg_shader _shader_post_blur = {
+   .name = "post_blur",
+   .link = shader_post_blur_link,
+   .vs = 
+{
+.orig_file = "shaders/post_blur.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );\n"
+"      aTexCoords = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/post_blur.fs.glsl",
+.static_src = 
+"uniform sampler2D uTexMain;\n"
+"uniform vec2 uDir;\n"
+"out vec4 FragColor;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"   vec4 colour = vec4(0.0);\n"
+"\n"
+"   vec2 off1 = vec2(1.411764705882353)  * uDir;\n"
+"   vec2 off2 = vec2(3.2941176470588234) * uDir;\n"
+"   vec2 off3 = vec2(5.176470588235294)  * uDir;\n"
+"   colour += texture2D( uTexMain, aTexCoords ) * 0.1964825501511404;\n"
+"   colour += texture2D( uTexMain, aTexCoords + off1 ) * 0.2969069646728344;\n"
+"   colour += texture2D( uTexMain, aTexCoords - off1 ) * 0.2969069646728344;\n"
+"   colour += texture2D( uTexMain, aTexCoords + off2 ) * 0.09447039785044732;\n"
+"   colour += texture2D( uTexMain, aTexCoords - off2 ) * 0.09447039785044732;\n"
+"   colour += texture2D( uTexMain, aTexCoords + off3 ) * 0.010381362401148057;\n"
+"   colour += texture2D( uTexMain, aTexCoords - off3 ) * 0.010381362401148057;\n"
+"      FragColor = colour;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_post_blur_uTexMain;
+static GLuint _uniform_post_blur_uDir;
+static void shader_post_blur_uTexMain(int i){
+   glUniform1i(_uniform_post_blur_uTexMain,i);
+}
+static void shader_post_blur_uDir(v2f const v){
+   glUniform2fv(_uniform_post_blur_uDir,1,v);
+}
+static void shader_post_blur_register(void){
+   vg_shader_register( &_shader_post_blur );
+}
+static void shader_post_blur_use(void){ glUseProgram(_shader_post_blur.id); }
+static void shader_post_blur_link(void){
+   _uniform_post_blur_uTexMain = glGetUniformLocation( _shader_post_blur.id, "uTexMain" );
+   _uniform_post_blur_uDir = glGetUniformLocation( _shader_post_blur.id, "uDir" );
+}
+#endif /* SHADER_post_blur_H */
diff --git a/shaders/post_comp.h b/shaders/post_comp.h
new file mode 100644 (file)
index 0000000..a53ee5d
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef SHADER_post_comp_H
+#define SHADER_post_comp_H
+static void shader_post_comp_link(void);
+static void shader_post_comp_register(void);
+static struct vg_shader _shader_post_comp = {
+   .name = "post_comp",
+   .link = shader_post_comp_link,
+   .vs = 
+{
+.orig_file = "shaders/post_comp.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );\n"
+"      aTexCoords = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/post_comp.fs.glsl",
+.static_src = 
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexBloom;\n"
+"uniform vec2 uComp; /* x: bloom, y: vignette */\n"
+"out vec4 FragColor;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec4 texture_sample = texture( uTexMain, aTexCoords );\n"
+"   vec4 bloom_sample = texture( uTexBloom, aTexCoords );\n"
+"   \n"
+"   vec2 vigCoord = aTexCoords - 0.5;\n"
+"   float vig = pow(1.0 - dot( vigCoord, vigCoord ), 2.0);\n"
+"   \n"
+"      FragColor = (texture_sample + bloom_sample*0.3*uComp.x)\n"
+"                * max(uComp.y, vig);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_post_comp_uTexMain;
+static GLuint _uniform_post_comp_uTexBloom;
+static GLuint _uniform_post_comp_uComp;
+static void shader_post_comp_uTexMain(int i){
+   glUniform1i(_uniform_post_comp_uTexMain,i);
+}
+static void shader_post_comp_uTexBloom(int i){
+   glUniform1i(_uniform_post_comp_uTexBloom,i);
+}
+static void shader_post_comp_uComp(v2f const v){
+   glUniform2fv(_uniform_post_comp_uComp,1,v);
+}
+static void shader_post_comp_register(void){
+   vg_shader_register( &_shader_post_comp );
+}
+static void shader_post_comp_use(void){ glUseProgram(_shader_post_comp.id); }
+static void shader_post_comp_link(void){
+   _uniform_post_comp_uTexMain = glGetUniformLocation( _shader_post_comp.id, "uTexMain" );
+   _uniform_post_comp_uTexBloom = glGetUniformLocation( _shader_post_comp.id, "uTexBloom" );
+   _uniform_post_comp_uComp = glGetUniformLocation( _shader_post_comp.id, "uComp" );
+}
+#endif /* SHADER_post_comp_H */
diff --git a/shaders/post_darken.h b/shaders/post_darken.h
new file mode 100644 (file)
index 0000000..a7ece29
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef SHADER_post_darken_H
+#define SHADER_post_darken_H
+static void shader_post_darken_link(void);
+static void shader_post_darken_register(void);
+static struct vg_shader _shader_post_darken = {
+   .name = "post_darken",
+   .link = shader_post_darken_link,
+   .vs = 
+{
+.orig_file = "shaders/post_darken.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      gl_Position = vec4( a_co * 2.0 - 1.0, 0.0, 1.0 );\n"
+"      aTexCoords = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/post_darken.fs.glsl",
+.static_src = 
+"uniform sampler2D uTexMain;\n"
+"out vec4 FragColor;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec4 texture_sample = texture( uTexMain, aTexCoords );\n"
+"      FragColor = vec4(pow(texture_sample.rgb,vec3(2.2)), 1.0);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_post_darken_uTexMain;
+static void shader_post_darken_uTexMain(int i){
+   glUniform1i(_uniform_post_darken_uTexMain,i);
+}
+static void shader_post_darken_register(void){
+   vg_shader_register( &_shader_post_darken );
+}
+static void shader_post_darken_use(void){ glUseProgram(_shader_post_darken.id); }
+static void shader_post_darken_link(void){
+   _uniform_post_darken_uTexMain = glGetUniformLocation( _shader_post_darken.id, "uTexMain" );
+}
+#endif /* SHADER_post_darken_H */
diff --git a/shaders/sprite.h b/shaders/sprite.h
new file mode 100644 (file)
index 0000000..c221ea8
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef SHADER_sprite_H
+#define SHADER_sprite_H
+static void shader_sprite_link(void);
+static void shader_sprite_register(void);
+static struct vg_shader _shader_sprite = {
+   .name = "sprite",
+   .link = shader_sprite_link,
+   .vs = 
+{
+.orig_file = "shaders/sprite.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co; // quad mesh\n"
+"uniform vec4 uUv;\n"
+"uniform vec3 uPos;\n"
+"\n"
+"uniform mat3 uPv;\n"
+"\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec2 vertex_world = uUv.zw * (a_co-0.5) * uPos.z + uPos.xy;\n"
+"      gl_Position = vec4( uPv * vec3( vertex_world, 1.0 ), 1.0 );\n"
+"      aTexCoords = uUv.xy + a_co*uUv.zw;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/sprite.fs.glsl",
+.static_src = 
+"uniform sampler2D uTexMain;\n"
+"out vec4 FragColor;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      vec4 texture_sample = texture( uTexMain, aTexCoords );\n"
+"      FragColor = texture_sample;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_sprite_uUv;
+static GLuint _uniform_sprite_uPos;
+static GLuint _uniform_sprite_uPv;
+static GLuint _uniform_sprite_uTexMain;
+static void shader_sprite_uUv(v4f const v){
+   glUniform4fv(_uniform_sprite_uUv,1,v);
+}
+static void shader_sprite_uPos(v3f const v){
+   glUniform3fv(_uniform_sprite_uPos,1,v);
+}
+static void shader_sprite_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_sprite_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_sprite_uTexMain(int i){
+   glUniform1i(_uniform_sprite_uTexMain,i);
+}
+static void shader_sprite_register(void){
+   vg_shader_register( &_shader_sprite );
+}
+static void shader_sprite_use(void){ glUseProgram(_shader_sprite.id); }
+static void shader_sprite_link(void){
+   _uniform_sprite_uUv = glGetUniformLocation( _shader_sprite.id, "uUv" );
+   _uniform_sprite_uPos = glGetUniformLocation( _shader_sprite.id, "uPos" );
+   _uniform_sprite_uPv = glGetUniformLocation( _shader_sprite.id, "uPv" );
+   _uniform_sprite_uTexMain = glGetUniformLocation( _shader_sprite.id, "uTexMain" );
+}
+#endif /* SHADER_sprite_H */
diff --git a/shaders/tile_colour.h b/shaders/tile_colour.h
new file mode 100644 (file)
index 0000000..67aa2f2
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef SHADER_tile_colour_H
+#define SHADER_tile_colour_H
+static void shader_tile_colour_link(void);
+static void shader_tile_colour_register(void);
+static struct vg_shader _shader_tile_colour = {
+   .name = "tile_colour",
+   .link = shader_tile_colour_link,
+   .vs = 
+{
+.orig_file = "shaders/tile_colour.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform mat3 uPv;\n"
+"uniform vec3 uOffset;\n"
+"\n"
+"void main(){\n"
+"   gl_Position = vec4( uPv * vec3( a_co * uOffset.z + uOffset.xy, 1.0 ), 1.0 );\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/tile_colour.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"uniform vec4 uColour;\n"
+"void main(){\n"
+"   FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_tile_colour_uPv;
+static GLuint _uniform_tile_colour_uOffset;
+static GLuint _uniform_tile_colour_uColour;
+static void shader_tile_colour_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_tile_colour_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_tile_colour_uOffset(v3f const v){
+   glUniform3fv(_uniform_tile_colour_uOffset,1,v);
+}
+static void shader_tile_colour_uColour(v4f const v){
+   glUniform4fv(_uniform_tile_colour_uColour,1,v);
+}
+static void shader_tile_colour_register(void){
+   vg_shader_register( &_shader_tile_colour );
+}
+static void shader_tile_colour_use(void){ glUseProgram(_shader_tile_colour.id); }
+static void shader_tile_colour_link(void){
+   _uniform_tile_colour_uPv = glGetUniformLocation( _shader_tile_colour.id, "uPv" );
+   _uniform_tile_colour_uOffset = glGetUniformLocation( _shader_tile_colour.id, "uOffset" );
+   _uniform_tile_colour_uColour = glGetUniformLocation( _shader_tile_colour.id, "uColour" );
+}
+#endif /* SHADER_tile_colour_H */
diff --git a/shaders/tile_main.h b/shaders/tile_main.h
new file mode 100644 (file)
index 0000000..283ef55
--- /dev/null
@@ -0,0 +1,161 @@
+#ifndef SHADER_tile_main_H
+#define SHADER_tile_main_H
+static void shader_tile_main_link(void);
+static void shader_tile_main_register(void);
+static struct vg_shader _shader_tile_main = {
+   .name = "tile_main",
+   .link = shader_tile_main_link,
+   .vs = 
+{
+.orig_file = "shaders/tile_main.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform vec4 uOffset; // Tile x/y, uv x/y\n"
+"uniform mat3 uPv;\n"
+"uniform mat2 uSubTransform;\n"
+"uniform float uVisibility;\n"
+"\n"
+"out vec4 aTexCoords;\n"
+"out vec2 aWorldCoords;\n"
+"\n"
+"vec2 hash22(vec2 p){\n"
+"      vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));\n"
+"      p3 += dot(p3, p3.yzx+33.33);\n"
+"      return fract((p3.xx+p3.yz)*p3.zy);\n"
+"}\n"
+"\n"
+"void main(){\n"
+"      vec2 hash_val = hash22(uOffset.xy);\n"
+"      float scaling_factor = smoothstep( hash_val.x, hash_val.x+1.0, uVisibility );\n"
+"\n"
+"      // Vertex transform\n"
+"      vec2 subtransform = uSubTransform * (a_co-0.5) * scaling_factor + 0.5;\n"
+"      vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );\n"
+"      gl_Position = vec4( uPv * worldpos, 1.0 );\n"
+"\n"
+"      // Create texture coords\n"
+"      vec2 random_offset = floor(hash_val * 4.0) * 0.25;\n"
+"      vec2 edge_safe_coords = a_co * 0.98 + 0.01;\n"
+"      aTexCoords = vec4((edge_safe_coords + uOffset.zw) * 0.25, \n"
+"                      edge_safe_coords * 0.25 + random_offset );\n"
+"      aWorldCoords = worldpos.xy;             \n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/tile_main.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexGlyphs;\n"
+"uniform sampler2D uTexGlow;\n"
+"uniform sampler2D uTexWood;\n"
+"uniform float uGhost;\n"
+"uniform float uForeground;\n"
+"uniform vec2 uMousePos;\n"
+"uniform vec4 uColour;\n"
+"uniform vec3 uShadowing;\n"
+"uniform vec3 uGlowA;\n"
+"uniform vec3 uGlowB;\n"
+"\n"
+"in vec4 aTexCoords;\n"
+"in vec2 aWorldCoords;\n"
+"\n"
+"void main(){\n"
+"   vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );\n"
+"   vec4 glyph_glow = texture( uTexGlow, aTexCoords.xy );\n"
+"   vec4 wood = texture( uTexWood, aTexCoords.zw );\n"
+"   vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );\n"
+"   vec3 wood_comp = mix( wood_secondary.rgb * uShadowing, \n"
+"                         wood.rgb, clamp( glyph.b*2.0-1.0, 0.0, 1.0 ) );\n"
+"   \n"
+"   vec3 shadows = mix( uShadowing, vec3(1.0,1.0,1.0), glyph.r );\n"
+"   vec4 output_regular = vec4( wood_comp * shadows, \n"
+"                               mix( glyph.a, glyph.b, uForeground ) );\n"
+"   \n"
+"   float ghost_dist = clamp( 1.5-distance(uMousePos, aWorldCoords), 0.0, 1.0 );\n"
+"   vec4 output_ghost = vec4( 1.0, 1.0, 1.0, glyph.g*ghost_dist );\n"
+"   vec4 glow_comp = vec4(glyph_glow.b*uGlowA+glyph_glow.g*uGlowB,0.0);\n"
+"   \n"
+"   FragColor = mix( output_regular, output_ghost, uGhost )*uColour + glow_comp;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_tile_main_uOffset;
+static GLuint _uniform_tile_main_uPv;
+static GLuint _uniform_tile_main_uSubTransform;
+static GLuint _uniform_tile_main_uVisibility;
+static GLuint _uniform_tile_main_uTexGlyphs;
+static GLuint _uniform_tile_main_uTexGlow;
+static GLuint _uniform_tile_main_uTexWood;
+static GLuint _uniform_tile_main_uGhost;
+static GLuint _uniform_tile_main_uForeground;
+static GLuint _uniform_tile_main_uMousePos;
+static GLuint _uniform_tile_main_uColour;
+static GLuint _uniform_tile_main_uShadowing;
+static GLuint _uniform_tile_main_uGlowA;
+static GLuint _uniform_tile_main_uGlowB;
+static void shader_tile_main_uOffset(v4f const v){
+   glUniform4fv(_uniform_tile_main_uOffset,1,v);
+}
+static void shader_tile_main_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_tile_main_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_tile_main_uSubTransform(m2x2f m){
+   glUniformMatrix2fv(_uniform_tile_main_uSubTransform,1,GL_FALSE,(float*)m);
+}
+static void shader_tile_main_uVisibility(float f){
+   glUniform1f(_uniform_tile_main_uVisibility,f);
+}
+static void shader_tile_main_uTexGlyphs(int i){
+   glUniform1i(_uniform_tile_main_uTexGlyphs,i);
+}
+static void shader_tile_main_uTexGlow(int i){
+   glUniform1i(_uniform_tile_main_uTexGlow,i);
+}
+static void shader_tile_main_uTexWood(int i){
+   glUniform1i(_uniform_tile_main_uTexWood,i);
+}
+static void shader_tile_main_uGhost(float f){
+   glUniform1f(_uniform_tile_main_uGhost,f);
+}
+static void shader_tile_main_uForeground(float f){
+   glUniform1f(_uniform_tile_main_uForeground,f);
+}
+static void shader_tile_main_uMousePos(v2f const v){
+   glUniform2fv(_uniform_tile_main_uMousePos,1,v);
+}
+static void shader_tile_main_uColour(v4f const v){
+   glUniform4fv(_uniform_tile_main_uColour,1,v);
+}
+static void shader_tile_main_uShadowing(v3f const v){
+   glUniform3fv(_uniform_tile_main_uShadowing,1,v);
+}
+static void shader_tile_main_uGlowA(v3f const v){
+   glUniform3fv(_uniform_tile_main_uGlowA,1,v);
+}
+static void shader_tile_main_uGlowB(v3f const v){
+   glUniform3fv(_uniform_tile_main_uGlowB,1,v);
+}
+static void shader_tile_main_register(void){
+   vg_shader_register( &_shader_tile_main );
+}
+static void shader_tile_main_use(void){ glUseProgram(_shader_tile_main.id); }
+static void shader_tile_main_link(void){
+   _uniform_tile_main_uOffset = glGetUniformLocation( _shader_tile_main.id, "uOffset" );
+   _uniform_tile_main_uPv = glGetUniformLocation( _shader_tile_main.id, "uPv" );
+   _uniform_tile_main_uSubTransform = glGetUniformLocation( _shader_tile_main.id, "uSubTransform" );
+   _uniform_tile_main_uVisibility = glGetUniformLocation( _shader_tile_main.id, "uVisibility" );
+   _uniform_tile_main_uTexGlyphs = glGetUniformLocation( _shader_tile_main.id, "uTexGlyphs" );
+   _uniform_tile_main_uTexGlow = glGetUniformLocation( _shader_tile_main.id, "uTexGlow" );
+   _uniform_tile_main_uTexWood = glGetUniformLocation( _shader_tile_main.id, "uTexWood" );
+   _uniform_tile_main_uGhost = glGetUniformLocation( _shader_tile_main.id, "uGhost" );
+   _uniform_tile_main_uForeground = glGetUniformLocation( _shader_tile_main.id, "uForeground" );
+   _uniform_tile_main_uMousePos = glGetUniformLocation( _shader_tile_main.id, "uMousePos" );
+   _uniform_tile_main_uColour = glGetUniformLocation( _shader_tile_main.id, "uColour" );
+   _uniform_tile_main_uShadowing = glGetUniformLocation( _shader_tile_main.id, "uShadowing" );
+   _uniform_tile_main_uGlowA = glGetUniformLocation( _shader_tile_main.id, "uGlowA" );
+   _uniform_tile_main_uGlowB = glGetUniformLocation( _shader_tile_main.id, "uGlowB" );
+}
+#endif /* SHADER_tile_main_H */
diff --git a/shaders/wire.h b/shaders/wire.h
new file mode 100644 (file)
index 0000000..1760469
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef SHADER_wire_H
+#define SHADER_wire_H
+static void shader_wire_link(void);
+static void shader_wire_register(void);
+static struct vg_shader _shader_wire = {
+   .name = "wire",
+   .link = shader_wire_link,
+   .vs = 
+{
+.orig_file = "shaders/wire.vs.glsl",
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"uniform vec3 uStart;\n"
+"uniform vec3 uEnd;\n"
+"uniform mat3 uPv;\n"
+"uniform float uCurve;\n"
+"\n"
+"out vec2 aTexCoords;\n"
+"\n"
+"vec3 sample_curve_time( float t ){\n"
+"      vec3 line_coord = mix( uStart, uEnd, t );\n"
+"\n"
+"      float curve_amt = 1.0-(pow((t*2.0-1.0),2.0));\n"
+"      return vec3( line_coord.x, line_coord.y - curve_amt*uCurve, line_coord.z );\n"
+"}\n"
+"\n"
+"void main(){\n"
+"      // Vertex transform\n"
+"      vec3 p0 = sample_curve_time( a_co.x );\n"
+"      vec3 p1 = sample_curve_time( a_co.x + 0.025 );\n"
+"      \n"
+"      vec2 line_tangent = normalize(p1.xy-p0.xy);\n"
+"      vec2 line_normal = vec2( -line_tangent.y, line_tangent.x );\n"
+"      \n"
+"      vec2 worldfinal = p0.xy + line_normal*a_co.y*p0.z;\n"
+"      \n"
+"      gl_Position = vec4( uPv * vec3(worldfinal, 1.0), 1.0 );\n"
+"\n"
+"      // Create texture coords (todo: include stretch adjusted coords?)\n"
+"      aTexCoords = vec2( a_co.x, a_co.y + 0.5 );\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "shaders/wire.fs.glsl",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"uniform float uTime;\n"
+"uniform float uGlow;\n"
+"\n"
+"in vec2 aTexCoords;\n"
+"\n"
+"void main(){\n"
+"      // Compute shadowing\n"
+"      float shadow = 1.0 - abs(aTexCoords.y - 0.5) * 2.0;\n"
+"      float masking = smoothstep( 0.5, 0.8, shadow );\n"
+"      \n"
+"      vec3 colour_comp = mix( vec3(0.0,0.0,0.0), uColour.rgb, masking );\n"
+"      \n"
+"      float flow_thing = fract( aTexCoords.x + uTime );\n"
+"      vec3 final_comp = colour_comp + flow_thing * uGlow;\n"
+"      \n"
+"      FragColor = vec4( final_comp, max( shadow* 0.2, masking ) * uColour.a );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_wire_uStart;
+static GLuint _uniform_wire_uEnd;
+static GLuint _uniform_wire_uPv;
+static GLuint _uniform_wire_uCurve;
+static GLuint _uniform_wire_uTexMain;
+static GLuint _uniform_wire_uColour;
+static GLuint _uniform_wire_uTime;
+static GLuint _uniform_wire_uGlow;
+static void shader_wire_uStart(v3f const v){
+   glUniform3fv(_uniform_wire_uStart,1,v);
+}
+static void shader_wire_uEnd(v3f const v){
+   glUniform3fv(_uniform_wire_uEnd,1,v);
+}
+static void shader_wire_uPv(m3x3f m){
+   glUniformMatrix3fv(_uniform_wire_uPv,1,GL_FALSE,(float*)m);
+}
+static void shader_wire_uCurve(float f){
+   glUniform1f(_uniform_wire_uCurve,f);
+}
+static void shader_wire_uTexMain(int i){
+   glUniform1i(_uniform_wire_uTexMain,i);
+}
+static void shader_wire_uColour(v4f const v){
+   glUniform4fv(_uniform_wire_uColour,1,v);
+}
+static void shader_wire_uTime(float f){
+   glUniform1f(_uniform_wire_uTime,f);
+}
+static void shader_wire_uGlow(float f){
+   glUniform1f(_uniform_wire_uGlow,f);
+}
+static void shader_wire_register(void){
+   vg_shader_register( &_shader_wire );
+}
+static void shader_wire_use(void){ glUseProgram(_shader_wire.id); }
+static void shader_wire_link(void){
+   _uniform_wire_uStart = glGetUniformLocation( _shader_wire.id, "uStart" );
+   _uniform_wire_uEnd = glGetUniformLocation( _shader_wire.id, "uEnd" );
+   _uniform_wire_uPv = glGetUniformLocation( _shader_wire.id, "uPv" );
+   _uniform_wire_uCurve = glGetUniformLocation( _shader_wire.id, "uCurve" );
+   _uniform_wire_uTexMain = glGetUniformLocation( _shader_wire.id, "uTexMain" );
+   _uniform_wire_uColour = glGetUniformLocation( _shader_wire.id, "uColour" );
+   _uniform_wire_uTime = glGetUniformLocation( _shader_wire.id, "uTime" );
+   _uniform_wire_uGlow = glGetUniformLocation( _shader_wire.id, "uGlow" );
+}
+#endif /* SHADER_wire_H */
index 7e4ceb75505ef4ea9bdd74ba95095e3ce4d7904b..c1ba2b998f7c9779bbefc4f0e8f02c320fbb7943 100644 (file)
@@ -14,10 +14,6 @@ static struct button_binding vg_button_binds[] =
 
 static struct axis_binding vg_axis_binds[] = 
 {
-       { .name = "primary",    .positive = GLFW_MOUSE_BUTTON_LEFT,     .negative = -1 },
-       { .name = "secondary",  .positive = GLFW_MOUSE_BUTTON_RIGHT,    .negative = -1 },
-       { .name = "horizontal", .positive = GLFW_KEY_D,                                         .negative = GLFW_KEY_A },
-       { .name = "vertical",   .positive = GLFW_KEY_W,                                         .negative = GLFW_KEY_S }
 };
 
 static struct vg_achievement vg_achievements[] =