performance measurements
[carveJwlIkooP6JGAAIwe30JlM.git] / world_gen.c
index 5f7b9a362e7b3fc294b4e6a5d13cd3ce00847f6c..543be6d178fb2d72426db6ba55db601c38830720 100644 (file)
@@ -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; i<mdl_arrcount(&mdl->meshs); 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; i<vg_list_size(verts); i++ )
-   {
+   for( u32 i=0; i<vg_list_size(verts); i++ ){
       scene_vert *pvert = &dst_verts[ i ],
                  *src   = &verts[ i ];
 
       m4x3_mulv( transform, src->co, 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,7 +148,7 @@ VG_STATIC void world_apply_procedural_foliage( scene_context *scene,
    vg_info( "%d foliage models added\n", count );
 }
 
-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,12 +164,10 @@ void world_unpack_submesh_dynamic( world_instance *world,
 /*
  * 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 );
@@ -193,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 */
@@ -250,8 +252,10 @@ 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 );
    }
@@ -268,16 +272,28 @@ VG_STATIC void world_gen_generate_meshes(void)
          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; i<mdl_arrcount( &world->ent_challenge ); i++ ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
+   for( u32 i=0; i<mdl_arrcount( &world->ent_objective ); i++ ){
+      ent_objective *objective = mdl_arritm( &world->ent_objective, i );
 
-      for( u32 j=0; j<challenge->submesh_count; j ++ ){
+      for( u32 j=0; j<objective->submesh_count; j ++ ){
          mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
-                                       challenge->submesh_start+j );
+                                       objective->submesh_start+j );
+         world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+      }
+   }
+
+   /* unpack region models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_region ); i++ ){
+      ent_region *region = mdl_arritm( &world->ent_region, i );
+
+      for( u32 j=0; j<region->submesh_count; j ++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       region->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
       }
    }
@@ -295,12 +311,23 @@ VG_STATIC void world_gen_generate_meshes(void)
       }
    }
 
+   /* unpack prop models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_prop ); i++ ){
+      ent_prop *prop = mdl_arritm( &world->ent_prop, i );
+
+      for( u32 j=0; j<prop->submesh_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 );
 }
 
 /* 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 ) );
 
@@ -322,8 +349,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 );
@@ -338,10 +364,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 );
@@ -434,12 +458,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 );
@@ -498,10 +524,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 );
@@ -609,32 +634,58 @@ VG_STATIC void async_world_postprocess_render( void *payload, u32 _size )
    glBufferSubData( GL_UNIFORM_BUFFER, 0, 
                     sizeof(struct ub_world_lighting), &world->ub_lighting );
 
-   /* yes we are using this as the entity begin thing. FIXME */
-   world->probabilities[ k_probability_curve_constant ] = 1.0f;
-   for( u32 i=0; i<mdl_arrcount(&world->ent_audio); i++ ){
-      ent_audio *audio = mdl_arritm(&world->ent_audio,i);
-      if( audio->flags & AUDIO_FLAG_AUTO_START ){
-         ent_call call;
-         call.data = NULL;
-         call.function = k_ent_function_trigger;
-         call.id = mdl_entity_id( k_ent_audio, i );
-         entity_call( world, &call );
+   /*
+    * Allocate cubemaps
+    */
+   for( u32 i=0; i<mdl_arrcount(&world->ent_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;
 
    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; i<mdl_arrcount(&world->meta.textures); i++ ){
       mdl_texture *tex = mdl_arritm( &world->meta.textures, i );
@@ -664,8 +715,9 @@ VG_STATIC void world_gen_load_surfaces(void)
    memset( errmat, 0, sizeof(struct world_surface) );
                        
    for( u32 i=0; i<mdl_arrcount(&world->meta.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;
    }
 }