added spinny bits
authorhgn <hgodden00@gmail.com>
Wed, 20 Oct 2021 16:51:19 +0000 (17:51 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 20 Oct 2021 16:51:19 +0000 (17:51 +0100)
fishladder.c
textures/tileset.png
vg/vg_m.h
vg/vg_platform.h

index bf877e33b19e04f21bf4102ea50a8171f77a7381..ce43fa27bc29108473e17010c9b8efa85b6363df 100644 (file)
@@ -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;
                                        }
index 7b84b6c4b4a3aa9ff4d78edb3e9db1d5e3af537b..0a9779847e5e3e87e1e40b94ad1d44a6c23c95fb 100644 (file)
Binary files a/textures/tileset.png and b/textures/tileset.png differ
index 27481ae995db9b3aca8694ffea139671e9f27438..0c4ba358593af4927a59f6e6335906a5cf0e653c 100644 (file)
--- 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
 //======================================================================================================
 
index a5b36033e0edd9ccfb04df9591b974086df39926..2c5e36317b61a6a06c2a56bf9acb2d2b3175955f 100644 (file)
@@ -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];