From: hgn Date: Sat, 22 Apr 2023 14:53:39 +0000 (+0100) Subject: traffic X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=sidebyside;h=89113e9bc9544336b5ac4f53696c3de2d30698a2;p=carveJwlIkooP6JGAAIwe30JlM.git traffic --- diff --git a/blender_export.py b/blender_export.py index a7698e9..6211204 100644 --- a/blender_export.py +++ b/blender_export.py @@ -68,7 +68,8 @@ class mdl_submesh(Structure): ("vertex_start",c_uint32), ("vertex_count",c_uint32), ("bbx",(c_float*3)*2), - ("material_id",c_uint32)] # index into the material array + ("material_id",c_uint16), # index into the material array + ("flags",c_uint16)] #} class mdl_material(Structure): @@ -329,6 +330,18 @@ class ent_font(Structure): ("glyph_utf32_base",c_uint32)] #} +class ent_traffic(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("submesh_start",c_uint32), + ("submesh_count",c_uint32), + ("start_node",c_uint32), + ("node_count",c_uint32), + ("speed",c_float), + ("t",c_float), + ("index",c_uint32)] +#} + def obj_ent_type( obj ): #{ if obj.type == 'ARMATURE': return 'mdl_armature' @@ -664,25 +677,16 @@ def sr_armature_bones( armature ): yield from _recurse_bone( b ) #} -def sr_compile_mesh( obj ): +# Returns submesh_start,count and armature_id +def sr_compile_mesh_internal( obj ): #{ - node=mdl_mesh() - compile_obj_transform(obj, node.transform) - node.pstr_name = sr_compile_string(obj.name) - ent_type = obj_ent_type( obj ) - - node.entity_id = 0 - - if ent_type != 'none':#{ - ent_id_lwr = sr_compile.entity_ids[obj.name] - ent_id_upr = get_entity_enum_id( obj_ent_type(obj) ) - node.entity_id = (ent_id_upr << 16) | ent_id_lwr - #} - print( node.entity_id ) - can_use_cache = True armature = None + submesh_start = 0 + submesh_count = 0 + armature_id = 0 + for mod in obj.modifiers:#{ if mod.type == 'DATA_TRANSFER' or mod.type == 'SHRINKWRAP' or \ mod.type == 'BOOLEAN' or mod.type == 'CURVE' or \ @@ -695,7 +699,7 @@ def sr_compile_mesh( obj ): armature = mod.object rig_weight_groups = \ ['0 [ROOT]']+[_.name for _ in sr_armature_bones(mod.object)] - node.armature_id = sr_compile.entity_ids[armature.name] + armature_id = sr_compile.entity_ids[armature.name] POSE_OR_REST_CACHE = armature.data.pose_position armature.data.pose_position = 'REST' @@ -706,16 +710,15 @@ def sr_compile_mesh( obj ): # if can_use_cache and (obj.data.name in sr_compile.mesh_cache):#{ ref = sr_compile.mesh_cache[obj.data.name] - node.submesh_start = ref[0] - node.submesh_count = ref[1] - sr_compile.mesh_data.extend(bytearray(node)) - return + submesh_start = ref[0] + submesh_count = ref[1] + return (submesh_start,submesh_count,armature_id) #} # Compile a whole new mesh # - node.submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh) - node.submesh_count = 0 + submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh) + submesh_count = 0 dgraph = bpy.context.evaluated_depsgraph_get() data = obj.evaluated_get(dgraph).data @@ -899,16 +902,37 @@ def sr_compile_mesh( obj ): # Add submesh to encoder # sr_compile.submesh_data.extend( bytearray(sm) ) - node.submesh_count += 1 + submesh_count += 1 #} if armature:#{ armature.data.pose_position = POSE_OR_REST_CACHE #} - # Save a reference to this node since we want to reuse the submesh indices + # Save a reference to this mesh since we want to reuse the submesh indices # later. - sr_compile.mesh_cache[obj.data.name]=(node.submesh_start,node.submesh_count) + sr_compile.mesh_cache[obj.data.name]=(submesh_start,submesh_count) + return (submesh_start,submesh_count,armature_id) +#} + +def sr_compile_mesh( obj ): +#{ + node=mdl_mesh() + compile_obj_transform(obj, node.transform) + node.pstr_name = sr_compile_string(obj.name) + ent_type = obj_ent_type( obj ) + + node.entity_id = 0 + + if ent_type != 'none':#{ + ent_id_lwr = sr_compile.entity_ids[obj.name] + ent_id_upr = get_entity_enum_id( obj_ent_type(obj) ) + node.entity_id = (ent_id_upr << 16) | ent_id_lwr + #} + + node.submesh_start, node.submesh_count, node.armature_id = \ + sr_compile_mesh_internal( obj ) + sr_compile.mesh_data.extend(bytearray(node)) #} @@ -1274,7 +1298,9 @@ def sr_compile( collection ): mesh_count = 0 for obj in collection.all_objects: #{ - if obj.type == 'MESH': mesh_count += 1 + if obj.type == 'MESH':#{ + mesh_count += 1 + #} ent_type = obj_ent_type( obj ) if ent_type == 'none': continue @@ -1289,6 +1315,14 @@ def sr_compile( collection ): for obj in collection.all_objects:#{ if obj.type == 'MESH':#{ i+=1 + + ent_type = obj_ent_type( obj ) + + # entity ignore mesh list + # + if ent_type == 'ent_traffic': continue + #-------------------------- + print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' ) sr_compile_mesh( obj ) #} @@ -1468,6 +1502,7 @@ def sr_compile( collection ): route_gates = [] route_curves = [] routes = [] + traffics = [] for obj in col.objects:#{ if obj.type == 'ARMATURE': pass @@ -1483,6 +1518,8 @@ def sr_compile( collection ): #} elif ent_type == 'ent_route': routes += [obj] + elif ent_type == 'ent_traffic': + traffics += [obj] #} #} @@ -1541,6 +1578,52 @@ def sr_compile( collection ): sr_ent_push( route ) #} + for obj in traffics:#{ + traffic = ent_traffic() + compile_obj_transform( obj, traffic.transform ) + traffic.submesh_start, traffic.submesh_count, _ = \ + sr_compile_mesh_internal( obj ) + + # find best subsection + + graph_keys = list(dij.graph) + min_dist = 100.0 + best_point = 0 + + for j in range(len(dij.points)):#{ + point = dij.points[j] + dist = (point-obj.location).magnitude + + if dist < min_dist:#{ + min_dist = dist + best_point = j + #} + #} + + # scan to each edge + best_begin = best_point + best_end = best_point + + while True:#{ + map0 = dij.subsections[best_begin] + if map0[1] == -1: break + best_begin = map0[1] + #} + while True:#{ + map1 = dij.subsections[best_end] + if map1[2] == -1: break + best_end = map1[2] + #} + + traffic.start_node = routenode_count + best_begin + traffic.node_count = best_end - best_begin + traffic.index = best_point - best_begin + traffic.speed = obj.SR_data.ent_traffic[0].speed + traffic.t = 0.0 + + sr_ent_push(traffic) + #} + for point in dij.points:#{ rn = ent_route_node() rn.co[0] = point[0] @@ -1552,7 +1635,6 @@ def sr_compile( collection ): routenode_count += len(dij.points) #} - print( F"[SR] Writing file" ) file_array_instructions = {} @@ -1595,7 +1677,7 @@ def sr_compile( collection ): fp = open( path, "wb" ) header = mdl_header() - header.version = 40 + header.version = 100 sr_array_title( header.arrays, \ 'index', len(file_array_instructions), \ sizeof(mdl_array), header_size ) @@ -2492,9 +2574,7 @@ class SR_OBJECT_ENT_FONT(bpy.types.PropertyGroup): class SR_OBJECT_ENT_TRAFFIC(bpy.types.PropertyGroup): #{ - track: bpy.props.PointerProperty(\ - type=bpy.types.Object, name='track', \ - poll=lambda self,obj: sr_filter_ent_type(obj,['ent_route_node'])) + speed: bpy.props.FloatProperty(default=1.0) #} class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): diff --git a/entity.h b/entity.h index 25fd63f..7d6fabf 100644 --- a/entity.h +++ b/entity.h @@ -18,6 +18,7 @@ typedef struct ent_volume ent_volume; typedef struct ent_audio ent_audio; typedef struct ent_index ent_index; typedef struct ent_marker ent_marker; +typedef struct ent_traffic ent_traffic; typedef struct ent_font ent_font; typedef struct ent_font_variant ent_font_variant; typedef struct ent_glyph ent_glyph; @@ -208,6 +209,17 @@ struct ent_marker{ u32 pstr_alias; }; +struct ent_traffic{ + mdl_transform transform; + u32 submesh_start, + submesh_count, + start_node, + node_count; + float speed, + t; + u32 index; /* into the path */ +}; + VG_STATIC ent_marker *ent_find_marker( mdl_context *mdl, mdl_array_ptr *arr, const char *alias ) { diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index ffe3816..557de7d 100644 Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ diff --git a/maps_src/mp_mtzero.mdl b/maps_src/mp_mtzero.mdl index 9eb41d7..f5de1f7 100644 Binary files a/maps_src/mp_mtzero.mdl and b/maps_src/mp_mtzero.mdl differ diff --git a/maps_src/mp_spawn.mdl b/maps_src/mp_spawn.mdl index 8df5081..eb65fa9 100644 Binary files a/maps_src/mp_spawn.mdl and b/maps_src/mp_spawn.mdl differ diff --git a/model.h b/model.h index fffd26d..8124198 100644 --- a/model.h +++ b/model.h @@ -7,6 +7,8 @@ #include "common.h" +#define MDL_VERSION_NR 100 + enum mdl_shader { k_shader_standard = 0, @@ -29,12 +31,12 @@ enum mdl_surface_prop enum material_flag { - k_material_flag_skate_target = 0x1, - k_material_flag_collision = 0x2, - k_material_flag_grow_grass = 0x4, - k_material_flag_grindable = 0x8, - k_material_flag_invisible = 0x10, - k_material_flag_boundary = 0x20 + k_material_flag_skate_target = 0x00000001, + k_material_flag_collision = 0x00000002, + k_material_flag_grow_grass = 0x00000004, + k_material_flag_grindable = 0x00000008, + k_material_flag_invisible = 0x00000010, + k_material_flag_boundary = 0x00000020 }; #pragma pack(push,1) @@ -75,17 +77,6 @@ struct mdl_transform v4f q; }; -struct mdl_submesh -{ - u32 indice_start, - indice_count, - vertex_start, - vertex_count; - - boxf bbx; - u32 material_id; -}; - struct mdl_material { u32 pstr_name, @@ -118,9 +109,9 @@ struct mdl_bone enum bone_flag { - k_bone_flag_deform = 0x1, - k_bone_flag_ik = 0x2, - k_bone_flag_cone_constraint = 0x4 + k_bone_flag_deform = 0x00000001, + k_bone_flag_ik = 0x00000002, + k_bone_flag_cone_constraint = 0x00000004 }; enum bone_collider @@ -147,6 +138,23 @@ struct mdl_animation u32 offset; }; +struct mdl_submesh +{ + u32 indice_start, + indice_count, + vertex_start, + vertex_count; + + boxf bbx; + u16 material_id, flags; +}; + +enum esubmesh_flags +{ + k_submesh_flag_none = 0x0000, + k_submesh_flag_consumed = 0x0001 +}; + struct mdl_mesh { mdl_transform transform; @@ -366,6 +374,14 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc ) if( l != 1 ) mdl_load_fatal_corrupt( mdl ); + if( mdl->info.version != MDL_VERSION_NR ){ + vg_warn( "For model: %s\n", path ); + vg_warn( " version: %u (current: %u)\n", mdl->info.version, + MDL_VERSION_NR ); + + vg_fatal_exit_loop( "Legacy model version incompatable" ); + } + mdl_load_array_file( mdl, &mdl->index, &mdl->info.index, lin_alloc ); mdl_array *pack = mdl_find_array( mdl, "pack" ); diff --git a/models_src/board_fish.mdl b/models_src/board_fish.mdl index b72141d..33af54e 100644 Binary files a/models_src/board_fish.mdl and b/models_src/board_fish.mdl differ diff --git a/models_src/ch_jordan.mdl b/models_src/ch_jordan.mdl index 00fbf4c..c42eba6 100644 Binary files a/models_src/ch_jordan.mdl and b/models_src/ch_jordan.mdl differ diff --git a/models_src/ch_new.mdl b/models_src/ch_new.mdl index 042c4e3..85845bb 100644 Binary files a/models_src/ch_new.mdl and b/models_src/ch_new.mdl differ diff --git a/models_src/ch_outlaw.mdl b/models_src/ch_outlaw.mdl index a761b0a..211e447 100644 Binary files a/models_src/ch_outlaw.mdl and b/models_src/ch_outlaw.mdl differ diff --git a/models_src/rs_font.mdl b/models_src/rs_font.mdl index 1c84117..cd55971 100644 Binary files a/models_src/rs_font.mdl and b/models_src/rs_font.mdl differ diff --git a/models_src/rs_gate.mdl b/models_src/rs_gate.mdl index 2f0e62b..fda4b5e 100644 Binary files a/models_src/rs_gate.mdl and b/models_src/rs_gate.mdl differ diff --git a/models_src/rs_menu.mdl b/models_src/rs_menu.mdl index 18c6db3..9c49da5 100644 Binary files a/models_src/rs_menu.mdl and b/models_src/rs_menu.mdl differ diff --git a/models_src/rs_scoretext.mdl b/models_src/rs_scoretext.mdl index a85faa6..bf85fc4 100644 Binary files a/models_src/rs_scoretext.mdl and b/models_src/rs_scoretext.mdl differ diff --git a/models_src/rs_skydome.mdl b/models_src/rs_skydome.mdl index 894246f..beb78ea 100644 Binary files a/models_src/rs_skydome.mdl and b/models_src/rs_skydome.mdl differ diff --git a/world.h b/world.h index 8093971..5318f8e 100644 --- a/world.h +++ b/world.h @@ -164,7 +164,8 @@ struct world_instance { ent_audio_clip, ent_audio, - ent_volume; + ent_volume, + ent_traffic; ent_gate *rendering_gate; @@ -547,6 +548,67 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) world_routes_update_timer_texts( world ); world_routes_update( world ); //world_routes_debug( world ); + + /* ---- traffic -------- */ + + for( u32 i=0; ient_traffic ); i++ ){ + ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i ); + + u32 i1 = traffic->index, + i0, + i2 = i1+1; + + if( i1 == 0 ) i0 = traffic->node_count-1; + else i0 = i1-1; + + if( i2 >= traffic->node_count ) i2 = 0; + + i0 += traffic->start_node; + i1 += traffic->start_node; + i2 += traffic->start_node; + + v3f h[3]; + + ent_route_node *rn0 = mdl_arritm( &world->ent_route_node, i0 ), + *rn1 = mdl_arritm( &world->ent_route_node, i1 ), + *rn2 = mdl_arritm( &world->ent_route_node, i2 ); + + v3_copy( rn1->co, h[1] ); + v3_lerp( rn0->co, rn1->co, 0.5f, h[0] ); + v3_lerp( rn1->co, rn2->co, 0.5f, h[2] ); + + float const k_sample_dist = 0.0025f; + v3f pc, pd; + eval_bezier3( h[0], h[1], h[2], traffic->t, pc ); + eval_bezier3( h[0], h[1], h[2], traffic->t+k_sample_dist, pd ); + + v3f v0; + v3_sub( pd, pc, v0 ); + float length = vg_maxf( 0.0001f, v3_length( v0 ) ); + v3_muls( v0, 1.0f/length, v0 ); + + float mod = k_sample_dist / length; + + traffic->t += traffic->speed * vg.time_delta * mod; + + if( traffic->t > 1.0f ){ + traffic->t -= 1.0f; + + if( traffic->t > 1.0f ) traffic->t = 0.0f; + + traffic->index ++; + + if( traffic->index >= traffic->node_count ) + traffic->index = 0; + } + + v3_copy( pc, traffic->transform.co ); + + float a = atan2f( -v0[0], v0[2] ); + q_axis_angle( traffic->transform.q, (v3f){0.0f,1.0f,0.0f}, -a ); + + vg_line_pt3( traffic->transform.co, 0.3f, VG__BLUE ); + } /* ---- SFD ------------ */ diff --git a/world_gen.h b/world_gen.h index 3f57498..e8e9293 100644 --- a/world_gen.h +++ b/world_gen.h @@ -196,6 +196,43 @@ VG_STATIC void world_generate( world_instance *world ) scene_copy_slice( world->scene_no_collide, &mat->sm_no_collide ); } + /* this FIXME TODO IMPORTANT is going here because need to write down. + * + * acuire_thread_sync; replace this with a buffer that you fill up with + * opengl loader commands in a seperate memory area. the operation blocks + * if the buffer is full, then those instructions get ran on the sync line. + * (start of the frame) + * + * also blocks if the other thread is executing the instructions, obviously. + * + * this prevents rapid context swaps between threads. + * + * guessing a 50mb loader buffer approx. + * + * TODO also: fadeout loading screen! + */ + + for( u32 i=0; ient_traffic ); i++ ){ + ent_traffic *vehc = mdl_arritm( &world->ent_traffic, i ); + + for( u32 j=0; jsubmesh_count; j++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + vehc->submesh_start+j ); + + if( sm->flags & k_submesh_flag_consumed ){ + continue; + } + + m4x3f identity; + m4x3_identity( identity ); + scene_add_mdl_submesh( world->scene_no_collide, &world->meta, + sm, identity ); + + scene_copy_slice( world->scene_no_collide, sm ); + sm->flags |= k_submesh_flag_consumed; + } + } + /* upload and free that */ vg_acquire_thread_sync(); { @@ -530,6 +567,13 @@ VG_STATIC void world_process_resources( world_instance *world ) world->textures = vg_linear_alloc( world->heap, vg_align8(sizeof(GLuint)*world->texture_count) ); + /* TODO FIXME IMPORTANT + * + * this is another area that would benefit from our load thread buffer idea. + * could get a stall if lots of textures, since its freading, we're locking + * the frame up from drawing based on that disk read!!! terrible! + */ + vg_acquire_thread_sync(); { /* error texture */ @@ -813,6 +857,7 @@ VG_STATIC void world_load( u32 index, const char *path ) mdl_load_array( meta, &world->ent_audio_clip,"ent_audio_clip", heap ); mdl_load_array( meta, &world->ent_audio, "ent_audio", heap ); mdl_load_array( meta, &world->ent_volume, "ent_volume", heap ); + mdl_load_array( meta, &world->ent_traffic, "ent_traffic", heap ); /* process resources from pack */ world_process_resources( world ); diff --git a/world_render.h b/world_render.h index b1972ba..f61974e 100644 --- a/world_render.h +++ b/world_render.h @@ -109,24 +109,26 @@ VG_STATIC void bind_terrain_noise(void) vg_tex2d_bind( &tex_terrain_noise, 0 ); } -typedef void (*func_bind_point)( world_instance *world, - struct world_surface *mat ); - -VG_STATIC void world_render_if( world_instance *world, - enum mdl_shader shader, - enum geo_type geo_type, - func_bind_point bind_point ) +struct world_pass{ + camera *cam; + enum mdl_shader shader; + enum geo_type geo_type; + + void (*fn_bind_textures)( world_instance *world, + struct world_surface *mat ); + void (*fn_set_mdl)( m4x3f mdl ); + void (*fn_set_uPvmPrev)( m4x4f pvm ); +}; + +VG_STATIC void world_render_if( world_instance *world, struct world_pass *pass ) { - - for( int i=0; isurface_count; i++ ) - { + for( int i=0; isurface_count; i++ ){ struct world_surface *mat = &world->surfaces[i]; - if( mat->info.shader == shader ) - { + if( mat->info.shader == pass->shader ){ mdl_submesh *sm; - if( geo_type == k_geo_type_solid ) + if( pass->geo_type == k_geo_type_solid ) sm = &mat->sm_geo; else sm = &mat->sm_no_collide; @@ -134,28 +136,55 @@ VG_STATIC void world_render_if( world_instance *world, if( !sm->indice_count ) continue; - bind_point( world, mat ); + m4x3f mmdl; + m4x3_identity( mmdl ); + pass->fn_set_mdl( mmdl ); + pass->fn_set_uPvmPrev( pass->cam->mtx_prev.pv ); + + pass->fn_bind_textures( world, mat ); mdl_draw_submesh( sm ); + + 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 ); + + 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 ); + } + } } } } VG_STATIC -void world_render_both_stages( world_instance *world, - enum mdl_shader shader, - func_bind_point bind_point ) +void world_render_both_stages( world_instance *world, struct world_pass *pass ) { mesh_bind( &world->mesh_geo ); - world_render_if( world, shader, k_geo_type_solid, bind_point ); + pass->geo_type = k_geo_type_solid; + world_render_if( world, pass ); glDisable( GL_CULL_FACE ); mesh_bind( &world->mesh_no_collide ); - world_render_if( world, shader, k_geo_type_nonsolid, bind_point ); + pass->geo_type = k_geo_type_nonsolid; + world_render_if( world, pass ); glEnable( GL_CULL_FACE ); } VG_STATIC void bindpoint_diffuse_texture1( world_instance *world, struct world_surface *mat ) + { glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, world->textures[ mat->info.tex_diffuse ] ); @@ -163,9 +192,6 @@ VG_STATIC void bindpoint_diffuse_texture1( world_instance *world, VG_STATIC void render_world_vb( world_instance *world, camera *cam ) { - m4x3f identity_matrix; - m4x3_identity( identity_matrix ); - shader_scene_vertex_blend_use(); shader_scene_vertex_blend_uTexGarbage(0); shader_scene_vertex_blend_uTexGradients(1); @@ -180,24 +206,25 @@ VG_STATIC void render_world_vb( world_instance *world, camera *cam ) vg_tex2d_bind( &tex_terrain_noise, 0 ); shader_scene_vertex_blend_uPv( cam->mtx.pv ); - shader_scene_vertex_blend_uPvmPrev( cam->mtx_prev.pv ); - shader_scene_vertex_blend_uMdl( identity_matrix ); shader_scene_vertex_blend_uCamera( cam->transform[3] ); - world_render_both_stages( world, k_shader_standard_vertex_blend, - bindpoint_diffuse_texture1 ); + struct world_pass pass = { + .shader = k_shader_standard_vertex_blend, + .cam = cam, + .fn_bind_textures = bindpoint_diffuse_texture1, + .fn_set_mdl = shader_scene_vertex_blend_uMdl, + .fn_set_uPvmPrev = shader_scene_vertex_blend_uPvmPrev, + }; + + world_render_both_stages( world, &pass ); } VG_STATIC void render_world_standard( world_instance *world, camera *cam ) { - m4x3f identity_matrix; - m4x3_identity( identity_matrix ); - shader_scene_standard_use(); shader_scene_standard_uTexGarbage(0); shader_scene_standard_uTexMain(1); shader_scene_standard_uPv( cam->mtx.pv ); - shader_scene_standard_uPvmPrev( cam->mtx_prev.pv ); world_link_lighting_ub( world, _shader_scene_standard.id ); world_bind_position_texture( world, _shader_scene_standard.id, @@ -208,24 +235,25 @@ VG_STATIC void render_world_standard( world_instance *world, camera *cam ) _uniform_scene_standard_uLightsIndex, 4 ); bind_terrain_noise(); - - shader_scene_standard_uMdl( identity_matrix ); shader_scene_standard_uCamera( cam->transform[3] ); - world_render_both_stages( world, k_shader_standard, - bindpoint_diffuse_texture1 ); + struct world_pass pass = { + .shader = k_shader_standard, + .cam = cam, + .fn_bind_textures = bindpoint_diffuse_texture1, + .fn_set_mdl = shader_scene_standard_uMdl, + .fn_set_uPvmPrev = shader_scene_standard_uPvmPrev, + }; + + world_render_both_stages( world, &pass ); } VG_STATIC void render_world_alphatest( world_instance *world, camera *cam ) { - m4x3f identity_matrix; - m4x3_identity( identity_matrix ); - shader_scene_standard_alphatest_use(); shader_scene_standard_alphatest_uTexGarbage(0); shader_scene_standard_alphatest_uTexMain(1); shader_scene_standard_alphatest_uPv( cam->mtx.pv ); - shader_scene_standard_alphatest_uPvmPrev( cam->mtx_prev.pv ); world_link_lighting_ub( world, _shader_scene_standard_alphatest.id ); world_bind_position_texture( world, _shader_scene_standard_alphatest.id, @@ -238,13 +266,20 @@ VG_STATIC void render_world_alphatest( world_instance *world, camera *cam ) bind_terrain_noise(); - shader_scene_standard_alphatest_uMdl( identity_matrix ); + shader_scene_standard_alphatest_uCamera( cam->transform[3] ); glDisable(GL_CULL_FACE); - - world_render_both_stages( world, k_shader_standard_cutout, - bindpoint_diffuse_texture1 ); + + struct world_pass pass = { + .shader = k_shader_standard_cutout, + .cam = cam, + .fn_bind_textures = bindpoint_diffuse_texture1, + .fn_set_mdl = shader_scene_standard_alphatest_uMdl, + .fn_set_uPvmPrev = shader_scene_standard_alphatest_uPvmPrev, + }; + + world_render_both_stages( world, &pass ); glEnable(GL_CULL_FACE); } @@ -261,9 +296,6 @@ VG_STATIC void bindpoint_terrain( world_instance *world, VG_STATIC void render_terrain( world_instance *world, camera *cam ) { - m4x3f identity_matrix; - m4x3_identity( identity_matrix ); - shader_scene_terrain_use(); shader_scene_terrain_uTexGarbage(0); shader_scene_terrain_uTexGradients(1); @@ -279,12 +311,17 @@ VG_STATIC void render_terrain( world_instance *world, camera *cam ) vg_tex2d_bind( &tex_terrain_noise, 0 ); shader_scene_terrain_uPv( cam->mtx.pv ); - shader_scene_terrain_uPvmPrev( cam->mtx_prev.pv ); - - shader_scene_terrain_uMdl( identity_matrix ); shader_scene_terrain_uCamera( cam->transform[3] ); - world_render_both_stages( world, k_shader_terrain_blend, bindpoint_terrain ); + struct world_pass pass = { + .shader = k_shader_terrain_blend, + .cam = cam, + .fn_bind_textures = bindpoint_terrain, + .fn_set_mdl = shader_scene_terrain_uMdl, + .fn_set_uPvmPrev = shader_scene_terrain_uPvmPrev, + }; + + world_render_both_stages( world, &pass ); } VG_STATIC void render_sky( world_instance *world, camera *cam ) @@ -387,8 +424,7 @@ VG_STATIC void world_prerender( world_instance *world ) state->g_debug_indices = k_debug_light_indices; state->g_light_preview = k_light_preview; state->g_debug_complexity = k_debug_light_complexity; - - state->g_time_of_day = vg_fractf( g_time ); +state->g_time_of_day = vg_fractf( g_time ); state->g_day_phase = cosf( state->g_time_of_day * VG_PIf * 2.0f ); state->g_sunset_phase= cosf( state->g_time_of_day * VG_PIf * 4.0f + VG_PIf );