X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_gen.c;h=e2ec14af8edd774ad28c7f441b624d3c66109d4c;hb=53b534974303043efaf1d887711fcd349f6a2885;hp=b7aaf50995caef93d29660110007cd35696928f5;hpb=2329044d44a5aff035b01926f7901d9e89ad284e;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_gen.c b/world_gen.c index b7aaf50..e2ec14a 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,7 +46,7 @@ VG_STATIC void world_add_all_if_material( m4x3f transform, scene_context *scene, * | | * |________| */ -VG_STATIC void world_gen_add_blob( world_instance *world, +static void world_gen_add_blob( vg_rand *rand, world_instance *world, scene_context *scene, ray_hit *hit ) { m4x3f transform; @@ -57,7 +57,7 @@ VG_STATIC void world_gen_add_blob( world_instance *world, float angle = v3_dot(hit->normal,(v3f){0.0f,1.0f,0.0f}); q_axis_angle( qsurface, axis, angle ); - q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64()*VG_TAUf ); + q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64(rand)*VG_TAUf ); q_mul( qsurface, qrandom, qsurface ); q_m3x3( qsurface, transform ); v3_copy( hit->pos, transform[3] ); @@ -85,13 +85,12 @@ VG_STATIC void world_gen_add_blob( world_instance *world, 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,7 +105,7 @@ VG_STATIC void world_gen_add_blob( world_instance *world, /* * Sprinkle foliage models over the map on terrain material */ -VG_STATIC void world_apply_procedural_foliage( world_instance *world, +static void world_apply_procedural_foliage( world_instance *world, scene_context *scene, struct world_surface *mat ) { @@ -124,9 +123,10 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world, float area = volume[0]*volume[2]; u32 particles = 0.08f * area; - /* TODO: Quasirandom? */ vg_info( "Map area: %f. Max particles: %u\n", area, particles ); + u64 t0 = SDL_GetPerformanceCounter(); +#if 0 for( u32 i=0; i 0.8f) && (m1 == mat) && (hit.pos[1] > 0.0f+10.0f)){ world_gen_add_blob( world, scene, &hit ); @@ -144,11 +145,55 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world, } } } +#else - vg_info( "%d foliage models added\n", count ); + vg_rand rand; + vg_rand_seed( &rand, 3030 ); + + const f32 tile_scale = 16.0f; + v2i tiles = { volume[0]/tile_scale, volume[2]/tile_scale }; + + u32 per_tile = particles/(tiles[0]*tiles[1]); + + for( i32 x=0; xscene_geo.bbx[0], co ); + + ray_hit hit; + hit.dist = INFINITY; + + if( ray_world( world, co, (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( &rand, world, scene, &hit ); + count ++; + } + } + + } + } + } + +#endif + + + + u64 t1 = SDL_GetPerformanceCounter(), + utime_blobs = t1-t0, + ufreq = SDL_GetPerformanceFrequency(); + f64 ftime_blobs = ((f64)utime_blobs / (f64)ufreq)*1000.0; + + vg_info( "%d foliage models added. %f%% (%fms)\n", count, + 100.0*((f64)count/(f64)particles), ftime_blobs); } -VG_STATIC +static void world_unpack_submesh_dynamic( world_instance *world, scene_context *scene, mdl_submesh *sm ){ if( sm->flags & k_submesh_flag_consumed ) return; @@ -164,7 +209,7 @@ void world_unpack_submesh_dynamic( world_instance *world, /* * Create the main meshes for the world */ -VG_STATIC void world_gen_generate_meshes( world_instance *world ){ +static void world_gen_generate_meshes( world_instance *world ){ /* * Compile meshes into the world scenes */ @@ -191,6 +236,10 @@ VG_STATIC void world_gen_generate_meshes( world_instance *world ){ &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 */ @@ -268,16 +317,28 @@ VG_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; } } /* unpack challenge models */ - for( u32 i=0; ient_challenge ); i++ ){ - ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i ); + 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 ++ ){ + for( u32 j=0; jsubmesh_count; j ++ ){ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, - challenge->submesh_start+j ); + region->submesh_start+j ); world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); } } @@ -295,6 +356,18 @@ VG_STATIC void world_gen_generate_meshes( world_instance *world ){ } } + /* 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->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_PROPS; + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } + vg_async_dispatch( call, async_scene_upload ); } @@ -321,7 +394,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 ); @@ -336,7 +409,7 @@ VG_STATIC void async_upload_light_indices( void *payload, u32 size ){ /* * Computes light indices for world */ -VG_STATIC void world_gen_compute_light_indices( world_instance *world ){ +static void world_gen_compute_light_indices( world_instance *world ){ /* light cubes */ v3f cubes_min, cubes_max; v3_muls( world->scene_geo.bbx[0], 1.0f/k_world_light_cube_size, cubes_min ); @@ -430,12 +503,14 @@ VG_STATIC void world_gen_compute_light_indices( world_instance *world ){ 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 ); @@ -494,7 +569,7 @@ VG_STATIC void world_gen_compute_light_indices( world_instance *world ){ /* * Rendering pass needed to complete the world */ -VG_STATIC void async_world_postprocess( void *payload, u32 _size ){ +static void async_world_postprocess( void *payload, u32 _size ){ /* create scene lighting buffer */ world_instance *world = payload; @@ -604,19 +679,58 @@ VG_STATIC void async_world_postprocess( void *payload, u32 _size ){ glBufferSubData( GL_UNIFORM_BUFFER, 0, sizeof(struct ub_world_lighting), &world->ub_lighting ); - world->status = k_world_status_loaded; + /* + * 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( world_instance *world ){ +static void world_gen_load_surfaces( world_instance *world ){ vg_info( "Loading textures\n" ); world->texture_count = 0; world->texture_count = world->meta.textures.count+1; world->textures = vg_linear_alloc( world->heap, vg_align8(sizeof(GLuint)*world->texture_count) ); - - vg_tex2d_replace_with_error( &world->textures[0] ); + world->textures[0] = vg.tex_missing; for( u32 i=0; imeta.textures); i++ ){ mdl_texture *tex = mdl_arritm( &world->meta.textures, i ); @@ -646,8 +760,9 @@ VG_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; } }