From 57a968ab8ebab8b69852c81697bc8cd27f4784ed Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 25 Jul 2021 00:07:27 +0100 Subject: [PATCH] setup instanced rendering for tilemap --- fishladder.c | 151 ++++++++++++++++++++++++++++++++++++++++++------- vg/vg.h | 7 ++- vg/vg_shader.h | 1 + vg/vg_tex.h | 2 +- 4 files changed, 138 insertions(+), 23 deletions(-) diff --git a/fishladder.c b/fishladder.c index ec571af..bb26185 100644 --- a/fishladder.c +++ b/fishladder.c @@ -3,6 +3,9 @@ //#define VG_STEAM #include "vg/vg.h" +#define CELL_SHEET_X 256 +#define CELL_SHEET_Y 256 + SHADER_DEFINE( colour_shader, // VERTEX @@ -28,26 +31,38 @@ SHADER_DEFINE( colour_shader, UNIFORMS({ "uPv", "uMdl", "uColour" }) ) -/* SHADER_DEFINE( tilemap_shader, // VERTEX - "layout (location=0) in vec2 a_co;" + "layout (location=0) in vec2 a_co;" // XY + "layout (location=1) in vec2 a_offset;" // XY offset + "layout (location=2) in vec4 a_data;" // atlas-uv, amt, other "uniform mat4 uPv;" - "uniform vec4 uTextureInfo;" // Cell dx,dy 1.0/mx, 1.0/my - "uniform " + "uniform vec2 uOrigin;" "" - "uniform vec2 uPosition;" - "uniform int uCellIndex;" - "" - "out vec2 s_uv;" + "out vec2 aCoords;" "" "void main()" "{" - " gl_Position = uPv * vec4( uPosition.x + a_co.x, 0.0, uPosition.y + a_co.y, 0.0 );" - " s_uv = vec2( mod( uCellIndex," + "vec2 world_coord = a_co+a_offset+uOrigin;" + "gl_Position = uPv * vec4( world_coord.x, 0.0, world_coord.y, 1.0 );" + "aCoords = (a_co*0.98+0.01 + a_data.xy) * 0.125;" + "}", + + // FRAGMENT + "uniform sampler2D uTexTiles;" + + "in vec2 aCoords;" + "out vec4 FragColor;" + + "void main()" + "{" + "vec4 glyph = texture( uTexTiles, aCoords );" + "FragColor = vec4( glyph.xyz, 1.0 );" "}" -*/ + , + UNIFORMS({ "uPv", "uTexTiles", "uOrigin" }) +) mat4 m_projection; mat4 m_view; @@ -121,6 +136,9 @@ static struct GLuint tile_texture; GLuint flow_texture; + + GLuint tiles_vao; + GLuint tiles_vbo; } map; @@ -214,6 +232,20 @@ static struct cell *map_stack_next(void) return tile; } +static void map_update_visual(void) +{ + u8 celldata[ 4096 ]; + + for( int i = 0; i < map.x*map.y; i ++ ) + { + celldata[i*4+0] = i & 0x7; + celldata[i*4+1] = (i & ~0x7) >> 3; + } + + glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo ); + glBufferSubData( GL_ARRAY_BUFFER, 16*sizeof(float) + 1024*2*sizeof(float), map.x*map.y*4, celldata ); +} + static int map_load( const char *str ) { map_free(); @@ -333,6 +365,22 @@ static int map_load( const char *str ) map.origin[0] = -((float)map.x) * 0.5f; map.origin[2] = -((float)map.y) * 0.5f; + float *offset_array = (float *)malloc( map.x*map.y*2*sizeof(float) ); + + for( int y = 0; y < map.y; y ++ ) + { + for( int x = 0; x < map.x; x ++ ) + { + float *coord = offset_array + (y*map.x+x)*2; + coord[0] = x; + coord[1] = y; + } + } + + glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo ); + glBufferSubData( GL_ARRAY_BUFFER, 16*sizeof(float), map.x*map.y*2*sizeof(float), offset_array ); + + free( offset_array ); vg_success( "Map loaded! (%u:%u)\n", map.x, map.y ); return 1; } @@ -382,11 +430,11 @@ void vg_update(void) // Update camera float ratio = (float)vg_window_y / (float)vg_window_x; float const size = 7.5f; - glm_ortho( -size, size, -size*ratio, size*ratio, 0.1f, 100.f, m_projection ); + glm_ortho( -size, size, -size*ratio, size*ratio, 0.01f, 150.f, m_projection ); glm_mat4_identity( m_view ); glm_translate_z( m_view, -10.f ); - glm_rotate_x( m_view, 1.0f, m_view ); + glm_rotate_x( m_view, 1.5708f, m_view ); glm_mat4_mul( m_projection, m_view, vg_pv ); @@ -633,10 +681,11 @@ void vg_render(void) { glViewport( 0,0, vg_window_x, vg_window_y ); - glEnable( GL_DEPTH_TEST ); + //glEnable( GL_DEPTH_TEST ); glClearColor( 0.94f, 0.94f, 0.94f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + /* glBindVertexArray( tile_vao ); SHADER_USE( colour_shader ); @@ -649,9 +698,9 @@ void vg_render(void) glm_mat4_identity( m_mdl ); glm_translate( m_mdl, (vec3){ - map.origin[0] + (float)x + 0.5f, + map.origin[0] + (float)x, 0.f, - map.origin[2] + (float)y + 0.5f + map.origin[2] + (float)y } ); glUniformMatrix4fv( SHADER_UNIFORM( colour_shader, "uMdl" ), 1, GL_FALSE, (float *)m_mdl ); @@ -705,19 +754,42 @@ void vg_render(void) glDrawArrays( GL_TRIANGLES, 0, 6 ); } } + */ + + glBindVertexArray( map.tiles_vao ); + + map_update_visual(); + + SHADER_USE( tilemap_shader ); + glUniformMatrix4fv( SHADER_UNIFORM( tilemap_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv ); + + glUniform1i( SHADER_UNIFORM( tilemap_shader, "uTexTiles" ), 0 ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, map.tile_texture ); + + glUniform2f( SHADER_UNIFORM( tilemap_shader, "uOrigin" ), map.origin[0], map.origin[2] ); + + glDrawArraysInstanced( GL_TRIANGLES, 0, 6, map.x*map.y ); } -void vg_start(void) +void vg_register(void) { SHADER_INIT( colour_shader ); - + SHADER_INIT( tilemap_shader ); +} + +void vg_start(void) +{ glGenVertexArrays( 1, &tile_vao ); glGenBuffers( 1, &tile_vbo ); float quad_mesh[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, + + // Padding + 0.0f, 0.0f, 0.0f, 0.0f }; glBindVertexArray( tile_vao ); @@ -735,8 +807,41 @@ void vg_start(void) VG_CHECK_GL(); + // Create map buffers + glGenVertexArrays( 1, &map.tiles_vao ); + glGenBuffers( 1, &map.tiles_vbo ); + + glBindVertexArray( map.tiles_vao ); + glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo ); + glBufferData( GL_ARRAY_BUFFER, + sizeof( quad_mesh ) + + sizeof( float )*2 * 1024 + + sizeof( u8 )*4 * 1024, + NULL, + GL_DYNAMIC_DRAW + ); + + glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof( quad_mesh ), quad_mesh ); + + // Base quad + glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 ); + glEnableVertexAttribArray( 0 ); + + // Offset, data arrays (instancing) + glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)(sizeof(quad_mesh)) ); + glEnableVertexAttribArray( 1 ); + glVertexAttribDivisor( 1, 1 ); + + glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4, (void*)(sizeof(quad_mesh)+sizeof(float)*2*1024) ); + glEnableVertexAttribArray( 2 ); + glVertexAttribDivisor( 2, 1 ); + map.tile_texture = vg_tex2d_rgba( "textures/rivertiles_flowm.tga" ); - map.flow_texture = vg_tex2d_rgba( "textures/rivertiles_ripple.tga" ); + vg_tex2d_nearest(); + vg_tex2d_repeat(); + + map.flow_texture = vg_tex2d_rgba( "textures/rivertiles_ripple.tga" ); + map_load ( @@ -754,6 +859,12 @@ void vg_free(void) { map_free(); + glDeleteVertexArrays( 1, &tile_vao ); + glDeleteVertexArrays( 1, &map.tiles_vao ); + + glDeleteBuffers( 1, &tile_vbo ); + glDeleteBuffers( 1, &map.tiles_vbo ); + glDeleteTextures( 1, &map.tile_texture ); glDeleteTextures( 1, &map.flow_texture ); } diff --git a/vg/vg.h b/vg/vg.h index 9e012af..c6b8fb9 100644 --- a/vg/vg.h +++ b/vg/vg.h @@ -255,6 +255,7 @@ void vg_framebuffer_resize_callback( GLFWwindow *ptrW, int w, int h ) vg_window_y = h; } +static void vg_register(void) VG_GAMELOOP; static void vg_start(void) VG_GAMELOOP; static void vg_update(void) VG_GAMELOOP; static void vg_render(void) VG_GAMELOOP; @@ -283,7 +284,7 @@ static void vg_init( int argc, char *argv[], const char *window_name ) glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE ); - glfwWindowHint( GLFW_SAMPLES, 4 ); + glfwWindowHint( GLFW_SAMPLES, 1 ); GLFWmonitor *monitor_primary = glfwGetPrimaryMonitor(); @@ -342,11 +343,13 @@ static void vg_init( int argc, char *argv[], const char *window_name ) vg_lines_init(); vg_register_exit( &vg_lines_free, "vg_lines_free" ); - vg_start(); + vg_register(); vg_register_exit( &vg_free, "vg_free" ); if( vg_shaders_compile() ) { + vg_start(); + // Main gameloop while( !glfwWindowShouldClose( vg_window ) ) { diff --git a/vg/vg_shader.h b/vg/vg_shader.h index ede1b13..8e17da3 100644 --- a/vg/vg_shader.h +++ b/vg/vg_shader.h @@ -19,6 +19,7 @@ static inline int static_str_index( const char *list[], int len, const char *str } #pragma GCC diagnostic pop +#define SHADER_NAME( NAME ) (NAME##_static_shader.program) #define SHADER_USE( NAME ) glUseProgram( NAME##_static_shader.program ) #define SHADER_UNIFORM( NAME, U ) NAME##_shader_uniforms[ STR_STATIC_INDEX( NAME##_shader_names, U ) ] diff --git a/vg/vg_tex.h b/vg/vg_tex.h index 742493b..4ab300c 100644 --- a/vg/vg_tex.h +++ b/vg/vg_tex.h @@ -38,7 +38,7 @@ static inline void vg_tex2d_clamp(void) static GLuint vg_tex2d_rgba( const char *path ) { int x,y,nc; - stbi_set_flip_vertically_on_load( 1 ); + stbi_set_flip_vertically_on_load( 0 ); i64 length; u8 *src_data = vg_asset_read_s( path, &length ); -- 2.25.1