From 0c3d1d55160d5ce911ead69de84b1d8200a0036f Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 5 Dec 2023 08:37:57 +0000 Subject: [PATCH] refactor world rendering code --- player.c | 1 - world.h | 3 + world_gen.c | 7 +- world_render.c | 259 +++++++++++++++++++++---------------------------- 4 files changed, 121 insertions(+), 149 deletions(-) diff --git a/player.c b/player.c index 07e5f30..74d56f3 100644 --- a/player.c +++ b/player.c @@ -35,7 +35,6 @@ static int localplayer_cmd_respawn( int argc, const char *argv[] ){ static void player_init(void){ for( u32 i=0; isystem_register ) sys->system_register(); } diff --git a/world.h b/world.h index 9d8cd49..642e757 100644 --- a/world.h +++ b/world.h @@ -58,6 +58,8 @@ static i32 k_debug_light_indices = 0, k_debug_light_complexity= 0, k_light_preview = 0; +#define WORLD_SURFACE_HAS_TRAFFIC 0x1 +#define WORLD_SURFACE_HAS_PROPS 0x2 struct world_instance { /* Fixed items @@ -155,6 +157,7 @@ struct world_instance { mdl_material info; mdl_submesh sm_geo, sm_no_collide; + u32 flags; } * surfaces; u32 surface_count; diff --git a/world_gen.c b/world_gen.c index b94c689..543be6d 100644 --- a/world_gen.c +++ b/world_gen.c @@ -272,6 +272,7 @@ static void world_gen_generate_meshes( world_instance *world ){ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, vehc->submesh_start+j ); world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_TRAFFIC; } } @@ -317,6 +318,7 @@ static void world_gen_generate_meshes( world_instance *world ){ for( u32 j=0; jsubmesh_count; j ++ ){ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, prop->submesh_start+j ); + world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_PROPS; world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); } } @@ -713,8 +715,9 @@ static void world_gen_load_surfaces( world_instance *world ){ memset( errmat, 0, sizeof(struct world_surface) ); for( u32 i=0; imeta.materials); i++ ){ - world->surfaces[i+1].info = - *(mdl_material *)mdl_arritm( &world->meta.materials, i ); + struct world_surface *surf = &world->surfaces[i+1]; + surf->info = *(mdl_material *)mdl_arritm( &world->meta.materials, i ); + surf->flags = 0; } } diff --git a/world_render.c b/world_render.c index 3381485..4ba8a4f 100644 --- a/world_render.c +++ b/world_render.c @@ -23,8 +23,7 @@ static int ccmd_set_time( int argc, const char *argv[] ){ return 0; } -static void async_world_render_init( void *payload, u32 size ) -{ +static void async_world_render_init( void *payload, u32 size ){ vg_info( "Allocate uniform buffers\n" ); for( int i=0; iubo_bind_point ); @@ -135,17 +137,31 @@ static void world_bind_light_index( world_instance *world, glUniform1i( location, slot ); } -static void render_world_depth( world_instance *world, camera *cam ); - -/* - * Rendering - */ - static void bind_terrain_noise(void){ glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise ); } +/* + * Get OpenGL texture name from texture ID. + */ +static GLuint world_get_texture( world_instance *world, u32 id ){ + if( id & 0x80000000 ) return skaterift.rt_textures[id & ~0x80000000]; + else return world->textures[ id ]; +} + +static void bindpoint_diffuse_texture1( world_instance *world, + struct world_surface *mat ){ + glActiveTexture( GL_TEXTURE1 ); + glBindTexture( GL_TEXTURE_2D, + world_get_texture(world,mat->info.tex_diffuse) ); +} + +/* + * Passes Rendering + * ---------------------------------------------------------------------------- + */ + struct world_pass{ camera *cam; enum mdl_shader shader; @@ -158,82 +174,76 @@ struct world_pass{ void (*fn_set_uNormalMtx)( m3x3f mnorm ); }; -/* FIXME: we gotta do something about this crap, maybe batch lists. something.. - * anything but this. */ -static -void world_render_props( world_instance *world, u32 material_id, - struct world_pass *pass ){ - if( !mdl_arrcount( &world->ent_prop ) ) return; +static void render_world_depth( world_instance *world, camera *cam ); + +/* + * Render a run of submeshes, only of those which match material_id + */ +static void world_render_submeshes( world_instance *world, + struct world_pass *pass, + mdl_transform *transform, + u32 start, u32 count, u32 material_id ){ + for( u32 k=0; kmeta.submeshs, start+k ); + if( sm->material_id != material_id ) continue; + + m4x3f mmdl; + mdl_transform_m4x3( transform, mmdl ); + m4x4f m4mdl; + m4x3_expand( mmdl, m4mdl ); + m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl ); + + pass->fn_set_mdl( mmdl ); + pass->fn_set_uPvmPrev( m4mdl ); + + mdl_draw_submesh( sm ); + } +} +/* + * Render props attached to this material + */ +static void world_render_props( world_instance *world, u32 material_id, + struct world_pass *pass ){ struct world_surface *mat = &world->surfaces[ material_id ]; + if( !(mat->flags & WORLD_SURFACE_HAS_PROPS) ) return; + pass->fn_bind_textures( world, mat ); for( u32 j=0; jent_prop ); j++ ){ ent_prop *prop = mdl_arritm( &world->ent_prop, j ); if( prop->flags & 0x1 ) continue; - - for( u32 k=0; ksubmesh_count; k++ ){ - mdl_submesh *sm = - mdl_arritm( &world->meta.submeshs, prop->submesh_start+k ); - - if( sm->material_id != material_id ) continue; - - m4x3f mmdl; - mdl_transform_m4x3( &prop->transform, mmdl ); - - m4x4f m4mdl; - m4x3_expand( mmdl, m4mdl ); - m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl ); - - pass->fn_set_mdl( mmdl ); - pass->fn_set_uPvmPrev( m4mdl ); - mdl_draw_submesh( sm ); - } + world_render_submeshes( world, pass, &prop->transform, + prop->submesh_start, prop->submesh_count, material_id ); } } -static -void world_render_traffic( world_instance *world, u32 material_id, - struct world_pass *pass ){ - if( !mdl_arrcount( &world->ent_traffic ) ) return; - - /* HACK: use the first material for every traffic entity */ - ent_traffic *first = mdl_arritm( &world->ent_traffic, 0 ); - if( !first->submesh_count ) return; - - mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, first->submesh_start ); - if( sm->material_id != material_id ) return; - +/* + * Render traffic models attactched to this material + */ +static void world_render_traffic( world_instance *world, u32 material_id, + struct world_pass *pass ){ struct world_surface *mat = &world->surfaces[ material_id ]; + if( !(mat->flags & WORLD_SURFACE_HAS_TRAFFIC) ) return; + pass->fn_bind_textures( world, mat ); for( u32 j=0; jent_traffic ); j++ ){ ent_traffic *traffic = mdl_arritm( &world->ent_traffic, j ); - - for( u32 k=0; ksubmesh_count; k++ ){ - sm = mdl_arritm( &world->meta.submeshs, - traffic->submesh_start+k ); - - m4x3f mmdl; - q_m3x3( traffic->transform.q, mmdl ); - v3_copy( traffic->transform.co, mmdl[3] ); - - m4x4f m4mdl; - m4x3_expand( mmdl, m4mdl ); - m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl ); - pass->fn_set_mdl( mmdl ); - pass->fn_set_uPvmPrev( m4mdl ); - - mdl_draw_submesh( sm ); - } + world_render_submeshes( world, pass, &traffic->transform, + traffic->submesh_start, traffic->submesh_count, + material_id ); } } -static -void world_render_pass( world_instance *world, struct world_pass *pass ){ +/* + * Iterate and render all materials which match the passes shader and geometry + * type. Includes props/traffic. + */ +static void world_render_pass( world_instance *world, struct world_pass *pass ){ for( int i=0; isurface_count; i++ ){ struct world_surface *mat = &world->surfaces[i]; @@ -263,9 +273,13 @@ void world_render_pass( world_instance *world, struct world_pass *pass ){ } } -static -void world_render_both_stages( world_instance *world, struct world_pass *pass ) -{ +/* + * Specific shader instructions + * ---------------------------------------------------------------------------- + */ + +static void world_render_both_stages( world_instance *world, + struct world_pass *pass ){ mesh_bind( &world->mesh_geo ); pass->geo_type = k_world_geo_type_solid; world_render_pass( world, pass ); @@ -277,51 +291,11 @@ void world_render_both_stages( world_instance *world, struct world_pass *pass ) glEnable( GL_CULL_FACE ); } -static GLuint world_get_texture( world_instance *world, u32 id ){ - if( id & 0x80000000 ) - return skaterift.rt_textures[id & ~0x80000000]; - else - return world->textures[ id ]; -} - -static void bindpoint_diffuse_texture1( world_instance *world, - struct world_surface *mat ){ - glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, - world_get_texture(world,mat->info.tex_diffuse) ); -} - -static void bindpoint_diffuse1_and_cubemap10( world_instance *world, - struct world_surface *mat ){ - glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, - world_get_texture(world,mat->info.tex_diffuse) ); - - u32 cubemap_id = mat->info.tex_none0, - cubemap_index = 0; - - if( mdl_entity_id_type( cubemap_id ) == k_ent_cubemap ){ - cubemap_index = mdl_entity_id_id( cubemap_id ); - } - - ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, cubemap_index ); - glActiveTexture( GL_TEXTURE10 ); - glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id ); - - shader_scene_cubemapped_uColour( mat->info.colour ); -} - static void render_world_vb( world_instance *world, camera *cam ){ shader_scene_vertex_blend_use(); shader_scene_vertex_blend_uTexGarbage(0); shader_scene_vertex_blend_uTexGradients(1); - world_link_lighting_ub( world, _shader_scene_vertex_blend.id ); - world_bind_position_texture( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_vertex_blend.id, - _uniform_scene_vertex_blend_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_vertex_blend ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise ); @@ -345,14 +319,7 @@ static void world_shader_standard_bind( world_instance *world, camera *cam ){ shader_scene_standard_uTexGarbage(0); shader_scene_standard_uTexMain(1); shader_scene_standard_uPv( cam->mtx.pv ); - - world_link_lighting_ub( world, _shader_scene_standard.id ); - world_bind_position_texture( world, _shader_scene_standard.id, - _uniform_scene_standard_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_standard.id, - _uniform_scene_standard_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_standard.id, - _uniform_scene_standard_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_standard ); bind_terrain_noise(); shader_scene_standard_uCamera( cam->transform[3] ); @@ -371,6 +338,26 @@ static void render_world_standard( world_instance *world, camera *cam ){ world_render_both_stages( world, &pass ); } +static void bindpoint_diffuse1_and_cubemap10( world_instance *world, + struct world_surface *mat ){ + glActiveTexture( GL_TEXTURE1 ); + glBindTexture( GL_TEXTURE_2D, + world_get_texture(world,mat->info.tex_diffuse) ); + + u32 cubemap_id = mat->info.tex_none0, + cubemap_index = 0; + + if( mdl_entity_id_type( cubemap_id ) == k_ent_cubemap ){ + cubemap_index = mdl_entity_id_id( cubemap_id ); + } + + ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, cubemap_index ); + glActiveTexture( GL_TEXTURE10 ); + glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id ); + + shader_scene_cubemapped_uColour( mat->info.colour ); +} + static void render_world_cubemapped( world_instance *world, camera *cam, int enabled ){ if( !mdl_arrcount( &world->ent_cubemap ) ) @@ -396,13 +383,7 @@ static void render_world_cubemapped( world_instance *world, camera *cam, shader_scene_cubemapped_uTexCubemap(10); shader_scene_cubemapped_uPv( cam->mtx.pv ); - world_link_lighting_ub( world, _shader_scene_cubemapped.id ); - world_bind_position_texture( world, _shader_scene_cubemapped.id, - _uniform_scene_cubemapped_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_cubemapped.id, - _uniform_scene_cubemapped_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_cubemapped.id, - _uniform_scene_cubemapped_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_cubemapped ); bind_terrain_noise(); shader_scene_cubemapped_uCamera( cam->transform[3] ); @@ -425,20 +406,10 @@ static void render_world_alphatest( world_instance *world, camera *cam ){ shader_scene_standard_alphatest_uTexMain(1); shader_scene_standard_alphatest_uPv( cam->mtx.pv ); - world_link_lighting_ub( world, _shader_scene_standard_alphatest.id ); - world_bind_position_texture( world, _shader_scene_standard_alphatest.id, - _uniform_scene_standard_alphatest_g_world_depth, 2 ); - world_bind_light_array( world, _shader_scene_standard_alphatest.id, - _uniform_scene_standard_alphatest_uLightsArray, 3 ); - world_bind_light_index( world, _shader_scene_standard_alphatest.id, - _uniform_scene_standard_alphatest_uLightsIndex, 4 ); - + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_standard_alphatest ); bind_terrain_noise(); - - shader_scene_standard_alphatest_uCamera( cam->transform[3] ); - glDisable(GL_CULL_FACE); struct world_pass pass = { @@ -450,7 +421,6 @@ static void render_world_alphatest( world_instance *world, camera *cam ){ }; world_render_both_stages( world, &pass ); - glEnable(GL_CULL_FACE); } @@ -646,14 +616,7 @@ static void render_world_fxglow( world_instance *host_world, shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } ); shader_scene_fxglow_uTexMain(1); shader_scene_fxglow_uPv( cam->mtx.pv ); - - world_link_lighting_ub( host_world, _shader_scene_fxglow.id ); - world_bind_position_texture( host_world, _shader_scene_fxglow.id, - _uniform_scene_fxglow_g_world_depth, 2 ); - world_bind_light_array( host_world, _shader_scene_fxglow.id, - _uniform_scene_fxglow_uLightsArray, 3 ); - world_bind_light_index( host_world, _shader_scene_fxglow.id, - _uniform_scene_fxglow_uLightsIndex, 4 ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_fxglow ); shader_scene_fxglow_uCamera( cam->transform[3] ); glDisable(GL_CULL_FACE); @@ -1027,10 +990,9 @@ static void render_world( world_instance *world, camera *cam, static void render_world_override_pass( world_instance *world, struct world_pass *pass, m4x3f mmdl, m3x3f mnormal, - m4x4f mpvm_prev ){ + m4x4f mpvm_prev ){ for( int i=0; isurface_count; i++ ){ struct world_surface *mat = &world->surfaces[i]; - if( mat->info.flags & k_material_flag_ghosts ) continue; mdl_submesh *sm; @@ -1182,6 +1144,11 @@ static void render_world_cubemaps( world_instance *world ){ } } +/* + * Geo shaders + * --------------------------------------------- + */ + static void render_world_depth( world_instance *world, camera *cam ){ m4x3f identity_matrix; m4x3_identity( identity_matrix ); -- 2.25.1