X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_gen.c;h=df5b342e40fb11965c963a0ce4009db6a4da31bb;hb=e311bbe2fa903a7e2a922f202f389b799193195d;hp=799059a5f423626e00dd8a9969f94f3ece09a58e;hpb=342fcbf6fda017bdd38d56ce0fa7c9e59e589f3b;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_gen.c b/world_gen.c index 799059a..df5b342 100644 --- a/world_gen.c +++ b/world_gen.c @@ -18,7 +18,7 @@ * Add all triangles from the model, which match the material ID * applies affine transform to the model */ -VG_STATIC void world_add_all_if_material( m4x3f transform, scene_context *scene, +static void world_add_all_if_material( m4x3f transform, scene_context *scene, mdl_context *mdl, u32 id ) { for( u32 i=0; imeshs); i++ ){ @@ -46,9 +46,9 @@ VG_STATIC void world_add_all_if_material( m4x3f transform, scene_context *scene, * | | * |________| */ -VG_STATIC void world_gen_add_blob( scene_context *scene, ray_hit *hit ) +static void world_gen_add_blob( world_instance *world, + scene_context *scene, ray_hit *hit ) { - world_instance *world = world_loading_instance(); m4x3f transform; v4f qsurface, qrandom; v3f axis; @@ -85,13 +85,12 @@ VG_STATIC void world_gen_add_blob( scene_context *scene, ray_hit *hit ) scene_vert *ref = &world->scene_geo.arrvertices[ hit->tri[0] ]; - for( u32 i=0; ico, pvert->co ); - scene_vert_pack_norm( pvert, transform[1] ); + scene_vert_pack_norm( pvert, transform[1], 0.0f ); v2_copy( ref->uv, pvert->uv ); } @@ -106,13 +105,13 @@ VG_STATIC void world_gen_add_blob( scene_context *scene, ray_hit *hit ) /* * Sprinkle foliage models over the map on terrain material */ -VG_STATIC void world_apply_procedural_foliage( scene_context *scene, +static void world_apply_procedural_foliage( world_instance *world, + scene_context *scene, struct world_surface *mat ) { if( vg.quality_profile == k_quality_profile_low ) return; - world_instance *world = world_loading_instance(); vg_info( "Applying foliage (%u)\n", mat->info.pstr_name ); v3f volume; @@ -136,10 +135,11 @@ VG_STATIC void world_apply_procedural_foliage( scene_context *scene, ray_hit hit; hit.dist = INFINITY; - if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &hit )){ + if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &hit, + k_material_flag_ghosts )){ struct world_surface *m1 = ray_hit_surface( world, &hit ); if((hit.normal[1] > 0.8f) && (m1 == mat) && (hit.pos[1] > 0.0f+10.0f)){ - world_gen_add_blob( scene, &hit ); + world_gen_add_blob( world, scene, &hit ); count ++; } } @@ -148,15 +148,26 @@ VG_STATIC void world_apply_procedural_foliage( scene_context *scene, vg_info( "%d foliage models added\n", count ); } +static +void world_unpack_submesh_dynamic( world_instance *world, + scene_context *scene, mdl_submesh *sm ){ + if( sm->flags & k_submesh_flag_consumed ) return; + + m4x3f identity; + m4x3_identity( identity ); + scene_add_mdl_submesh( scene, &world->meta, sm, identity ); + + scene_copy_slice( scene, sm ); + sm->flags |= k_submesh_flag_consumed; +} + /* * Create the main meshes for the world */ -VG_STATIC void world_gen_generate_meshes(void) -{ +static void world_gen_generate_meshes( world_instance *world ){ /* * Compile meshes into the world scenes */ - world_instance *world = world_loading_instance(); scene_init( &world->scene_geo, 320000, 1200000 ); u32 buf_size = scene_mem_required( &world->scene_geo ); u8 *buffer = vg_linear_alloc( world->heap, buf_size ); @@ -180,6 +191,10 @@ VG_STATIC void world_gen_generate_meshes(void) &world->meta, i ); scene_copy_slice( &world->scene_geo, &surf->sm_geo ); + scene_set_vertex_flags( &world->scene_geo, + surf->sm_geo.vertex_start, + surf->sm_geo.vertex_count, + (u16)(surf->info.flags & 0xffff) ); } /* compress that bad boy */ @@ -227,7 +242,7 @@ VG_STATIC void world_gen_generate_meshes(void) vg_async_item *call = scene_alloc_async( &world->scene_no_collide, &world->mesh_no_collide, - 200000, 500000 ); + 250000, 500000 ); for( u32 i=0; isurface_count; i++ ){ struct world_surface *surf = &world->surfaces[ i ]; @@ -237,30 +252,72 @@ VG_STATIC void world_gen_generate_meshes(void) &world->scene_no_collide, &world->meta, i ); } - if( surf->info.flags & k_material_flag_grow_grass ) - world_apply_procedural_foliage( &world->scene_no_collide, surf ); + if( surf->info.flags & k_material_flag_grow_grass ){ + world_apply_procedural_foliage( world, &world->scene_no_collide, + surf ); + } scene_copy_slice( &world->scene_no_collide, &surf->sm_no_collide ); } + /* unpack traffic models.. TODO: should we just put all these submeshes in a + * dynamic models list? and then the actual entitities point to the + * models. we only have 2 types at the moment which need dynamic models but + * would make sense to do this when/if we have more. + */ 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 ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } - if( sm->flags & k_submesh_flag_consumed ){ - continue; - } + /* unpack challenge models */ + for( u32 i=0; ient_objective ); i++ ){ + ent_objective *objective = mdl_arritm( &world->ent_objective, i ); + + for( u32 j=0; jsubmesh_count; j ++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + objective->submesh_start+j ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } + + /* unpack region models */ + for( u32 i=0; ient_region ); i++ ){ + ent_region *region = mdl_arritm( &world->ent_region, i ); + + for( u32 j=0; jsubmesh_count; j ++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + region->submesh_start+j ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } - m4x3f identity; - m4x3_identity( identity ); - scene_add_mdl_submesh( &world->scene_no_collide, - &world->meta, sm, identity ); + /* unpack gate models */ + for( u32 i=0; ient_gate ); i++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, i ); - scene_copy_slice( &world->scene_no_collide, sm ); - sm->flags |= k_submesh_flag_consumed; + if( !(gate->flags & k_ent_gate_custom_mesh) ) continue; + + for( u32 j=0; jsubmesh_count; j ++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + gate->submesh_start+j ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } + + /* unpack prop models */ + for( u32 i=0; ient_prop ); i++ ){ + ent_prop *prop = mdl_arritm( &world->ent_prop, i ); + + for( u32 j=0; jsubmesh_count; j ++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + prop->submesh_start+j ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); } } @@ -268,8 +325,7 @@ VG_STATIC void world_gen_generate_meshes(void) } /* signed distance function for cone */ -static f32 fsd_cone_infinite( v3f p, v2f c ) -{ +static f32 fsd_cone_infinite( v3f p, v2f c ){ v2f q = { v2_length( (v2f){ p[0], p[2] } ), -p[1] }; float s = vg_maxf( 0.0f, v2_dot( q, c ) ); @@ -291,8 +347,7 @@ struct light_indices_upload_info{ /* * Async reciever to buffer light index data */ -VG_STATIC void async_upload_light_indices( void *payload, u32 size ) -{ +static void async_upload_light_indices( void *payload, u32 size ){ struct light_indices_upload_info *info = payload; glGenTextures( 1, &info->world->tex_light_cubes ); @@ -307,10 +362,8 @@ VG_STATIC void async_upload_light_indices( void *payload, u32 size ) /* * Computes light indices for world */ -VG_STATIC void world_gen_compute_light_indices(void) -{ +static void world_gen_compute_light_indices( world_instance *world ){ /* light cubes */ - world_instance *world = world_loading_instance(); v3f cubes_min, cubes_max; v3_muls( world->scene_geo.bbx[0], 1.0f/k_world_light_cube_size, cubes_min ); v3_muls( world->scene_geo.bbx[1], 1.0f/k_world_light_cube_size, cubes_max ); @@ -403,12 +456,14 @@ VG_STATIC void world_gen_compute_light_indices(void) v3f closest; closest_point_aabb( light->transform.co, bbx, closest ); - float dist = v3_dist( closest, light->transform.co ), - influence = 1.0f/(dist+1.0f); + f32 dist2 = v3_dist2( closest, light->transform.co ); - if( dist > light->range ) + if( dist2 > light->range*light->range ) continue; + f32 dist = sqrtf(dist2), + influence = 1.0f/(dist+1.0f); + if( light->type == k_light_type_spot){ v3f local; m4x3_mulv( light->inverse_world, center, local ); @@ -467,10 +522,9 @@ VG_STATIC void world_gen_compute_light_indices(void) /* * Rendering pass needed to complete the world */ -VG_STATIC void async_world_postprocess_render( void *payload, u32 _size ) -{ +static void async_world_postprocess( void *payload, u32 _size ){ /* create scene lighting buffer */ - world_instance *world = world_loading_instance(); + world_instance *world = payload; u32 size = VG_MAX(mdl_arrcount(&world->ent_light),1) * sizeof(float)*12; vg_info( "Upload %ubytes (lighting)\n", size ); @@ -577,12 +631,52 @@ VG_STATIC void async_world_postprocess_render( void *payload, u32 _size ) glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting ); glBufferSubData( GL_UNIFORM_BUFFER, 0, sizeof(struct ub_world_lighting), &world->ub_lighting ); + + /* + * Allocate cubemaps + */ + for( u32 i=0; ient_cubemap); i++ ){ + ent_cubemap *cm = mdl_arritm(&world->ent_cubemap,i); + + glGenTextures( 1, &cm->texture_id ); + glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id ); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + for( u32 j=0; j<6; j ++ ) { + glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, 0, GL_RGB, + WORLD_CUBEMAP_RES, WORLD_CUBEMAP_RES, + 0, GL_RGB, GL_UNSIGNED_BYTE, NULL ); + } + + glGenFramebuffers( 1, &cm->framebuffer_id ); + glBindFramebuffer( GL_FRAMEBUFFER, cm->framebuffer_id ); + glGenRenderbuffers(1, &cm->renderbuffer_id ); + glBindRenderbuffer( GL_RENDERBUFFER, cm->renderbuffer_id ); + glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, + WORLD_CUBEMAP_RES, WORLD_CUBEMAP_RES ); + + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X, cm->texture_id, 0 ); + glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, cm->renderbuffer_id ); + + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X, cm->texture_id, 0 ); + + if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ){ + vg_error( "Cubemap framebuffer incomplete.\n" ); + } + } + + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } /* Loads textures from the pack file */ -VG_STATIC void world_gen_load_surfaces(void) -{ - world_instance *world = world_loading_instance(); +static void world_gen_load_surfaces( world_instance *world ){ vg_info( "Loading textures\n" ); world->texture_count = 0;