From: hgn Date: Sat, 29 Oct 2022 15:23:38 +0000 (+0100) Subject: surface props X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=23a1be081ab9e378cba49a23b8ed4d4082b580c1;hp=1f0e3292c021e8263716e5f4544a1efcedf3f03d;p=carveJwlIkooP6JGAAIwe30JlM.git surface props --- diff --git a/audio.h b/audio.h index 26c1a35..9622c50 100644 --- a/audio.h +++ b/audio.h @@ -37,6 +37,24 @@ audio_clip audio_footsteps[] = { {.path = "sound/step_concrete3.ogg" } }; +audio_clip audio_footsteps_grass[] = { + {.path = "sound/step_bush0.ogg" }, + {.path = "sound/step_bush1.ogg" }, + {.path = "sound/step_bush2.ogg" }, + {.path = "sound/step_bush3.ogg" }, + {.path = "sound/step_bush4.ogg" }, + {.path = "sound/step_bush5.ogg" } +}; + +audio_clip audio_footsteps_wood[] = { + {.path = "sound/step_wood0.ogg" }, + {.path = "sound/step_wood1.ogg" }, + {.path = "sound/step_wood2.ogg" }, + {.path = "sound/step_wood3.ogg" }, + {.path = "sound/step_wood4.ogg" }, + {.path = "sound/step_wood5.ogg" } +}; + audio_clip audio_lands[] = { { .path = "sound/land0.ogg" }, { .path = "sound/land1.ogg" }, @@ -167,6 +185,10 @@ VG_STATIC void audio_init(void) audio_clip_loadn( audio_water, vg_list_size(audio_water), NULL ); audio_clip_loadn( audio_grass, vg_list_size(audio_grass), NULL ); audio_clip_loadn( audio_footsteps, vg_list_size(audio_footsteps), NULL ); + audio_clip_loadn( audio_footsteps_grass, + vg_list_size(audio_footsteps_grass), NULL ); + audio_clip_loadn( audio_footsteps_wood, + vg_list_size(audio_footsteps_wood), NULL ); audio_clip_loadn( audio_rewind, vg_list_size(audio_rewind), NULL ); audio_clip_loadn( audio_ui, vg_list_size(audio_ui), NULL ); @@ -281,7 +303,7 @@ enum audio_sprite_type * Trace out a random point, near the player to try and determine water areas */ VG_STATIC enum audio_sprite_type audio_sample_sprite_random( v3f origin, - v3f output ) + v3f output ) { v3f chance = { (vg_randf()-0.5f) * 30.0f, 8.0f, @@ -296,22 +318,29 @@ VG_STATIC enum audio_sprite_type audio_sample_sprite_random( v3f origin, if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &contact ) ) { - if( ray_hit_is_ramp( &contact ) ) + struct world_material *mat = ray_hit_material( &contact ); + + if( mat->info.surface_prop == k_surface_prop_grass) + { + v3_copy( contact.pos, output ); + return k_audio_sprite_type_grass; + } + else { vg_line( pos, contact.pos, 0xff0000ff ); vg_line_pt3( contact.pos, 0.3f, 0xff0000ff ); return k_audio_sprite_type_none; } - - v3_copy( contact.pos, output ); - return k_audio_sprite_type_grass; } output[0] = pos[0]; output[1] = 0.0f; output[2] = pos[2]; - - return k_audio_sprite_type_water; + + if( world.water.enabled ) + return k_audio_sprite_type_water; + else + return k_audio_sprite_type_none; } VG_STATIC void audio_debug_soundscapes(void) diff --git a/blender_export.py b/blender_export.py index 4508bca..8195123 100644 --- a/blender_export.py +++ b/blender_export.py @@ -71,6 +71,7 @@ class mdl_material(Structure): _fields_ = [("pstr_name",c_uint32), ("shader",c_uint32), ("flags",c_uint32), + ("surface_prop",c_uint32), ("colour",c_float*4), ("colour1",c_float*4), ("tex_diffuse",c_uint32), @@ -1080,8 +1081,13 @@ def encoder_process_material( mat ): flags = 0x00 if mat.cv_data.skate_surface: flags |= 0x1 if mat.cv_data.collision: flags |= 0x2 + if mat.cv_data.grow_grass: flags |= 0x4 dest.flags = flags + if mat.cv_data.surface_prop == 'concrete': dest.surface_prop = 0 + if mat.cv_data.surface_prop == 'wood': dest.surface_prop = 1 + if mat.cv_data.surface_prop == 'grass': dest.surface_prop = 2 + if mat.cv_data.shader == 'standard': dest.shader = 0 if mat.cv_data.shader == 'standard_cutout': dest.shader = 1 if mat.cv_data.shader == 'terrain_blend': @@ -1101,8 +1107,8 @@ def encoder_process_material( mat ): #{ dest.shader = 3 - dest.colour1[0] = mat.cv_data.uv_offset[0] - dest.colour1[1] = mat.cv_data.uv_offset[1] + dest.colour1[0] = mat.cv_data.blend_offset[0] + dest.colour1[1] = mat.cv_data.blend_offset[1] #} if mat.cv_data.shader == 'water': @@ -2405,6 +2411,14 @@ class CV_MATERIAL_SETTINGS(bpy.types.PropertyGroup): ('vertex_blend', "vertex_blend", "", 3), ('water',"water","",4), ]) + + surface_prop: bpy.props.EnumProperty( + name="Surface Property", + items = [ + ('concrete','concrete','',0), + ('wood','wood','',1), + ('grass','grass','',2) + ]) collision: bpy.props.BoolProperty( \ name="Collisions Enabled",\ @@ -2416,6 +2430,11 @@ class CV_MATERIAL_SETTINGS(bpy.types.PropertyGroup): default=True,\ description = "Should the game try to target this surface?" \ ) + grow_grass: bpy.props.BoolProperty( \ + name="Grow Grass", \ + default=False,\ + description = "Spawn grass sprites on this surface?" \ + ) blend_offset: bpy.props.FloatVectorProperty( \ name="Blend Offset", \ size=2, \ @@ -2464,10 +2483,12 @@ class CV_MATERIAL_PANEL(bpy.types.Panel): info = material_info( active_mat ) _.layout.prop( active_mat.cv_data, "shader" ) + _.layout.prop( active_mat.cv_data, "surface_prop" ) _.layout.prop( active_mat.cv_data, "collision" ) if active_mat.cv_data.collision: _.layout.prop( active_mat.cv_data, "skate_surface" ) + _.layout.prop( active_mat.cv_data, "grow_grass" ) if active_mat.cv_data.shader == "terrain_blend": #{ diff --git a/main.c b/main.c index 0e5a2fc..22052fa 100644 --- a/main.c +++ b/main.c @@ -94,7 +94,7 @@ VG_STATIC void vg_load(void) world_audio_init(); /* 'systems' are completely loaded now */ - strcpy( world.world_name, "models/mp_test.mdl" ); + strcpy( world.world_name, "models/mp_dev.mdl" ); world_load(); vg_console_load_autos(); } diff --git a/menu.h b/menu.h index 02ab252..21fa313 100644 --- a/menu.h +++ b/menu.h @@ -17,14 +17,16 @@ VG_STATIC float menu_fov_target = 97.0f; VG_STATIC v2f menu_extra_angles; VG_STATIC int menu_loc = 1, - menu_loc_last = 1; + menu_loc_last = 1; VG_STATIC u32 menu_page = 0; VG_STATIC int cl_menu = 0, - cl_menu_go_away = 0; + cl_menu_go_away = 0; VG_STATIC const char *playermodels[] = { "ch_new", "ch_jordan", "ch_outlaw" }; +vg_tex2d tex_menu = { .path = "textures/menu.qoi",.flags = VG_TEXTURE_NEAREST }; + VG_STATIC void menu_btn_paused( int event ); VG_STATIC void menu_btn_quit( int event ); VG_STATIC void menu_btn_skater( int event ); @@ -104,7 +106,10 @@ VG_STATIC void menu_init(void) mdl_close( &menu_model ); vg_acquire_thread_sync(); - mdl_unpack_glmesh( &menu_model, &menu_glmesh ); + { + mdl_unpack_glmesh( &menu_model, &menu_glmesh ); + vg_tex2d_init( (vg_tex2d *[]){ &tex_menu }, 1 ); + } vg_release_thread_sync(); for( int i=0; irb.co ); audio_player_set_vol( &audio_player_extra, 6.0f ); - audio_player_playclip( &audio_player_extra, - &audio_footsteps[rand()%4] ); + + if( player.surface_prop == k_surface_prop_concrete ) + { + audio_player_playclip( + &audio_player_extra, + &audio_footsteps[rand()%vg_list_size(audio_footsteps)] + ); + } + else if( player.surface_prop == k_surface_prop_grass ) + { + audio_player_playclip( + &audio_player_extra, + &audio_footsteps_grass[rand()%vg_list_size(audio_footsteps_grass)] + ); + } + else if( player.surface_prop == k_surface_prop_wood ) + { + audio_player_playclip( + &audio_player_extra, + &audio_footsteps_wood[rand()%vg_list_size(audio_footsteps_wood)] + ); + } } player.step_phase = walk_phase; diff --git a/player_physics.h b/player_physics.h index ff8d1f7..438441e 100644 --- a/player_physics.h +++ b/player_physics.h @@ -81,7 +81,8 @@ VG_STATIC void player_start_air(void) u32 scolour = (u8)(vg_minf(-land_delta * 2.0f, 255.0f)); /* Bias prediction towords ramps */ - if( ray_hit_is_ramp( &contact ) ) + if( ray_hit_material( &contact )->info.flags + & k_material_flag_skate_surface ) { land_delta *= 0.1f; scolour |= 0x0000a000; @@ -359,7 +360,14 @@ VG_STATIC void player_walk_physics(void) } } - phys->in_air = len==0?1:0; + if( len == 0 ) + phys->in_air = 1; + else + { + phys->in_air = 0; + struct world_material *surface_mat = world_contact_material( manifold ); + player.surface_prop = surface_mat->info.surface_prop; + } if( !phys->in_air ) { diff --git a/shaders/standard.fs b/shaders/standard.fs index e3f05c8..d3a6842 100644 --- a/shaders/standard.fs +++ b/shaders/standard.fs @@ -1,20 +1,40 @@ out vec4 FragColor; +uniform sampler2D uTexGarbage; uniform sampler2D uTexMain; -uniform vec4 uColour; +uniform vec3 uCamera; +uniform vec4 uPlane; in vec4 aColour; in vec2 aUv; in vec3 aNorm; in vec3 aCo; +in vec3 aWorldCo; + +#include "common_world.glsl" void main() { - vec3 diffuse = texture( uTexMain, aUv ).rgb; - float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm)); - float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm)); - diffuse += vec3(0.2,0.2,0.2) + - vec3(1.0,1.0,0.9)*light1 + - vec3(0.1,0.3,0.4)*light2; - FragColor = vec4(diffuse*uColour.rgb, aColour.a*uColour.a); + vec3 vfrag = vec3(0.5,0.5,0.5); + vec4 vsamplemain = texture( uTexMain, aUv ); + vec3 qnorm = normalize(aNorm); + + vfrag = vsamplemain.rgb; + + if( g_light_preview == 1 ) + { + vfrag = vec3(0.5); + } + + // Lighting + vec3 halfview = uCamera - aWorldCo; + float fdist = length( halfview ); + halfview /= fdist; + + vfrag = do_light_diffuse( vfrag, qnorm ); + vfrag = do_light_spec( vfrag, qnorm, halfview, 0.1 ); + vfrag = do_light_shadowing( vfrag ); + vfrag = apply_fog( vfrag, fdist ); + + FragColor = vec4(vfrag, 1.0); } diff --git a/shaders/standard.h b/shaders/standard.h index cf98fb0..ac052b0 100644 --- a/shaders/standard.h +++ b/shaders/standard.h @@ -44,42 +44,172 @@ static struct vg_shader _shader_standard = { .static_src = "out vec4 FragColor;\n" "\n" +"uniform sampler2D uTexGarbage;\n" "uniform sampler2D uTexMain;\n" -"uniform vec4 uColour;\n" +"uniform vec3 uCamera;\n" +"uniform vec4 uPlane;\n" "\n" "in vec4 aColour;\n" "in vec2 aUv;\n" "in vec3 aNorm;\n" "in vec3 aCo;\n" +"in vec3 aWorldCo;\n" +"\n" +"#line 1 1 \n" +"layout (std140) uniform ub_world_lighting\n" +"{\n" +" vec4 g_light_colours[3];\n" +" vec4 g_light_directions[3];\n" +" vec4 g_ambient_colour;\n" +"\n" +" vec4 g_water_plane;\n" +" vec4 g_depth_bounds;\n" +" float g_water_fog;\n" +" int g_light_count;\n" +" int g_light_preview;\n" +"};\n" +"\n" +"uniform sampler2D g_world_depth;\n" +"\n" +"// Standard diffuse + spec models\n" +"// ==============================\n" +"\n" +"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n" +"{\n" +" vec3 vtotal = g_ambient_colour.rgb;\n" +"\n" +" for( int i=0; itri[0] >= valid_start) && - (hit->tri[0] < valid_end); -#endif + if( (index >= mat->sm_geo.vertex_start) && + (index < mat->sm_geo.vertex_start+mat->sm_geo.vertex_count ) ) + { + return mat; + } + } + + /* error material */ + return &world.materials[0]; } -VG_STATIC int ray_hit_is_ramp( ray_hit *hit ) +VG_STATIC struct world_material *world_contact_material( rb_ct *ct ) { - return 1; -#if 0 - u32 valid_start = world.sm_geo_std.vertex_start, - valid_end = world.sm_geo_vb.vertex_start; + return world_tri_index_material( ct->element_id ); +} - return (hit->tri[0] >= valid_start) && - (hit->tri[0] < valid_end); -#endif +VG_STATIC struct world_material *ray_hit_material( ray_hit *hit ) +{ + return world_tri_index_material( hit->tri[0] ); } #endif /* WORLD_H */ diff --git a/world_gen.h b/world_gen.h index c87112a..9ee1e6b 100644 --- a/world_gen.h +++ b/world_gen.h @@ -34,7 +34,7 @@ VG_STATIC void world_add_all_if_material( m4x3f transform, scene *pscene, } /* Sprinkle foliage models over the map on terrain material */ -VG_STATIC void world_apply_procedural_foliage(void) +VG_STATIC void world_apply_procedural_foliage( struct world_material *mat ) { vg_linear_clear( vg_mem.scratch ); @@ -61,8 +61,8 @@ VG_STATIC void world_apply_procedural_foliage(void) if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit )) { - if( (hit.normal[1] > 0.8f) && ray_hit_is_terrain(&hit) && - (hit.pos[1] > 0.0f+10.0f) ) + struct world_material *m1 = ray_hit_material( &hit ); + if((hit.normal[1] > 0.8f) && (m1 == mat) && (hit.pos[1] > 0.0f+10.0f)) { v4f qsurface, qrandom; v3f axis; @@ -173,22 +173,8 @@ VG_STATIC void world_pct_water( mdl_node *pnode ) return; } - mdl_submesh *sm = mdl_node_submesh( world.meta, pnode, 0 ); - - if( sm ) - { - vg_acquire_thread_sync(); - { - mdl_unpack_submesh( world.meta, &world.mesh_water, sm ); - world.water.enabled = 1; - water_set_surface( pnode->co[1] ); - } - vg_release_thread_sync(); - } - else - { - vg_warn( "Water entity has no submeshes!\n" ); - } + world.water.enabled = 1; + water_set_surface( pnode->co[1] ); } VG_STATIC void world_pct_audio( mdl_node *pnode ) @@ -322,7 +308,7 @@ VG_STATIC void world_generate(void) /* * Compile meshes into the world scenes */ - world.scene_geo = scene_init( world.dynamic_vgl, 350000, 1200000 ); + world.scene_geo = scene_init( world.dynamic_vgl, 320000, 1200000 ); m4x3f midentity; m4x3_identity( midentity ); @@ -340,13 +326,10 @@ VG_STATIC void world_generate(void) struct world_material *mat = &world.materials[ i ]; if( mat->info.flags & k_material_flag_collision ) - { world_add_all_if_material( midentity, world.scene_geo, world.meta, i ); - scene_copy_slice( world.scene_geo, &mat->sm_geo ); - } - } - + scene_copy_slice( world.scene_geo, &mat->sm_geo ); + } @@ -386,7 +369,21 @@ VG_STATIC void world_generate(void) scene_copy_slice( world.scene_no_collide, &world.sm_foliage_main ); #endif + for( int i=0; iinfo.flags & k_material_flag_collision) ) + { + world_add_all_if_material( midentity, world.scene_no_collide, + world.meta, i ); + } + if( mat->info.flags & k_material_flag_grow_grass ) + world_apply_procedural_foliage( mat ); + + scene_copy_slice( world.scene_no_collide, &mat->sm_no_collide ); + } /* upload and free that */ vg_acquire_thread_sync(); @@ -561,7 +558,6 @@ VG_STATIC void world_unload(void) mesh_free( &world.mesh_route_lines ); mesh_free( &world.mesh_geo ); mesh_free( &world.mesh_no_collide ); - mesh_free( &world.mesh_water ); world.time = 0.0; world.rewind_from = 0.0; diff --git a/world_render.h b/world_render.h index 25d72ee..8398a60 100644 --- a/world_render.h +++ b/world_render.h @@ -7,28 +7,16 @@ #include "world.h" -vg_tex2d tex_terrain_colours = { .path = "textures/gradients.qoi", - .flags = VG_TEXTURE_CLAMP|VG_TEXTURE_NEAREST }; - vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi", .flags = VG_TEXTURE_NEAREST }; -vg_tex2d tex_alphatest = { .path = "textures/alphatest.qoi", - .flags = VG_TEXTURE_NEAREST }; - -vg_tex2d tex_graffiti = { .path = "textures/graffitibox.qoi", - .flags = VG_TEXTURE_NEAREST }; - VG_STATIC void world_render_init(void) { vg_info( "Loading default world textures\n" ); vg_acquire_thread_sync(); { - vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_colours, - &tex_terrain_noise, - &tex_alphatest, - &tex_graffiti }, 4 ); + vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_noise }, 1 ); } vg_release_thread_sync(); } @@ -39,10 +27,9 @@ VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera ); * Rendering */ -VG_STATIC void bind_terrain_textures(void) +VG_STATIC void bind_terrain_noise(void) { vg_tex2d_bind( &tex_terrain_noise, 0 ); - vg_tex2d_bind( &tex_terrain_colours, 1 ); } VG_STATIC void world_render_if( enum mdl_shader shader, @@ -106,6 +93,24 @@ VG_STATIC void render_world_vb( m4x4f projection, v3f camera ) bindpoint_diffuse_texture1 ); } +VG_STATIC void render_world_standard( m4x4f projection, v3f camera ) +{ + m4x3f identity_matrix; + m4x3_identity( identity_matrix ); + + shader_standard_use(); + shader_standard_uTexGarbage(0); + shader_standard_uTexMain(1); + shader_link_standard_ub( _shader_standard.id, 2 ); + bind_terrain_noise(); + + shader_standard_uPv( projection ); + shader_standard_uMdl( identity_matrix ); + shader_standard_uCamera( camera ); + + world_render_both_stages( k_shader_standard, + bindpoint_diffuse_texture1 ); +} VG_STATIC void render_world_alphatest( m4x4f projection, v3f camera ) { @@ -116,8 +121,7 @@ VG_STATIC void render_world_alphatest( m4x4f projection, v3f camera ) shader_alphatest_uTexGarbage(0); shader_alphatest_uTexMain(1); shader_link_standard_ub( _shader_alphatest.id, 2 ); - - vg_tex2d_bind( &tex_terrain_noise, 0 ); + bind_terrain_noise(); shader_alphatest_uPv( projection ); shader_alphatest_uMdl( identity_matrix ); diff --git a/world_routes.h b/world_routes.h index 97fc557..5a7c07b 100644 --- a/world_routes.h +++ b/world_routes.h @@ -1119,7 +1119,7 @@ VG_STATIC void world_routes_update(void) } } -VG_STATIC void bind_terrain_textures(void); +VG_STATIC void bind_terrain_noise(void); VG_STATIC void render_world_routes( m4x4f projection, v3f camera ) { m4x3f identity_matrix; @@ -1128,7 +1128,7 @@ VG_STATIC void render_world_routes( m4x4f projection, v3f camera ) shader_route_use(); shader_route_uTexGarbage(0); shader_link_standard_ub( _shader_route.id, 2 ); - bind_terrain_textures(); + bind_terrain_noise(); shader_route_uPv( projection ); shader_route_uMdl( identity_matrix ); diff --git a/world_sfd.h b/world_sfd.h index a83fe0a..5b5bd99 100644 --- a/world_sfd.h +++ b/world_sfd.h @@ -99,6 +99,7 @@ VG_STATIC void sfd_update(void) } } +VG_STATIC void bind_terrain_noise(void); VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform ) { mesh_bind( &world.sfd.mesh_display ); @@ -107,7 +108,7 @@ VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform ) shader_scoretext_uTexGarbage(0); shader_scoretext_uTexGradients(1); shader_link_standard_ub( _shader_scoretext.id, 2 ); - bind_terrain_textures(); + bind_terrain_noise(); vg_tex2d_bind( &tex_scoretext, 1 ); shader_scoretext_uPv( projection ); @@ -128,7 +129,8 @@ VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform ) shader_vblend_uTexGarbage(0); shader_vblend_uTexGradients(1); shader_link_standard_ub( _shader_vblend.id, 2 ); - bind_terrain_textures(); + bind_terrain_noise(); + vg_tex2d_bind( &tex_scoretext, 1 ); shader_vblend_uPv( projection ); shader_vblend_uMdl( transform ); diff --git a/world_water.h b/world_water.h index 928d36c..e31994a 100644 --- a/world_water.h +++ b/world_water.h @@ -157,7 +157,7 @@ VG_STATIC void render_water_surface( m4x4f pv, m4x3f camera ) glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); - mesh_bind( &world.mesh_water ); + mesh_bind( &world.mesh_no_collide ); for( int i=0; i