From 5f7656147f3566b32e4eb8c5dffd554e233bdefb Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 24 Oct 2021 20:30:09 +0100 Subject: [PATCH] switch texture loading to resource based --- fishladder.c | 212 ++--------------------------------------- fishladder_resources.h | 178 ++++++++++++++++++++++++++++++++++ vg/vg_platform.h | 3 + vg/vg_tex.h | 57 +++++++++++ 4 files changed, 247 insertions(+), 203 deletions(-) create mode 100644 fishladder_resources.h diff --git a/fishladder.c b/fishladder.c index 60bfb6a..dec99e2 100644 --- a/fishladder.c +++ b/fishladder.c @@ -2,129 +2,7 @@ //#define VG_STEAM #include "vg/vg.h" - -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 vec2 uOffset;" - "uniform mat3 uPv;" - "" - "out vec2 aTexCoords;" - "" - "void main()" - "{" - // Create texture coords - "aTexCoords = a_co;" - - // Vertex transform - "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );" - "gl_Position = vec4( uPv * worldpos, 1.0 );" - "}", - - // FRAGMENT - "out vec4 FragColor;" - "" - "uniform sampler2D uTexMain;" - "uniform vec3 uColour;" - "" - "in vec2 aTexCoords;" - "" - "void main()" - "{" - "vec4 glyph = texture( uTexMain, aTexCoords );" - "FragColor = vec4( uColour + glyph.rgb * 0.2, glyph.a );" - "}" - , - UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv" }) -) - -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;" - "" - "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()" - "{" - // 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 );" - - // 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 );" - "aWorldCoords = worldpos.xy;" - "}", - - // FRAGMENT - "out vec4 FragColor;" - "" - "uniform sampler2D uTexGlyphs;" - "uniform sampler2D uTexWood;" - "uniform float uGhost;" - "uniform vec2 uMousePos;" - "uniform vec4 uColour;" - "" - "in vec4 aTexCoords;" - "in vec2 aWorldCoords;" - "" - "void main()" - "{" - "vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 );" - "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );" - "vec4 wood = texture( uTexWood, aTexCoords.zw );" - "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );" - "vec3 wood_comp = mix( wood_secondary.rgb * shadowing_colour, 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 );" - - "vec4 output_regular = vec4( wood_comp * shadows, glyph.b );" - - "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 );" - - "FragColor = mix( output_regular, output_ghost, uGhost ) * uColour;" - "}" - , - UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", "uColour" }) -) +#include "fishladder_resources.h" const char *level_pack[] = { @@ -184,35 +62,6 @@ const char *level_pack[] = "#############;\n" }; -GLuint tex_tile_data; -GLuint tex_tile_detail; -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/mod_01.ogg\0\ -sound/mod_02.ogg\0\ -sound/mod_03.ogg\0\ -sound/mod_04.ogg\0\ -sound/mod_05.ogg\0\ -sound/mod_06.ogg\0", - .flags = 0 -}; - m3x3f m_projection; m3x3f m_view; m3x3f m_mdl; @@ -498,13 +347,6 @@ int main( int argc, char *argv[] ) vg_init( argc, argv, "Fish (Marbles Computer) Ladder Simulator 2022 | N,M: change level | SPACE: Test | LeftClick: Toggle tile" ); } -void vg_register(void) -{ - SHADER_INIT( shader_tile_colour ); - SHADER_INIT( shader_tile_main ); - SHADER_INIT( shader_ball ); -} - void vg_start(void) { // Quad mesh @@ -554,50 +396,19 @@ void vg_start(void) init_mesh( &world.circle, circle_mesh, vg_list_size( circle_mesh ) ); } - // Textures - { - tex_tile_detail = vg_tex2d_rgba( "textures/tile_overlays.png" ); - vg_tex2d_mipmap(); - vg_tex2d_linear_mipmap(); - vg_tex2d_repeat(); - - tex_tile_data = vg_tex2d_rgba( "textures/tileset.png" ); - vg_tex2d_mipmap(); - vg_tex2d_linear_mipmap(); - vg_tex2d_repeat(); - - tex_wood = vg_tex2d_rgba( "textures/wood.png" ); - vg_tex2d_mipmap(); - vg_tex2d_linear_mipmap(); - vg_tex2d_repeat(); - - 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 ); - } + resource_load_main(); map_load( level_pack[ 0 ] ); } void vg_free(void) { + resource_free_main(); + free_mesh( &world.tile ); free_mesh( &world.circle ); map_free(); - - glDeleteTextures( 1, &tex_tile_data ); - 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 ) @@ -1049,12 +860,10 @@ void vg_render(void) glUniform1f( SHADER_UNIFORM( shader_tile_main, "uGhost" ), 0.0f ); // Bind textures - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, tex_tile_data ); + vg_tex2d_bind( &tex_tile_data, 0 ); glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexGlyphs" ), 0 ); - glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, tex_wood ); + vg_tex2d_bind( &tex_wood, 1 ); glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexWood" ), 1 ); render_tiles( NULL, NULL, colour_default, colour_default ); @@ -1066,8 +875,7 @@ void vg_render(void) SHADER_USE( shader_ball ); glUniformMatrix3fv( SHADER_UNIFORM( shader_ball, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, tex_ball ); + vg_tex2d_bind( &tex_ball, 0 ); glUniform1i( SHADER_UNIFORM( shader_ball, "uTexMain" ), 0 ); // Draw 'fish' @@ -1150,12 +958,10 @@ void vg_render(void) SHADER_USE( shader_tile_main ); // Bind textures - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, tex_tile_data ); + vg_tex2d_bind( &tex_tile_data, 0 ); glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexGlyphs" ), 0 ); - glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, tex_wood ); + vg_tex2d_bind( &tex_wood, 1 ); glUniform1i( SHADER_UNIFORM( shader_tile_main, "uTexWood" ), 1 ); render_tiles( NULL, NULL, colour_default, colour_selected ); diff --git a/fishladder_resources.h b/fishladder_resources.h new file mode 100644 index 0000000..a029421 --- /dev/null +++ b/fishladder_resources.h @@ -0,0 +1,178 @@ +vg_tex2d tex_tile_data = { .path = "textures/tileset.png" }; +vg_tex2d tex_tile_detail = { .path = "textures/tile_overlays.png" }; +vg_tex2d tex_wood = { .path = "textures/wood.png" }; +vg_tex2d tex_ball = { .path = "textures/ball.png", .flags = VG_TEXTURE_CLAMP }; + +vg_tex2d *texture_list[] = { &tex_tile_detail, &tex_tile_data, &tex_wood, &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/mod_01.ogg\0\ +sound/mod_02.ogg\0\ +sound/mod_03.ogg\0\ +sound/mod_04.ogg\0\ +sound/mod_05.ogg\0\ +sound/mod_06.ogg\0", + .flags = 0 +}; + +static void resource_load_main(void) +{ + // Textures + vg_tex2d_init( texture_list, vg_list_size( texture_list ) ); + + // Audio + sfx_set_init( &audio_tile_mod, NULL ); +} + +static void resource_free_main(void) +{ + vg_tex2d_free( texture_list, vg_list_size( texture_list ) ); + sfx_set_free( &audio_tile_mod ); +} + +// 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 vec2 uOffset;" + "uniform mat3 uPv;" + "" + "out vec2 aTexCoords;" + "" + "void main()" + "{" + // Create texture coords + "aTexCoords = a_co;" + + // Vertex transform + "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );" + "gl_Position = vec4( uPv * worldpos, 1.0 );" + "}", + + // FRAGMENT + "out vec4 FragColor;" + "" + "uniform sampler2D uTexMain;" + "uniform vec3 uColour;" + "" + "in vec2 aTexCoords;" + "" + "void main()" + "{" + "vec4 glyph = texture( uTexMain, aTexCoords );" + "FragColor = vec4( uColour + glyph.rgb * 0.2, glyph.a );" + "}" + , + UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv" }) +) + +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;" + "" + "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()" + "{" + // 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 );" + + // 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 );" + "aWorldCoords = worldpos.xy;" + "}", + + // FRAGMENT + "out vec4 FragColor;" + "" + "uniform sampler2D uTexGlyphs;" + "uniform sampler2D uTexWood;" + "uniform float uGhost;" + "uniform vec2 uMousePos;" + "uniform vec4 uColour;" + "" + "in vec4 aTexCoords;" + "in vec2 aWorldCoords;" + "" + "void main()" + "{" + "vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 );" + "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );" + "vec4 wood = texture( uTexWood, aTexCoords.zw );" + "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );" + "vec3 wood_comp = mix( wood_secondary.rgb * shadowing_colour, 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 );" + + "vec4 output_regular = vec4( wood_comp * shadows, glyph.b );" + + "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 );" + + "FragColor = mix( output_regular, output_ghost, uGhost ) * uColour;" + "}" + , + UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", "uColour" }) +) + +void vg_register(void) +{ + SHADER_INIT( shader_tile_colour ); + SHADER_INIT( shader_tile_main ); + SHADER_INIT( shader_ball ); +} diff --git a/vg/vg_platform.h b/vg/vg_platform.h index 2c5e363..2488284 100644 --- a/vg/vg_platform.h +++ b/vg/vg_platform.h @@ -22,6 +22,9 @@ typedef v3f m3x3f[3]; typedef v3f m4x3f[4]; typedef v3f boxf[2]; +// Resource types +typedef struct vg_tex2d vg_tex2d; + #define vg_static_assert _Static_assert #define vg_list_size( A ) (sizeof(A)/sizeof(A[0])) diff --git a/vg/vg_tex.h b/vg/vg_tex.h index 742493b..967337a 100644 --- a/vg/vg_tex.h +++ b/vg/vg_tex.h @@ -1,5 +1,23 @@ // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved +#define VG_TEXTURE_NO_MIP 0x1 +#define VG_TEXTURE_REPEAT 0x2 +#define VG_TEXTURE_CLAMP 0x4 +#define VG_TEXTURE_NEAREST 0x8 + +struct vg_tex2d +{ + const char *path; + u32 flags; + GLuint name; +}; + +static void vg_tex2d_bind( vg_tex2d *tex, u32 id ) +{ + glActiveTexture( GL_TEXTURE0 + id ); + glBindTexture( GL_TEXTURE_2D, tex->name ); +} + static inline void vg_tex2d_mipmap(void) { glGenerateMipmap( GL_TEXTURE_2D ); @@ -71,3 +89,42 @@ static GLuint vg_tex2d_rgba( const char *path ) return texture_name; } + +static void vg_tex2d_init( vg_tex2d *textures[], int num ) +{ + for( int i = 0; i < num; i ++ ) + { + vg_tex2d *tex = textures[i]; + tex->name = vg_tex2d_rgba( tex->path ); + if( !(tex->flags & VG_TEXTURE_NO_MIP) ) + vg_tex2d_mipmap(); + + if( tex->flags & VG_TEXTURE_NEAREST ) + { + if( tex->flags & VG_TEXTURE_NO_MIP ) + vg_error( "Invalid texture settings\n" ); + else + vg_tex2d_nearest(); + } + else + { + if( tex->flags & VG_TEXTURE_NO_MIP ) + vg_tex2d_linear(); + else + vg_tex2d_linear_mipmap(); + } + + if( tex->flags & VG_TEXTURE_CLAMP ) + vg_tex2d_clamp(); + else + vg_tex2d_repeat(); + } +} + +static void vg_tex2d_free( vg_tex2d *textures[], int num ) +{ + for( int i = 0; i < num; i ++ ) + { + glDeleteTextures( 1, &textures[i]->name ); + } +} -- 2.25.1