From: hgn Date: Wed, 20 Oct 2021 16:51:19 +0000 (+0100) Subject: added spinny bits X-Git-Url: https://harrygodden.com/git/?p=fishladder.git;a=commitdiff_plain;h=c8165f11120b296045f670bbdd8e614e92b0c5e8 added spinny bits --- diff --git a/fishladder.c b/fishladder.c index bf877e3..ce43fa2 100644 --- a/fishladder.c +++ b/fishladder.c @@ -32,6 +32,7 @@ SHADER_DEFINE( shader_tile_main, "layout (location=0) in vec2 a_co;" "uniform vec4 uOffset;" // Tile x/y, uv x/y "uniform mat3 uPv;" + "uniform mat2 uSubTransform;" "" "out vec4 aTexCoords;" "" @@ -44,10 +45,15 @@ SHADER_DEFINE( shader_tile_main, "" "void main()" "{" + // Create texture coords "vec2 random_offset = floor(hash22(uOffset.xy) * 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 );" - "gl_Position = vec4( uPv * vec3( a_co + uOffset.xy, 1.0 ), 1.0 );" + + // Vertex transform + "vec2 subtransform = uSubTransform * (a_co-0.5) + 0.5;" + "vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );" + "gl_Position = vec4( uPv * worldpos, 1.0 );" "}", // FRAGMENT @@ -68,10 +74,10 @@ SHADER_DEFINE( shader_tile_main, "vec3 shadows = mix( vec3( 0.85, 0.7344, 0.561 ), vec3(1.0,1.0,1.0), glyph.r );" - "FragColor = vec4( wood_comp * shadows, 1.0 );" + "FragColor = vec4( wood_comp * shadows, glyph.b );" "}" , - UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood" }) + UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform" }) ) const char *level_pack[] = @@ -149,6 +155,7 @@ m3x3f m_mdl; #define FLAG_MERGER 0x40 #define FLAG_DROP_R 0x80 #define FLAG_FLIP_FLOP 0x100 +#define FLAG_FLIP_ROTATING 0x200 v3f colour_sets[] = { { 0.9f, 0.2f, 0.01f }, @@ -514,11 +521,10 @@ static int cell_interactive( v2i co ) // List of 3x3 configurations that we do not allow static u32 invalid_src[][9] = { - /* { 0,1,0, 1,1,1, 0,1,0 - },*/ + }, { 0,0,0, 0,1,1, 0,1,1 @@ -535,7 +541,6 @@ static int cell_interactive( v2i co ) 1,1,0, 0,0,0 }, - /* { 0,1,0, 0,1,1, 0,1,0 @@ -543,7 +548,7 @@ static int cell_interactive( v2i co ) { 0,1,0, 1,1,0, 0,1,0 - }*/ + } }; // Statically compile invalid configurations into bitmasks @@ -719,7 +724,9 @@ void vg_update(void) if( config == 0x7 ) // splitter { - world.data[y*world.w+x ].state |= (FLAG_SPLIT | FLAG_DROP_L | FLAG_DROP_R); + struct cell *cell = pcell((v2i){x,y}); + + cell->state |= (FLAG_SPLIT | FLAG_DROP_L | FLAG_DROP_R); } else if( config == 0xD ) { @@ -770,6 +777,16 @@ void vg_update(void) } } } + + // Update splitter deltas + for( int i = 0; i < world.h*world.w; i ++ ) + { + struct cell *cell = &world.data[i]; + if( cell->config == 0x7 ) + { + cell->state &= ~FLAG_FLIP_ROTATING; + } + } for( int i = 0; i < world.num_fishes; i ++ ) { @@ -842,6 +859,10 @@ void vg_update(void) fish->pos[0] += fish->dir[0]; fish->pos[1] += fish->dir[1]; + + struct cell *cell_entry = pcell( fish->pos ); + if( cell_entry->config == 0x7 ) + cell_entry->state |= FLAG_FLIP_ROTATING; } } @@ -858,6 +879,14 @@ void vg_render(void) glClearColor( 0.8f, 0.8f, 0.8f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + float scaled_time = 0.0f, frame_lerp = 0.0f; + + if( world.simulating ) + { + scaled_time = (vg_time-world.sim_start)*2.0f; + frame_lerp = scaled_time - (float)world.sim_frame; + } + // Shadow layer /* glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.5f, 0.5f, 0.5f, 1.0f ); @@ -925,12 +954,24 @@ void vg_render(void) } */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); + v2f const curve_3[] = {{0.5f,1.0f},{0.5f,0.625f},{0.625f,0.5f},{1.0f,0.5f}}; + v2f const curve_6[] = {{0.5f,1.0f},{0.5f,0.625f},{0.375f,0.5f},{0.0f,0.5f}}; + v2f const curve_9[] = {{1.0f,0.5f},{0.625f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; + v2f const curve_12[]= {{0.0f,0.5f},{0.375f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; + + v2f const curve_7[] = {{0.5f,0.8438f},{0.875f,0.8438f},{0.625f,0.5f},{1.0f,0.5f}}; + v2f const curve_7_1[] = {{0.5f,0.8438f},{1.0f-0.875f,0.8438f},{1.0-0.625f,0.5f},{0.0f,0.5f}}; + float const curve_7_linear_section = 0.1562f; + + // TILE SET RENDERING + // ====================================================================== use_mesh( &world.tile ); SHADER_USE( shader_tile_main ); + + m2x2f subtransform; + m2x2_identity( subtransform ); + glUniformMatrix2fv( SHADER_UNIFORM( shader_tile_main, "uSubTransform" ), 1, GL_FALSE, (float *)subtransform ); glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_main, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); // Bind textures @@ -984,18 +1025,57 @@ void vg_render(void) uv[1] = tile_offsets[ cell->config ][1]; } - glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), (float)x, (float)y, uv[0], uv[1] ); // TODO: PICK GLYPH + glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), (float)x, (float)y, uv[0], uv[1] ); draw_mesh( 0, 2 ); } } + + // Draw splitters + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); - SHADER_USE( shader_tile_colour ); - glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); + for( int y = 0; y < world.h; y ++ ) + { + for( int x = 0; x < world.w; x ++ ) + { + struct cell *cell = pcell((v2i){x,y}); + + if( cell->state & FLAG_SPLIT ) + { + float rotation = cell->state & FLAG_FLIP_FLOP? vg_rad( -45.0f ): vg_rad( 45.0f ); + + if( cell->state & FLAG_FLIP_ROTATING ) + { + if( (frame_lerp > curve_7_linear_section) ) + { + float const rotation_speed = 0.4f; + if( (frame_lerp < 1.0f-rotation_speed) ) + { + float t = frame_lerp - curve_7_linear_section; + t *= -2.0f * (1.0f/(1.0f-(curve_7_linear_section+rotation_speed))); + t += 1.0f; + + rotation *= t; + } + else + rotation *= -1.0f; + } + } + + 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)x, (float)y + 0.125f, 0.0f, 0.0f ); + draw_mesh( 0, 2 ); + } + } + } glDisable(GL_BLEND); - - - + + SHADER_USE( shader_tile_colour ); + glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); use_mesh( &world.circle ); // Draw i/o arrays @@ -1050,9 +1130,6 @@ void vg_render(void) // Draw 'fish' if( world.simulating ) { - float scaled_time = (vg_time-world.sim_start)*2.0f; - float lerp = scaled_time - (float)world.sim_frame; - v4f dot_colour = { 0.0f, 0.0f, 0.0f, 1.0f }; for( int i = 0; i < world.num_fishes; i ++ ) @@ -1069,19 +1146,9 @@ void vg_render(void) struct cell *cell = pcell(fish->pos); v2f fish_pos; - v2f const curve_3[] = {{0.5f,1.0f},{0.5f,0.625f},{0.625f,0.5f},{1.0f,0.5f}}; - v2f const curve_6[] = {{0.5f,1.0f},{0.5f,0.625f},{0.375f,0.5f},{0.0f,0.5f}}; - v2f const curve_9[] = {{1.0f,0.5f},{0.625f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; - v2f const curve_12[]= {{0.0f,0.5f},{0.375f,0.5f},{0.5f,0.375f},{0.5f,0.0f}}; - - v2f const curve_7[] = {{0.5f,0.8438f},{0.875f,0.8438f},{0.625f,0.5f},{1.0f,0.5f}}; - v2f const curve_7_1[] = {{0.5f,0.8438f},{1.0f-0.875f,0.8438f},{1.0-0.625f,0.5f},{0.0f,0.5f}}; - - float const linear_section = 0.1562f; - v2f const *curve; - float t = lerp; + float t = frame_lerp; switch( cell->config ) { @@ -1096,10 +1163,10 @@ void vg_render(void) case 9: curve = curve_9; break; case 12: curve = curve_12; break; case 7: - if( t > linear_section ) + if( t > curve_7_linear_section ) { - t -= linear_section; - t *= (1.0f/(1.0f-linear_section)); + t -= curve_7_linear_section; + t *= (1.0f/(1.0f-curve_7_linear_section)); curve = cell->state & FLAG_FLIP_FLOP? curve_7: curve_7_1; } diff --git a/textures/tileset.png b/textures/tileset.png index 7b84b6c..0a97798 100644 Binary files a/textures/tileset.png and b/textures/tileset.png differ diff --git a/vg/vg_m.h b/vg/vg_m.h index 27481ae..0c4ba35 100644 --- a/vg/vg_m.h +++ b/vg/vg_m.h @@ -226,6 +226,40 @@ static inline void v4_zero( v4f a ) a[0] = 0.f; a[1] = 0.f; a[2] = 0.f; a[3] = 0.f; } +// Matrix 2x2 +// =========================================================================================================== + +#define M2X2_INDENTIY {{1.0f, 0.0f, }, \ + { 0.0f, 1.0f, }} + +#define M2X2_ZERO {{0.0f, 0.0f, }, \ + { 0.0f, 0.0f, }} + +static inline void m2x2_copy( m2x2f a, m2x2f b ) +{ + v2_copy( a[0], b[0] ); + v2_copy( a[1], b[1] ); +} + +static inline void m2x2_identity( m2x2f a ) +{ + m2x2f id = M2X2_INDENTIY; + m2x2_copy( id, a ); +} + +static inline void m2x2_create_rotation( m2x2f a, float theta ) +{ + float s, c; + + s = sinf( theta ); + c = cosf( theta ); + + a[0][0] = c; + a[0][1] = -s; + a[1][0] = s; + a[1][1] = c; +} + // Matrix 3x3 //====================================================================================================== diff --git a/vg/vg_platform.h b/vg/vg_platform.h index a5b3603..2c5e363 100644 --- a/vg/vg_platform.h +++ b/vg/vg_platform.h @@ -17,6 +17,7 @@ typedef int v4i[4]; typedef float v2f[2]; typedef float v3f[3]; typedef float v4f[4]; +typedef v2f m2x2f[2]; typedef v3f m3x3f[3]; typedef v3f m4x3f[4]; typedef v3f boxf[2];