"aTexCoords = a_co;"
// Vertex transform
- "vec3 worldpos = vec3( a_co * 0.25 - 0.125 + uOffset, 1.0 );"
+ "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );"
"gl_Position = vec4( uPv * worldpos, 1.0 );"
"}",
"void main()"
"{"
"vec4 glyph = texture( uTexMain, aTexCoords );"
- "FragColor = vec4( glyph.rgb * uColour, glyph.a );"
+ "FragColor = vec4( uColour + glyph.rgb * 0.2, glyph.a );"
"}"
,
UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv" })
GLuint tex_wood;
GLuint tex_ball;
+sfx_system_t audio_system_sfx =
+{
+ .vol = 1.f,
+ .spd = 1.f,
+ .ch = 1,
+ .cur = 0,
+ .vol_src = &g_vol_sfx,
+ .flags = 0x00,
+ .fadeout = FADEOUT_LENGTH,
+ .name = "sfx"
+};
+
+sfx_set_t audio_tile_mod =
+{
+ .sources = "\
+sound/mod00.ogg\0\
+sound/mod01.ogg\0\
+sound/mod02.ogg\0\
+sound/mod03.ogg\0",
+ .flags = 0
+};
+
m3x3f m_projection;
m3x3f m_view;
m3x3f m_mdl;
vg_tex2d_linear_mipmap();
vg_tex2d_repeat();
- tex_ball = vg_tex2d_rgba( "textures/ball_metallic.png" );
+ tex_ball = vg_tex2d_rgba( "textures/ball.png" );
vg_tex2d_mipmap();
vg_tex2d_linear_mipmap();
vg_tex2d_clamp();
}
+ // Audio
+ {
+ sfx_set_init( &audio_tile_mod, NULL );
+ }
+
map_load( level_pack[ 0 ] );
}
glDeleteTextures( 1, &tex_tile_detail );
glDeleteTextures( 1, &tex_wood );
glDeleteTextures( 1, &tex_ball );
+
+ sfx_set_free( &audio_tile_mod );
}
static int cell_interactive( v2i co )
if( vg_get_button_down("primary") )
{
world.data[ world.selected ].state ^= FLAG_CANAL;
+ sfx_set_playrnd( &audio_tile_mod, &audio_system_sfx );
}
}
else
continue;
}
- if( !(cell_current->state & (FLAG_INPUT|FLAG_CANAL)) )
+ if( cell_current->state & FLAG_SPLIT )
{
- fish->alive = 0;
+ // Flip flop L/R
+ fish->dir[0] = cell_current->state&FLAG_FLIP_FLOP?1:-1;
+ fish->dir[1] = 0;
+
+ cell_current->state ^= FLAG_FLIP_FLOP;
+ }
+ else if( cell_current->state & FLAG_MERGER )
+ {
+ // Can only move up
+ fish->dir[0] = 0;
+ fish->dir[1] = -1;
}
else
{
- if( cell_current->state & FLAG_SPLIT )
+ struct cell *cell_next = pcell( (v2i){ fish->pos[0]+fish->dir[0], fish->pos[1]+fish->dir[1] } );
+ if( !(cell_next->state & (FLAG_CANAL|FLAG_OUTPUT)) )
{
- // Flip flop L/R
- fish->dir[0] = cell_current->state&FLAG_FLIP_FLOP?1:-1;
- fish->dir[1] = 0;
+ // Try other directions for valid, so down, left, right..
+ v2i dirs[] = {{1,0},{-1,0},{0,-1}};
+ vg_info( "Trying some other directions...\n" );
- cell_current->state ^= FLAG_FLIP_FLOP;
- }
- else if( cell_current->state & FLAG_MERGER )
- {
- // Can only move up
- fish->dir[0] = 0;
- fish->dir[1] = -1;
- }
- else
- {
- struct cell *cell_next = pcell( (v2i){ fish->pos[0]+fish->dir[0], fish->pos[1]+fish->dir[1] } );
- if( !(cell_next->state & (FLAG_CANAL|FLAG_OUTPUT)) )
+ for( int j = 0; j < vg_list_size(dirs); j ++ )
{
- // Try other directions for valid, so down, left, right..
- v2i dirs[] = {{1,0},{-1,0},{0,-1}};
- vg_info( "Trying some other directions...\n" );
-
- for( int j = 0; j < vg_list_size(dirs); j ++ )
+ if( (dirs[j][0] == -fish->dir[0]) && (dirs[j][1] == -fish->dir[1]) )
+ continue;
+
+ if( pcell( (v2i){ fish->pos[0]+dirs[j][0], fish->pos[1]+dirs[j][1] } )->state & (FLAG_CANAL|FLAG_OUTPUT) )
{
- if( (dirs[j][0] == -fish->dir[0]) && (dirs[j][1] == -fish->dir[1]) )
- continue;
-
- if( pcell( (v2i){ fish->pos[0]+dirs[j][0], fish->pos[1]+dirs[j][1] } )->state & (FLAG_CANAL|FLAG_OUTPUT) )
- {
- fish->dir[0] = dirs[j][0];
- fish->dir[1] = dirs[j][1];
- }
+ fish->dir[0] = dirs[j][0];
+ fish->dir[1] = dirs[j][1];
}
}
}
-
- fish->pos[0] += fish->dir[0];
- fish->pos[1] += fish->dir[1];
-
- struct cell *cell_entry = pcell( fish->pos );
-
+ }
+
+ fish->pos[0] += fish->dir[0];
+ fish->pos[1] += fish->dir[1];
+
+ struct cell *cell_entry = pcell( fish->pos );
+
+ if( !(cell_entry->state & (FLAG_INPUT|FLAG_CANAL|FLAG_OUTPUT) ))
+ fish->alive = 0;
+ else
if( cell_entry->config == k_cell_type_split )
cell_entry->state |= FLAG_FLIP_ROTATING;
- }
}
world.sim_frame ++;
}
}
+static void render_tiles(void)
+{
+ for( int y = 0; y < world.h; y ++ )
+ {
+ for( int x = 0; x < world.w; x ++ )
+ {
+ struct cell *cell = pcell((v2i){x,y});
+ int selected = world.selected == y*world.w + x;
+
+ int tile_offsets[][2] =
+ {
+ {2, 0}, {0, 3}, {0, 2}, {2, 2},
+ {1, 0}, {2, 3}, {3, 2}, {1, 3},
+ {3, 1}, {0, 1}, {1, 2}, {2, 1},
+ {1, 1}, {3, 3}, {2, 1}, {2, 1}
+ };
+
+ int uv[2] = { 3, 0 };
+
+ if( cell->state & FLAG_CANAL )
+ {
+ uv[0] = tile_offsets[ cell->config ][0];
+ uv[1] = tile_offsets[ cell->config ][1];
+ }
+
+ glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), (float)x, (float)y, uv[0], uv[1] );
+ draw_mesh( 0, 2 );
+ }
+ }
+}
+
void vg_render(void)
{
glViewport( 0,0, vg_window_x, vg_window_y );
float const curve_7_linear_section = 0.1562f;
- // TILE SET RENDERING
+ // TILE SET RENDERING
+ // todo: just slam everything into a mesh...
+ // when user modifies a tile the neighbours can be easily uploaded to gpu mem
+ // in ~3 subBuffers
+ // Currently we're uploading a fair amount of data every frame anyway.
+ // NOTE: this is for final optimisations ONLY!
// ======================================================================
+
use_mesh( &world.tile );
+
SHADER_USE( shader_tile_main );
m2x2f subtransform;
glBindTexture( GL_TEXTURE_2D, tex_wood );
glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexWood" ), 1 );
- for( int y = 0; y < world.h; y ++ )
- {
- for( int x = 0; x < world.w; x ++ )
- {
- struct cell *cell = pcell((v2i){x,y});
- int selected = world.selected == y*world.w + x;
-
- int tile_offsets[][2] =
- {
- {2, 0}, {0, 3}, {0, 2}, {2, 2},
- {1, 0}, {2, 3}, {3, 2}, {1, 3},
- {3, 1}, {0, 1}, {1, 2}, {2, 1},
- {1, 1}, {3, 3}, {2, 1}, {2, 1}
- };
-
- int uv[2] = { 3, 0 };
-
- if( cell->state & FLAG_CANAL )
- {
- uv[0] = tile_offsets[ cell->config ][0];
- uv[1] = tile_offsets[ cell->config ][1];
- }
-
- glUniform4f( SHADER_UNIFORM( shader_tile_main, "uOffset" ), (float)x, (float)y, uv[0], uv[1] );
- draw_mesh( 0, 2 );
- }
- }
-
- // Draw splitters
+ render_tiles();
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
- 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_ball );
glUniformMatrix3fv( SHADER_UNIFORM( shader_ball, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
}
}
+
+ SHADER_USE( shader_tile_main );
+
+ // Bind textures
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, tex_tile_data );
+ glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexGlyphs" ), 0 );
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, tex_wood );
+ glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexWood" ), 1 );
+
+ render_tiles();
+
+ // Draw splitters
+
+ 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);
+
glDisable(GL_BLEND);
SHADER_USE( shader_tile_colour );