chaos caused by async
authorhgn <hgodden00@gmail.com>
Mon, 24 Apr 2023 11:47:32 +0000 (12:47 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 24 Apr 2023 11:47:32 +0000 (12:47 +0100)
21 files changed:
blender_export.py
font.h
maps_src/mp_mtzero.mdl
maps_src/mp_spawn.mdl
menu.h
model.h
player_ragdoll.c
player_render.c
player_skate.c
render.h
rigidbody.h
scene.h
skaterift.c
skeleton.h
world.h
world_gate.h
world_gen.h
world_render.h
world_routes.h
world_sfd.h
world_water.h

index 62112041a8683776a10905957f505cfc65aba0c5..861d69249efbbfa640412cbe35b216dbbd42229c 100644 (file)
@@ -1321,6 +1321,8 @@ def sr_compile( collection ):
          # entity ignore mesh list
          #
          if ent_type == 'ent_traffic': continue
+         if ent_type == 'ent_font': continue
+         if ent_type == 'ent_font_variant': continue
          #--------------------------
 
          print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' )
diff --git a/font.h b/font.h
index eaba149b68d06bd7514fd9fc0b4d250ca06e3b2b..9b5a13b8b354aa18f8a4972f86749e86784a9192 100644 (file)
--- a/font.h
+++ b/font.h
@@ -31,32 +31,18 @@ VG_STATIC void font3d_load( font3d *font, const char *mdl_path, void *alloc )
    mdl_load_array( &font->mdl, &font->glyphs, "ent_glyph", alloc );
 
    vg_linear_clear( vg_mem.scratch );
-   mdl_load_mesh_block( &font->mdl, vg_mem.scratch );
 
    if( !mdl_arrcount( &font->mdl.textures ) )
-      vg_fatal_exit_loop( "No texture in font file" );
+      vg_fatal_error( "No texture in font file" );
 
    mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
    mdl_fread_pack_file( &font->mdl, &tex0->file, data );
 
-   vg_acquire_thread_sync();
-   {
-      /* upload mesh */
-      mesh_upload( &font->mesh, 
-                     font->mdl.verts.data, font->mdl.verts.count,
-                     font->mdl.indices.data, font->mdl.indices.count );
-
-      /* upload first texture */
-      font->texture = vg_tex2d_new();
-
-      vg_tex2d_set_error();
-      vg_tex2d_qoi( data, tex0->file.pack_size,
-                    mdl_pstr( &font->mdl, tex0->file.pstr_path ));
-      vg_tex2d_nearest();
-      vg_tex2d_repeat();
-   }
-   vg_release_thread_sync();
+   mdl_async_load_glmesh( &font->mdl, &font->mesh );
+   vg_tex2d_load_qoi_async( data, tex0->file.pack_size, 
+                            VG_TEX2D_NEAREST|VG_TEX2D_REPEAT|VG_TEX2D_NOMIP,
+                            &font->texture );
 
    mdl_close( &font->mdl );
 }
index f5de1f762a27ca73bc31b7880c92786b092c7cbc..0fb6064d7c7b40fe1aaea8378cd649ba03a23401 100644 (file)
Binary files a/maps_src/mp_mtzero.mdl and b/maps_src/mp_mtzero.mdl differ
index eb65fa960b085bdaca973320c93e27c4f950946e..48b5ecf5821042284b5c80c280e72ab889a3db41 100644 (file)
Binary files a/maps_src/mp_spawn.mdl and b/maps_src/mp_spawn.mdl differ
diff --git a/menu.h b/menu.h
index 1e2b8e7d422f607d432eb0873868c4710f39c722..483449038620f4f6350e6ef96a8f56def46ba31a 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -30,7 +30,7 @@ VG_STATIC int         menu_enabled(void){ return cl_menu; }
 
 VG_STATIC const char *playermodels[] = { "ch_new", "ch_jordan", "ch_outlaw" };
 
-vg_tex2d tex_menu = { .path = "textures/menu.qoi",.flags = VG_TEXTURE_NEAREST };
+GLuint tex_menu;
 
 VG_STATIC struct input_binding input_menu_h,
                                input_menu_v,
@@ -382,17 +382,15 @@ VG_STATIC void menu_init(void)
 
    mdl_open( &menu_model, "models/rs_menu.mdl", vg_mem.rtmemory );
    mdl_load_metadata_block( &menu_model, vg_mem.rtmemory );
-   mdl_load_mesh_block( &menu_model, vg_mem.scratch );
    mdl_load_array( &menu_model, &menu_markers, "ent_marker", vg_mem.rtmemory );
    //mdl_invert_uv_coordinates( &menu_model );
+   mdl_async_load_glmesh( &menu_model, &menu_glmesh );
    mdl_close( &menu_model );
 
-   vg_acquire_thread_sync();
-   {
-      mdl_unpack_glmesh( &menu_model, &menu_glmesh );
-      vg_tex2d_init( (vg_tex2d *[]){ &tex_menu }, 1 );
-   }
-   vg_release_thread_sync();
+   vg_tex2d_load_qoi_async_file( "textures/menu.qoi", 
+                                 VG_TEX2D_CLAMP|VG_TEX2D_NEAREST, 
+                                 &tex_menu );
+
 
    for( int i=0; i<vg_list_size(menu_buttons); i++ ){
       struct menu_button *btn = &menu_buttons[i];
@@ -400,7 +398,7 @@ VG_STATIC void menu_init(void)
 
       if( !btn->mesh ){
          vg_info( "info: %s\n", btn->name );
-         vg_fatal_exit_loop( "Menu programming error" );
+         vg_fatal_error( "Menu programming error" );
       }
    }
 
@@ -794,7 +792,9 @@ VG_STATIC void menu_render_fg( camera *cam )
    shader_model_menu_use();
    shader_model_menu_uColour( (v4f){ 1.0f,1.0f,1.0f,1.0f} );
    shader_model_menu_uTexMain( 1 );
-   vg_tex2d_bind( &tex_menu, 1 );
+
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, tex_menu );
 
    shader_model_menu_uPv( cam->mtx.pv );
    shader_model_menu_uPvmPrev( cam->mtx_prev.pv );
diff --git a/model.h b/model.h
index 81241987727e80b1acee1cad7482cb4948fa992d..8f90d128ad0a9637edb7a2624eed66ee1c2cc35b 100644 (file)
--- a/model.h
+++ b/model.h
@@ -233,7 +233,7 @@ VG_STATIC void mdl_load_fatal_corrupt( mdl_context *mdl )
 {
    fclose( mdl->file );
    vg_file_print_invalid( mdl->file );
-   vg_fatal_exit_loop( "Corrupt model" );
+   vg_fatal_error( "Corrupt model" );
 }
 
 /*
@@ -256,7 +256,7 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst )
 {
    if( !info->pack_size ){
       vg_warn( "path: %s\n", mdl_pstr( mdl, info->pstr_path ) );
-      vg_fatal_exit_loop( "Packed file is only a header; it is not packed" );
+      vg_fatal_error( "Packed file is only a header; it is not packed" );
    }
 
    fseek( mdl->file, mdl->pack_base_offset+info->pack_offset, SEEK_SET );
@@ -266,19 +266,28 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst )
       mdl_load_fatal_corrupt( mdl );
 }
 
-VG_STATIC void mdl_load_array_file( mdl_context *mdl, mdl_array_ptr *ptr,
-                                    mdl_array *arr, void *lin_alloc )
+/* TODO: Rename these */
+VG_STATIC 
+void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, 
+                                 void *buffer )
 {
    if( arr->item_count ){
-      u32 size = arr->item_size*arr->item_count;
-      ptr->data = vg_linear_alloc( lin_alloc, vg_align8(size) );
-
       fseek( mdl->file, arr->file_offset, SEEK_SET );
-      u64 l = fread( ptr->data, arr->item_size*arr->item_count, 1, mdl->file );
+      u64 l = fread( buffer, arr->item_size*arr->item_count, 1, mdl->file );
 
       if( l != 1 )
          mdl_load_fatal_corrupt( mdl );
    }
+}
+
+VG_STATIC void mdl_load_array_file( mdl_context *mdl, mdl_array_ptr *ptr,
+                                    mdl_array *arr, void *lin_alloc )
+{
+   if( arr->item_count ){
+      u32 size = arr->item_size*arr->item_count;
+      ptr->data = vg_linear_alloc( lin_alloc, vg_align8(size) );
+      mdl_load_array_file_buffer( mdl, arr, ptr->data );
+   }
    else
       ptr->data = NULL;
 
@@ -367,7 +376,7 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc )
 
    if( !mdl->file ){
       vg_error( "mdl_open('%s'): %s\n", path, strerror(errno) );
-      vg_fatal_exit_loop( "see above for details" );
+      vg_fatal_error( "see above for details" );
    }
 
    u64 l = fread( &mdl->info, sizeof(mdl_header), 1, mdl->file );
@@ -379,7 +388,7 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc )
       vg_warn( "  version: %u (current: %u)\n", mdl->info.version, 
                MDL_VERSION_NR );
 
-      vg_fatal_exit_loop( "Legacy model version incompatable" );
+      vg_fatal_error( "Legacy model version incompatable" );
    }
 
    mdl_load_array_file( mdl, &mdl->index, &mdl->info.index, lin_alloc );
@@ -514,38 +523,90 @@ VG_STATIC void mdl_draw_submesh( mdl_submesh *sm )
    mesh_drawn( sm->indice_start, sm->indice_count );
 }
 
-/* WARNING: Destructive! Only use this once and then discard the context. */
-VG_STATIC void mdl_unpack_glmesh( mdl_context *mdl, glmesh *mesh )
+VG_STATIC mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name )
 {
-   if( !mdl->submeshs.count )
-      vg_fatal_exit_loop( "Tried to unpack empty model file" );
+   for( u32 i=0; i<mdl_arrcount( &mdl->meshs ); i++ ){
+      mdl_mesh *mesh = mdl_arritm( &mdl->meshs, i );
+      if( !strcmp( name, mdl_pstr( mdl, mesh->pstr_name ))){
+         return mesh;
+      }
+   }
+   return NULL;
+}
 
-   mdl_submesh *sm = mdl_arritm( &mdl->submeshs, 0 );
-   u32 offset = sm->vertex_count;
+struct payload_glmesh_load{
+   mdl_vert *verts;
+   u32 *indices;
 
-   for( u32 i=1; i<mdl_arrcount( &mdl->submeshs ); i++ ){
-      mdl_submesh *sm = mdl_arritm( &mdl->submeshs, i );
-      u32 *indices    = mdl_arritm( &mdl->indices, sm->indice_start );
+   u32 vertex_count,
+       indice_count;
 
-      for( u32 j=0; j<sm->indice_count; j++ )
-         indices[j] += offset;
+   glmesh *mesh;
+};
 
-      offset += sm->vertex_count;
-   }
+VG_STATIC void async_mdl_load_glmesh( void *payload, u32 size )
+{
+   struct payload_glmesh_load *job = payload;
 
-   mesh_upload( mesh, mdl->verts.data, mdl->verts.count,
-                      mdl->indices.data, mdl->indices.count );
+   mesh_upload( job->mesh, job->verts, job->vertex_count,
+                           job->indices, job->indice_count );
 }
 
-VG_STATIC mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name )
+VG_STATIC void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh )
 {
-   for( u32 i=0; i<mdl_arrcount( &mdl->meshs ); i++ ){
-      mdl_mesh *mesh = mdl_arritm( &mdl->meshs, i );
-      if( !strcmp( name, mdl_pstr( mdl, mesh->pstr_name ))){
-         return mesh;
+   mdl_array *arr_vertices = mdl_find_array( mdl, "mdl_vert" );
+   mdl_array *arr_indices = mdl_find_array( mdl, "mdl_indice" );
+
+   if( arr_vertices && arr_indices ){
+      u32 size_verts   = vg_align8(mdl_query_array_size( arr_vertices )),
+          size_indices = vg_align8(mdl_query_array_size( arr_indices )),
+          size_hdr     = vg_align8(sizeof(struct payload_glmesh_load)),
+          total        = size_hdr + size_verts + size_indices;
+
+      vg_async_item *call = vg_async_alloc( total );
+      struct payload_glmesh_load *job = call->payload;
+
+      u8 *payload = call->payload;
+
+      job->mesh = mesh;
+      job->verts = (void*)(payload + size_hdr);
+      job->indices = (void*)(payload + size_hdr + size_verts);
+      job->vertex_count = arr_vertices->item_count;
+      job->indice_count = arr_indices->item_count;
+
+      mdl_load_array_file_buffer( mdl, arr_vertices, job->verts );
+      mdl_load_array_file_buffer( mdl, arr_indices, job->indices );
+
+      /*
+       * Unpack the indices (if there are meshes)
+       * ---------------------------------------------------------
+       */
+
+      if( mdl_arrcount( &mdl->submeshs ) ){
+         mdl_submesh *sm = mdl_arritm( &mdl->submeshs, 0 );
+         u32 offset = sm->vertex_count;
+
+         for( u32 i=1; i<mdl_arrcount( &mdl->submeshs ); i++ ){
+            mdl_submesh *sm = mdl_arritm( &mdl->submeshs, i );
+            u32 *indices    = job->indices + sm->indice_start;
+
+            for( u32 j=0; j<sm->indice_count; j++ )
+               indices[j] += offset;
+
+            offset += sm->vertex_count;
+         }
       }
+
+      /* 
+       * Dispatch 
+       * -------------------------
+       */
+
+      vg_async_dispatch( call, async_mdl_load_glmesh );
+   }
+   else{
+      vg_fatal_error( "no vertex/indice data\n" );
    }
-   return NULL;
 }
  
 #endif
index a7e3e7569dae27d7eb413ade9c91a85b96cc2f1f..a1733b765289449b93e62b2aa1b78ffcea20ec81 100644 (file)
@@ -66,7 +66,7 @@ VG_STATIC void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
    }
    else{
       vg_warn( "type: %u\n", bone->collider );
-      vg_fatal_exit_loop( "Invalid bone collider type" );
+      vg_fatal_error( "Invalid bone collider type" );
    }
 
    m4x3_invert_affine( rp->collider_mtx, rp->inv_collider_mtx );
@@ -89,7 +89,7 @@ VG_STATIC u32 ragdoll_bone_parent( struct player_ragdoll *rd,
       if( rd->parts[ j ].bone_id == bone_id )
          return j;
 
-   vg_fatal_exit_loop( "Referenced parent bone does not have a rigidbody" );
+   vg_fatal_error( "Referenced parent bone does not have a rigidbody" );
    return 0;
 }
 
@@ -117,7 +117,7 @@ VG_STATIC void player_setup_ragdoll_from_avatar( struct player_ragdoll *rd,
          continue;
 
       if( rd->part_count > vg_list_size(rd->parts) )
-         vg_fatal_exit_loop( "Playermodel has too many colliders" );
+         vg_fatal_error( "Playermodel has too many colliders" );
 
       struct ragdoll_part *rp = &rd->parts[ rd->part_count ++ ];
       rp->bone_id = i;
index ab8942207366aa30d30a435e009b997d0c5c62d5..df0dd6b1d3717e12b84529aecaf7edb90a38dc1e 100644 (file)
@@ -43,30 +43,19 @@ VG_STATIC void player_model_load( struct player_model *mdl, const char *path )
    mdl_context ctx;
    mdl_open( &ctx, path, vg_mem.scratch );
    mdl_load_metadata_block( &ctx, vg_mem.scratch );
-   mdl_load_mesh_block( &ctx, vg_mem.scratch );
 
    if( !mdl_arrcount( &ctx.textures ) )
-      vg_fatal_exit_loop( "No texture in player model" );
+      vg_fatal_error( "No texture in player model" );
 
    mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
    mdl_fread_pack_file( &ctx, &tex0->file, data );
 
-   vg_acquire_thread_sync();
-   {
-      mdl_unpack_glmesh( &ctx, &mdl->mesh );
-
-      /* upload first texture */
-      mdl->texture = vg_tex2d_new();
-
-      vg_tex2d_set_error();
-      vg_tex2d_qoi( data, tex0->file.pack_size,
-                    mdl_pstr( &ctx, tex0->file.pstr_path ));
-      vg_tex2d_nearest();
-      vg_tex2d_clamp();
-   }
-   vg_release_thread_sync();
+   vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
+                            VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
+                            &mdl->texture );
 
+   mdl_async_load_glmesh( &ctx, &mdl->mesh );
    mdl_close( &ctx );
 }
 
@@ -77,33 +66,22 @@ VG_STATIC void player_board_load( struct player_board *mdl, const char *path )
    mdl_context ctx;
    mdl_open( &ctx, path, vg_mem.scratch );
    mdl_load_metadata_block( &ctx, vg_mem.scratch );
-   mdl_load_mesh_block( &ctx, vg_mem.scratch );
 
    mdl_array_ptr markers;
    mdl_load_array( &ctx, &markers, "ent_marker", vg_mem.scratch );
 
    if( !mdl_arrcount( &ctx.textures ) )
-      vg_fatal_exit_loop( "No texture in board model" );
+      vg_fatal_error( "No texture in board model" );
 
    mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
    mdl_fread_pack_file( &ctx, &tex0->file, data );
 
-   vg_acquire_thread_sync();
-   {
-      mdl_unpack_glmesh( &ctx, &mdl->mesh );
-
-      /* upload first texture */
-      mdl->texture = vg_tex2d_new();
-
-      vg_tex2d_set_error();
-      vg_tex2d_qoi( data, tex0->file.pack_size,
-                    mdl_pstr( &ctx, tex0->file.pstr_path ));
-      vg_tex2d_nearest();
-      vg_tex2d_clamp();
-   }
-   vg_release_thread_sync();
+   vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
+                            VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
+                            &mdl->texture );
 
+   mdl_async_load_glmesh( &ctx, &mdl->mesh );
    mdl_close( &ctx );
 
    for( int i=0; i<4; i++ )
index 7da514f7609f0639448d54ee899051c2f90ca345..7029edc774f1fe9b6bdb722d7b0a31141d45a86f 100644 (file)
@@ -124,7 +124,7 @@ VG_STATIC int skate_grind_scansq( player_instance *player,
    v3_normalize( support_axis );
    
    while( bh_next( world->geo_bh, &it, box, &idx ) ){
-      u32 *ptri = &world->scene_geo->arrindices[ idx*3 ];
+      u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
       v3f tri[3];
 
       struct world_surface *surf = world_tri_index_surface(world,ptri[0]);
@@ -132,7 +132,7 @@ VG_STATIC int skate_grind_scansq( player_instance *player,
          continue;
 
       for( int j=0; j<3; j++ )
-         v3_copy( world->scene_geo->arrvertices[ptri[j]].co, tri[j] );
+         v3_copy( world->scene_geo.arrvertices[ptri[j]].co, tri[j] );
 
       for( int j=0; j<3; j++ ){
          int i0 = j,
@@ -519,7 +519,7 @@ void player__approximate_best_trajectory( player_instance *player )
             v3_copy( co, inf->log[ inf->log_length ++ ] ); 
 
             v3_copy( n, inf->n );
-            u32 *tri = &trace_world->scene_geo->arrindices[ idx*3 ];
+            u32 *tri = &trace_world->scene_geo.arrindices[ idx*3 ];
             struct world_surface *surf = 
                world_tri_index_surface( trace_world, tri[0] );
 
@@ -1163,7 +1163,7 @@ VG_STATIC void player__skate_post_update( player_instance *player )
       jump_info *jump = &s->possible_jumps[i];
 
       if( jump->log_length == 0 ){
-         vg_fatal_exit_loop( "assert: jump->log_length == 0\n" );
+         vg_fatal_error( "assert: jump->log_length == 0\n" );
       }
       
       for( int j=0; j<jump->log_length - 1; j ++ ){
@@ -1404,11 +1404,11 @@ int skate_compute_surface_alignment( player_instance *player,
 
       if( idx != -1 )
       {
-         u32 *tri = &world->scene_geo->arrindices[ idx * 3 ];
+         u32 *tri = &world->scene_geo.arrindices[ idx * 3 ];
          v3f verts[3];
 
          for( int j=0; j<3; j++ )
-            v3_copy( world->scene_geo->arrvertices[ tri[j] ].co, verts[j] );
+            v3_copy( world->scene_geo.arrvertices[ tri[j] ].co, verts[j] );
 
          v3f vert0, vert1, n;
          v3_sub( verts[1], verts[0], vert0 );
@@ -1951,7 +1951,7 @@ VG_STATIC enum skate_activity skate_availible_grind( player_instance *player )
    struct player_skate *s = &player->_skate;
 
    if( s->grind_cooldown > 100 ){
-      vg_fatal_exit_loop( "wth!\n" );
+      vg_fatal_error( "wth!\n" );
    }
 
    /* debounces this state manager a little bit */
index a4005ddbcec76028b77fd873c6b9b8dca479a7b1..440af479f605195d0c763d27e88ef55e631ec1b3 100644 (file)
--- a/render.h
+++ b/render.h
@@ -244,7 +244,7 @@ VG_STATIC void render_fb_bind_texture( framebuffer *fb,
    if( (at->purpose != k_framebuffer_attachment_type_texture) &&
        (at->purpose != k_framebuffer_attachment_type_texture_depth) )
    {
-      vg_fatal_exit_loop( "illegal operation: bind non-texture framebuffer"
+      vg_fatal_error( "illegal operation: bind non-texture framebuffer"
                           " attachment to texture slot" );
    }
 
@@ -480,7 +480,7 @@ VG_STATIC void render_fb_allocate( struct framebuffer *fb )
          vg_error( "  status: Generic Error" );
 
       vg_info( "}\n" );
-      vg_fatal_exit_loop( "Incomplete framebuffer (see logs)" );
+      vg_fatal_error( "Incomplete framebuffer (see logs)" );
    }
 }
 
@@ -503,9 +503,16 @@ VG_STATIC void render_fb_resize(void)
 
 VG_STATIC int render_framebuffer_control( int argc, char const *argv[] );
 VG_STATIC void render_framebuffer_poll( int argc, char const *argv[] );
-VG_STATIC void render_init_fs_quad(void)
+
+VG_STATIC void async_render_init( void *payload, u32 size )
 {
-   vg_info( "[render] Allocate quad\n" );
+   /* 
+    * Complete Framebuffers
+    */
+   for( int i=0; i<vg_list_size(framebuffers); i++ ){
+      struct framebuffer *fb = &framebuffers[i];
+      render_fb_allocate( fb );
+   }
 
    float quad[] = { 
       0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f,
@@ -552,6 +559,9 @@ VG_STATIC void render_init_fs_quad(void)
    glEnableVertexAttribArray( 0 );
 
    VG_CHECK_GL_ERR();
+
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+   gpipeline.ready = 1;
 }
 
 VG_STATIC void render_init(void)
@@ -560,23 +570,8 @@ VG_STATIC void render_init(void)
    shader_blitblur_register();
    shader_blitcolour_register();
 
-   vg_acquire_thread_sync();
-   {
-      /* 
-       * Complete Framebuffers
-       */
-      for( int i=0; i<vg_list_size(framebuffers); i++ ){
-         struct framebuffer *fb = &framebuffers[i];
-         render_fb_allocate( fb );
-      }
-
-      render_init_fs_quad();
-
-      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-      gpipeline.ready = 1;
-   }
-
-   vg_release_thread_sync();
+   vg_async_item *call = vg_async_alloc(0);
+   vg_async_dispatch( call, async_render_init );
 }
 
 /*
index 3d2f4107ca962f433e4f85d46493c2911fc5e816..efce416487fc164d2a2772d8c4a44d499fc2d989 100644 (file)
@@ -466,7 +466,7 @@ VG_STATIC void rb_iter( rigidbody *rb )
        !vg_validf( rb->v[1] ) ||
        !vg_validf( rb->v[2] ) )
    {
-      vg_fatal_exit_loop( "NaN velocity" );
+      vg_fatal_error( "NaN velocity" );
    }
 
    v3f gravity = { 0.0f, -9.8f, 0.0f };
@@ -1231,7 +1231,7 @@ VG_STATIC int rb_sphere__triangle( m4x3f mtxA, rb_sphere *b,
 VG_STATIC int rb_sphere__scene( m4x3f mtxA, rb_sphere *b,
                                 m4x3f mtxB, rb_scene *s, rb_ct *buf )
 {
-   scene *sc = s->bh_scene->user;
+   scene_context *sc = s->bh_scene->user;
 
    bh_iter it;
    bh_iter_init( 0, &it );
@@ -1273,7 +1273,7 @@ VG_STATIC int rb_box__scene( m4x3f mtxA, boxf bbx,
                              m4x3f mtxB, rb_scene *s, rb_ct *buf )
 {
 #if 1
-   scene *sc = s->bh_scene->user;
+   scene_context *sc = s->bh_scene->user;
    v3f tri[3];
 
    v3f extent, center;
@@ -1526,7 +1526,7 @@ VG_STATIC int rb_capsule__scene( m4x3f mtxA, rb_capsule *c,
    v3_sub( mtxA[3], (v3f){ c->height, c->height, c->height }, bbx[0] );
    v3_add( mtxA[3], (v3f){ c->height, c->height, c->height }, bbx[1] );
    
-   scene *sc = s->bh_scene->user;
+   scene_context *sc = s->bh_scene->user;
    
    while( bh_next( s->bh_scene, &it, bbx, &idx ) ){
       u32 *ptri = &sc->arrindices[ idx*3 ];
diff --git a/scene.h b/scene.h
index aeecd4e1e3d4df1e7a179dd1701efe66a2159e38..027f4bded5c3bd6b8dc9f2b9f1ed038a15b3ab2b 100644 (file)
--- a/scene.h
+++ b/scene.h
@@ -5,7 +5,7 @@
 #include "model.h"
 #include "bvh.h"
 
-typedef struct scene      scene;
+typedef struct scene_context scene_context;
 typedef struct scene_vert scene_vert;
 
 #pragma pack(push,1)
@@ -22,10 +22,15 @@ struct scene_vert
 
 #pragma pack(pop)
 
-struct scene
+/* 
+ * 1. this should probably be a CONTEXT based approach unlike this mess.
+ * take a bit of the mdl_context ideas and redo this header. its messed up
+ * pretty bad right now.
+ */
+
+struct scene_context
 {
    scene_vert *arrvertices;
-
    u32 *arrindices;
 
    u32 vertex_count, indice_count,
@@ -35,29 +40,36 @@ struct scene
    mdl_submesh submesh;
 };
 
-/* Initialize a scene description with bounded buffers */
-VG_STATIC scene *scene_init( void *lin_alloc, u32 max_verts, u32 max_indices )
+VG_STATIC u32 scene_mem_required( scene_context *ctx )
 {
-   u32 vertex_length = max_verts   * sizeof(scene_vert),
-       index_length  = max_indices * sizeof(u32),
-       tot_size = sizeof(scene) + vertex_length + index_length;
+   u32 vertex_length = vg_align8(ctx->max_vertices * sizeof(scene_vert)),
+       index_length  = vg_align8(ctx->max_indices  * sizeof(u32));
 
-   scene *pscene = vg_linear_alloc( lin_alloc, tot_size );
+   return vertex_length + index_length;
+}
 
-   pscene->arrvertices = (scene_vert *)(pscene+1);
-   pscene->arrindices  = (u32 *)( pscene->arrvertices + max_verts );
+VG_STATIC 
+void scene_init( scene_context *ctx, u32 max_vertices, u32 max_indices )
+{
+   ctx->vertex_count = 0;
+   ctx->indice_count = 0;
+   ctx->max_vertices = max_vertices;
+   ctx->max_indices = max_indices;
+   ctx->arrindices = NULL; /* must be filled out by user */
+   ctx->arrvertices = NULL;
 
-   pscene->vertex_count = 0;
-   pscene->indice_count = 0;
-   pscene->max_vertices = max_verts;
-   pscene->max_indices  = max_indices;
+   memset( &ctx->submesh, 0, sizeof(mdl_submesh) );
 
-   memset( &pscene->submesh, 0, sizeof(mdl_submesh) );
+   v3_fill( ctx->bbx[0],  999999.9f );
+   v3_fill( ctx->bbx[1], -999999.9f );
+}
 
-   v3_fill( pscene->bbx[0],  999999.9f );
-   v3_fill( pscene->bbx[1], -999999.9f );
+void scene_supply_buffer( scene_context *ctx, void *buffer )
+{
+   u32 vertex_length = vg_align8( ctx->max_vertices * sizeof(scene_vert) );
 
-   return pscene;
+   ctx->arrvertices = buffer;
+   ctx->arrindices  = (u32*)(((u8*)buffer) + vertex_length);
 }
 
 VG_STATIC void scene_vert_pack_norm( scene_vert *vert, v3f norm )
@@ -75,38 +87,32 @@ VG_STATIC void scene_vert_pack_norm( scene_vert *vert, v3f norm )
 /* 
  * Append a model into the scene with a given transform
  */
-VG_STATIC void scene_add_mdl_submesh( scene *pscene, mdl_context *mdl, 
+VG_STATIC void scene_add_mdl_submesh( scene_context *ctx, mdl_context *mdl, 
                                       mdl_submesh *sm, m4x3f transform )
 {
-   if( pscene->vertex_count + sm->vertex_count > pscene->max_vertices ){
-      vg_error( "%u(current) + %u > %u\n", pscene->vertex_count,
-                                           sm->vertex_count,
-                                           pscene->max_vertices );
-
-      vg_warn( "%p ... %p\n", pscene, sm );
-      vg_fatal_exit_loop( "Scene vertex buffer overflow" );
+   if( ctx->vertex_count + sm->vertex_count > ctx->max_vertices ){
+      vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
+                        ctx->vertex_count + sm->vertex_count, 
+                        ctx->max_vertices );
    }
 
-   if( pscene->indice_count + sm->indice_count > pscene->max_indices ){
-      vg_error( "%u(current) + %u > %u\n", pscene->indice_count,
-                                           sm->indice_count,
-                                           pscene->max_indices );
-      vg_warn( "%p ... %p\n", pscene, sm );
-
-      vg_fatal_exit_loop( "Scene index buffer overflow" );
+   if( ctx->indice_count + sm->indice_count > ctx->max_indices ){
+      vg_fatal_error( "Scene index buffer overflow (%u exceeds %u)\n",
+                        ctx->indice_count + sm->indice_count,
+                        ctx->max_indices );
    }
 
    mdl_vert   *src_verts = mdl_arritm( &mdl->verts, sm->vertex_start );
-   scene_vert *dst_verts = &pscene->arrvertices[ pscene->vertex_count ];
+   scene_vert *dst_verts = &ctx->arrvertices[ ctx->vertex_count ];
 
    u32 *src_indices    =  mdl_arritm( &mdl->indices, sm->indice_start ),
-       *dst_indices    = &pscene->arrindices[ pscene->indice_count ];
+       *dst_indices    = &ctx->arrindices[ ctx->indice_count ];
    
    /* Transform and place vertices */
    boxf bbxnew;
    box_copy( sm->bbx, bbxnew );
    m4x3_transform_aabb( transform, bbxnew );
-   box_concat( pscene->bbx, bbxnew );
+   box_concat( ctx->bbx, bbxnew );
 
    m3x3f normal_matrix;
    m3x3_copy( transform, normal_matrix );
@@ -128,103 +134,67 @@ VG_STATIC void scene_add_mdl_submesh( scene *pscene, mdl_context *mdl,
    }
 
    for( u32 i=0; i<sm->indice_count; i++ )
-      dst_indices[i] = src_indices[i] + pscene->vertex_count;
+      dst_indices[i] = src_indices[i] + ctx->vertex_count;
 
-   pscene->vertex_count += sm->vertex_count;
-   pscene->indice_count += sm->indice_count;
+   ctx->vertex_count += sm->vertex_count;
+   ctx->indice_count += sm->indice_count;
 }
 
 /*
  * One by one adders for simplified access (mostly procedural stuff)
  */
-VG_STATIC void scene_push_tri( scene *pscene, u32 tri[3] )
+VG_STATIC void scene_push_tri( scene_context *ctx, u32 tri[3] )
 {
-   if( pscene->indice_count + 3 > pscene->max_indices )
-      vg_fatal_exit_loop( "Scene vertex buffer overflow" );
+   if( ctx->indice_count + 3 > ctx->max_indices )
+      vg_fatal_error( "Scene indice buffer overflow (%u exceeds %u)\n",
+                        ctx->indice_count+3, ctx->max_indices );
 
-   u32 *dst = &pscene->arrindices[ pscene->indice_count ];
+   u32 *dst = &ctx->arrindices[ ctx->indice_count ];
 
    dst[0] = tri[0];
    dst[1] = tri[1];
    dst[2] = tri[2];
 
-   pscene->indice_count += 3;
+   ctx->indice_count += 3;
 }
 
-VG_STATIC void scene_push_vert( scene *pscene, scene_vert *v )
+VG_STATIC void scene_push_vert( scene_context *ctx, scene_vert *v )
 {
-   if( pscene->vertex_count + 1 > pscene->max_vertices )
-      vg_fatal_exit_loop( "Scene vertex buffer overflow" );
+   if( ctx->vertex_count + 1 > ctx->max_vertices )
+      vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
+                        ctx->vertex_count+1, ctx->max_vertices );
 
-   scene_vert *dst = &pscene->arrvertices[ pscene->vertex_count ];
+   scene_vert *dst = &ctx->arrvertices[ ctx->vertex_count ];
    *dst = *v;
 
-   pscene->vertex_count ++;
+   ctx->vertex_count ++;
 }
 
-VG_STATIC void scene_copy_slice( scene *pscene, mdl_submesh *sm )
+VG_STATIC void scene_copy_slice( scene_context *ctx, mdl_submesh *sm )
 {
-   sm->indice_start = pscene->submesh.indice_start;
-   sm->indice_count = pscene->indice_count - sm->indice_start;
+   sm->indice_start = ctx->submesh.indice_start;
+   sm->indice_count = ctx->indice_count - sm->indice_start;
 
-   sm->vertex_start = pscene->submesh.vertex_start;
-   sm->vertex_count = pscene->vertex_count - sm->vertex_start;
+   sm->vertex_start = ctx->submesh.vertex_start;
+   sm->vertex_count = ctx->vertex_count - sm->vertex_start;
    
-   pscene->submesh.indice_start = pscene->indice_count;
-   pscene->submesh.vertex_start = pscene->vertex_count;
+   ctx->submesh.indice_start = ctx->indice_count;
+   ctx->submesh.vertex_start = ctx->vertex_count;
 }
 
-/* finalization: tightly pack data */
-__attribute__((warn_unused_result))
-VG_STATIC scene *scene_fix( void *lin_alloc, scene *pscene )
-{
-   /* FIXME: Why is this disabled? */
-
-   u32 vertex_count  = pscene->vertex_count,
-       indice_count  = pscene->indice_count,
-       vertex_length = vertex_count * sizeof(scene_vert),
-       index_length  = indice_count * sizeof(u32),
-       tot_size      = vg_align8(sizeof(scene) + vertex_length + index_length);
-
-   /* copy down index data */
-   void *dst_indices = pscene->arrvertices + vertex_count;
-   memmove( dst_indices, pscene->arrindices, index_length );
-
-   /* realloc */
-   pscene = vg_linear_resize( lin_alloc, pscene, tot_size );
-
-   pscene->arrvertices = (scene_vert *)(pscene+1);
-   pscene->arrindices  = (u32 *)(pscene->arrvertices+vertex_count);
-   pscene->max_vertices = vertex_count;
-   pscene->max_indices  = indice_count;
-
-   return pscene;
-}
+struct scene_upload_info{
+   scene_context *ctx;
+   glmesh *mesh;
+};
 
-#if 0
-/* finalization: delete any offline buffers and reduce size */
-__attribute__((warn_unused_result))
-VG_STATIC scene *scene_free_offline_buffers( void *lin_alloc, scene *pscene )
+VG_STATIC void async_scene_upload( void *payload, u32 size )
 {
-   u32 tot_size = sizeof(scene);
-
-   scene    *src_scene   = pscene;
-   mdl_vert *src_verts   = pscene->arrvertices;
-   u32      *src_indices = pscene->arrindices;
-
-   scene *dst_scene = vg_linear_resize( lin_alloc, pscene, tot_size );
-   memcpy( dst_scene, src_scene, sizeof(scene) );
-
-   dst_scene->arrindices = NULL;
-   dst_scene->arrvertices = NULL;
+   struct scene_upload_info *info = payload;
 
-   return dst_scene;
-}
-#endif
-
-VG_STATIC void scene_upload( scene *pscene, glmesh *mesh )
-{
    //assert( mesh->loaded == 0 );
+   
+   glmesh *mesh = info->mesh;
+   scene_context *ctx = info->ctx;
 
    glGenVertexArrays( 1, &mesh->vao );
    glGenBuffers( 1, &mesh->vbo );
@@ -234,13 +204,13 @@ VG_STATIC void scene_upload( scene *pscene, glmesh *mesh )
    size_t stride = sizeof(scene_vert);
 
    glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
-   glBufferData( GL_ARRAY_BUFFER, pscene->vertex_count*stride, 
-                 pscene->arrvertices, GL_STATIC_DRAW );
+   glBufferData( GL_ARRAY_BUFFER, ctx->vertex_count*stride, 
+                 ctx->arrvertices, GL_STATIC_DRAW );
 
    glBindVertexArray( mesh->vao );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
-   glBufferData( GL_ELEMENT_ARRAY_BUFFER, pscene->indice_count*sizeof(u32),
-                 pscene->arrindices, GL_STATIC_DRAW );
+   glBufferData( GL_ELEMENT_ARRAY_BUFFER, ctx->indice_count*sizeof(u32),
+                 ctx->arrindices, GL_STATIC_DRAW );
    
    /* 0: coordinates */
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0 );
@@ -256,30 +226,56 @@ VG_STATIC void scene_upload( scene *pscene, glmesh *mesh )
          stride, (void *)offsetof(scene_vert, uv) );
    glEnableVertexAttribArray( 2 );
 
-#if 0
-   /* 3: light cluster */
-   glVertexAttribIPointer( 3, 4, GL_UNSIGNED_SHORT,
-         stride, (void *)offsetof(scene_vert, lights) );
-   glEnableVertexAttribArray( 3 );
-#endif
-
    VG_CHECK_GL_ERR();
 
-   mesh->indice_count = pscene->indice_count;
+   mesh->indice_count = ctx->indice_count;
    mesh->loaded = 1;
 
    vg_info( "Scene upload ( XYZ_f32 UV_f32 XYZW_i8 )[ u32 ]\n" );
-   vg_info( "   indices:%u\n", pscene->indice_count );
-   vg_info( "   verts:%u\n",   pscene->vertex_count );
+   vg_info( "   indices:%u\n", ctx->indice_count );
+   vg_info( "   verts:%u\n",   ctx->vertex_count );
 }
 
+VG_STATIC void scene_upload_async( scene_context *ctx, glmesh *mesh )
+{
+   vg_async_item *call = vg_async_alloc( sizeof(struct scene_upload_info) );
+
+   struct scene_upload_info *info = call->payload;
+   info->mesh = mesh;
+   info->ctx = ctx;
+
+   vg_async_dispatch( call, async_scene_upload );
+}
+
+VG_STATIC
+vg_async_item *scene_alloc_async( scene_context *scene, glmesh *mesh,
+                                  u32 max_vertices, u32 max_indices )
+{
+   scene_init( scene, max_vertices, max_indices );
+   u32 buf_size = scene_mem_required( scene );
+
+   u32 hdr_size = vg_align8(sizeof(struct scene_upload_info));
+   vg_async_item *call = vg_async_alloc( hdr_size + buf_size );
+
+   struct scene_upload_info *info = call->payload;
+
+   info->mesh = mesh;
+   info->ctx = scene;
+
+   void *buffer = ((u8*)call->payload)+hdr_size;
+   scene_supply_buffer( scene, buffer );
+
+   return call;
+}
+
+
 /*
  * BVH implementation
  */
 
 VG_STATIC void scene_bh_expand_bound( void *user, boxf bound, u32 item_index )
 {
-   scene *s = user;
+   scene_context *s = user;
    scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
               *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
               *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
@@ -291,7 +287,7 @@ VG_STATIC void scene_bh_expand_bound( void *user, boxf bound, u32 item_index )
 
 VG_STATIC float scene_bh_centroid( void *user, u32 item_index, int axis )
 {
-   scene *s = user;
+   scene_context *s = user;
    scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
               *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
               *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
@@ -314,7 +310,7 @@ VG_STATIC float scene_bh_centroid( void *user, u32 item_index, int axis )
 
 VG_STATIC void scene_bh_swap( void *user, u32 ia, u32 ib )
 {
-   scene *s = user;
+   scene_context *s = user;
 
    u32 *ti = &s->arrindices[ia*3];
    u32 *tj = &s->arrindices[ib*3];
@@ -335,7 +331,7 @@ VG_STATIC void scene_bh_swap( void *user, u32 ia, u32 ib )
 
 VG_STATIC void scene_bh_debug( void *user, u32 item_index )
 {
-   scene *s = user;
+   scene_context *s = user;
    u32 idx = item_index*3;
    scene_vert *pa = &s->arrvertices[ s->arrindices[ idx+0 ] ],
               *pb = &s->arrvertices[ s->arrindices[ idx+1 ] ],
@@ -349,7 +345,7 @@ VG_STATIC void scene_bh_debug( void *user, u32 item_index )
 VG_STATIC int scene_bh_ray( void *user, u32 index, v3f co, 
                             v3f dir, ray_hit *hit )
 {
-   scene *s = user;
+   scene_context *s = user;
    v3f positions[3];
    
    u32 *tri = &s->arrindices[ index*3 ];
@@ -358,10 +354,8 @@ VG_STATIC int scene_bh_ray( void *user, u32 index, v3f co,
       v3_copy( s->arrvertices[tri[i]].co, positions[i] );
    
    float t;
-   if(ray_tri( positions, co, dir, &t ))
-   {
-      if( t < hit->dist )
-      {
+   if(ray_tri( positions, co, dir, &t )){
+      if( t < hit->dist ){
          hit->dist = t;
          hit->tri = tri;
          return 1;
@@ -373,7 +367,7 @@ VG_STATIC int scene_bh_ray( void *user, u32 index, v3f co,
 
 VG_STATIC void scene_bh_closest( void *user, u32 index, v3f point, v3f closest )
 {
-   scene *s = user;
+   scene_context *s = user;
 
    v3f positions[3];
    u32 *tri = &s->arrindices[ index*3 ];
@@ -396,13 +390,12 @@ VG_STATIC bh_system bh_system_scene =
 /*
  * An extra step is added onto the end to calculate the hit normal
  */
-VG_STATIC int scene_raycast( scene *s, bh_tree *bh, 
+VG_STATIC int scene_raycast( scene_context *s, bh_tree *bh, 
                              v3f co, v3f dir, ray_hit *hit )
 {
    int count = bh_ray( bh, co, dir, hit );
 
-   if( count )
-   {
+   if( count ){
       v3f v0, v1;
       
       float *pa = s->arrvertices[hit->tri[0]].co,
@@ -419,7 +412,7 @@ VG_STATIC int scene_raycast( scene *s, bh_tree *bh,
    return count;
 }
 
-VG_STATIC bh_tree *scene_bh_create( void *lin_alloc, scene *s )
+VG_STATIC bh_tree *scene_bh_create( void *lin_alloc, scene_context *s )
 {
    u32 triangle_count = s->indice_count / 3;
    return bh_create( lin_alloc, &bh_system_scene, s, triangle_count, 2 );
index d943c2d07a13c55831527a4954d3031031dc913d..54e5feb5d202c3f3849be04f1a67cec2a42a4dbb 100644 (file)
@@ -25,6 +25,7 @@
 VG_STATIC struct player_avatar localplayer_avatar;
 VG_STATIC struct player_model  localplayer_models[3];
 VG_STATIC struct player_board  localplayer_boards[1];
+VG_STATIC int skaterift_status = 0;
 
 #include "network.h"
 #include "menu.h"
@@ -103,6 +104,14 @@ void temp_update_playermodel(void){
    player__use_model( &localplayer, &localplayer_models[cl_playermdl_id] );
 }
 
+VG_STATIC void async_skaterift_complete( void *payload, u32 size )
+{
+   skaterift_status = 1;
+
+   localplayer.viewable_world = get_active_world();
+   localplayer_cmd_respawn( 1, (const char *[]){ "start" } );
+}
+
 VG_STATIC void vg_load(void)
 {
    vg_loader_step( render_init, NULL );
@@ -150,12 +159,9 @@ VG_STATIC void vg_load(void)
 #endif
 
    vg_console_load_autos();
-}
 
-VG_STATIC void vg_start(void)
-{
-   localplayer.viewable_world = get_active_world();
-   localplayer_cmd_respawn( 1, (const char *[]){ "start" } );
+   vg_async_item *call = vg_async_alloc(0);
+   vg_async_dispatch( call, async_skaterift_complete );
 }
 
 VG_STATIC void draw_origin_axis(void)
@@ -169,7 +175,7 @@ VG_STATIC void vg_update(void)
 {
    steam_update();
 
-   if( vg.is_loaded ){
+   if( skaterift_status == 1 ){
       draw_origin_axis();
       network_update();
       
@@ -182,7 +188,7 @@ VG_STATIC void vg_update(void)
 
 VG_STATIC void vg_update_fixed(void)
 {
-   if( vg.is_loaded ){
+   if( skaterift_status == 1 ){
       world_routes_fixedupdate( get_active_world() );
 
       player__update( &localplayer );
@@ -215,7 +221,7 @@ VG_STATIC void vg_update_fixed(void)
 
 VG_STATIC void vg_update_post(void)
 {
-   if( vg.is_loaded ){
+   if( skaterift_status == 1 ){
       player__post_update( &localplayer );
 
       float dist;
@@ -428,6 +434,11 @@ VG_STATIC void render_main_game(void)
 
 VG_STATIC void vg_render(void)
 {
+   if( skaterift_status == 0 ){
+      _vg_loader_render();
+      return;
+   }
+
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
 
    glViewport( 0,0, vg.window_x, vg.window_y );
@@ -449,6 +460,10 @@ VG_STATIC void vg_render(void)
 
 VG_STATIC void vg_ui(void)
 {
+   if( skaterift_status == 0 ){
+      return;
+   }
+
 #if 0
    player__im_gui( &localplayer );
 #endif
index 2595cda8c6476254700f6da43eac496dd4ffbd24..79e80171b2acc49935c11ac5ad973122b3bf54e1 100644 (file)
@@ -61,7 +61,7 @@ VG_STATIC u32 skeleton_bone_id( struct skeleton *skele, const char *name )
    }
 
    vg_error( "skeleton_bone_id( *, \"%s\" );\n", name );
-   vg_fatal_exit_loop( "Bone does not exist\n" );
+   vg_fatal_error( "Bone does not exist\n" );
 
    return 0;
 }
@@ -403,7 +403,7 @@ VG_STATIC struct skeleton_anim *skeleton_get_anim( struct skeleton *skele,
    }
 
    vg_error( "skeleton_get_anim( *, \"%s\" )\n", name );
-   vg_fatal_exit_loop( "Invalid animation name\n" );
+   vg_fatal_error( "Invalid animation name\n" );
 
    return NULL;
 }
@@ -441,7 +441,7 @@ VG_STATIC void skeleton_alloc_from( struct skeleton *skele,
 
 VG_STATIC void skeleton_fatal_err(void)
 {
-   vg_fatal_exit_loop( "Skeleton setup failed" );
+   vg_fatal_error( "Skeleton setup failed" );
 }
 
 /* Setup an animated skeleton from model. mdl's metadata should stick around */
diff --git a/world.h b/world.h
index 5318f8e326408c6d75624b2ed4ab8f7b38453328..7084ff17334e7b9195abfc2ff584576bccefcbc1 100644 (file)
--- a/world.h
+++ b/world.h
@@ -174,9 +174,9 @@ struct world_instance {
     */
 
    /* world geometry */
-   scene *scene_geo, 
-         *scene_no_collide,
-         *scene_lines;
+   scene_context scene_geo,
+                 scene_no_collide,
+                 scene_lines;
 
    /* spacial mappings */
    bh_tree *audio_bh,
@@ -221,6 +221,7 @@ struct world_global{
       glmesh mesh_base, mesh_display;
       mdl_submesh sm_base;
       u32 active_route_board;
+      scene_context scene;
 
       u32 w, h;
       float *buffer;
@@ -386,15 +387,9 @@ VG_STATIC void world_init(void)
    mdl_context msky;
    mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
    mdl_load_metadata_block( &msky, vg_mem.scratch );
-   mdl_load_mesh_block( &msky, vg_mem.scratch );
+   mdl_async_load_glmesh( &msky, &world_global.skydome );
    mdl_close( &msky );
 
-   vg_acquire_thread_sync();
-   {
-      mdl_unpack_glmesh( &msky, &world_global.skydome );
-   }
-   vg_release_thread_sync();
-
    /* Other systems */
    vg_info( "Loading other world systems\n" );
 
@@ -456,7 +451,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
       v3_copy( audio->transform.co, sound_co );
    }
    else
-      vg_fatal_exit_loop( "ent_audio_call (invalid function id)" );
+      vg_fatal_error( "ent_audio_call (invalid function id)" );
 
    float chance = vg_randf()*100.0f,
          bar = 0.0f;
@@ -749,13 +744,13 @@ VG_STATIC void ray_world_get_tri( world_instance *world,
                                   ray_hit *hit, v3f tri[3] )
 {
    for( int i=0; i<3; i++ )
-      v3_copy( world->scene_geo->arrvertices[ hit->tri[i] ].co, tri[i] );
+      v3_copy( world->scene_geo.arrvertices[ hit->tri[i] ].co, tri[i] );
 }
 
 VG_STATIC int ray_world( world_instance *world,
                          v3f pos, v3f dir, ray_hit *hit )
 {
-   return scene_raycast( world->scene_geo, world->geo_bh, pos, dir, hit );
+   return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit );
 }
 
 /*
@@ -788,14 +783,14 @@ VG_STATIC int spherecast_world( world_instance *world,
 
    int idx;
    while( bh_next( world->geo_bh, &it, region, &idx ) ){
-      u32 *ptri = &world->scene_geo->arrindices[ idx*3 ];
+      u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
       v3f tri[3];
 
       boxf box;
       box_init_inf( box );
 
       for( int j=0; j<3; j++ ){
-         v3_copy( world->scene_geo->arrvertices[ptri[j]].co, tri[j] );
+         v3_copy( world->scene_geo.arrvertices[ptri[j]].co, tri[j] );
          box_addpt( box, tri[j] );
       }
 
index 989e918356a34e8f837d2af936e703be224c87b6..469f73695e7da46489e08a2f3b6dc8a93e67b306 100644 (file)
@@ -42,7 +42,6 @@ VG_STATIC void world_gates_init(void)
    mdl_context mgate;
    mdl_open( &mgate, "models/rs_gate.mdl", vg_mem.scratch );
    mdl_load_metadata_block( &mgate, vg_mem.scratch );
-   mdl_load_mesh_block( &mgate, vg_mem.scratch );
 
    mdl_mesh *surface = mdl_find_mesh( &mgate, "rs_gate" );
    mdl_submesh *sm = mdl_arritm(&mgate.submeshs,surface->submesh_start);
@@ -57,13 +56,8 @@ VG_STATIC void world_gates_init(void)
       world_global.sm_gate_marker[i] = *sm;
    }
 
+   mdl_async_load_glmesh( &mgate, &world_global.mesh_gate );
    mdl_close( &mgate );
-
-   vg_acquire_thread_sync();
-   {
-      mdl_unpack_glmesh( &mgate, &world_global.mesh_gate );
-   }
-   vg_release_thread_sync();
 }
 
 VG_STATIC int render_gate( world_instance *world_inside,
index e8e9293ddcd6401addfbdf28a2177dddeede21b1..3e7cdb90addbca4605f31b993f8aabfcf674002d 100644 (file)
@@ -9,7 +9,7 @@
 
 VG_STATIC void world_load( u32 index, const char *path );
 
-VG_STATIC void world_add_all_if_material( m4x3f transform, scene *pscene, 
+VG_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++ ){
@@ -22,14 +22,14 @@ VG_STATIC void world_add_all_if_material( m4x3f transform, scene *pscene,
             mdl_transform_m4x3( &mesh->transform, transform2 );
             m4x3_mul( transform, transform2, transform2 );
 
-            scene_add_mdl_submesh( pscene, mdl, sm, transform2 );
+            scene_add_mdl_submesh( scene, mdl, sm, transform2 );
          }
       }
    }
 }
 
 VG_STATIC void world_add_blob( world_instance *world,
-                               scene *pscene, ray_hit *hit )
+                               scene_context *scene, ray_hit *hit )
 {
    m4x3f transform;
    v4f qsurface, qrandom;
@@ -56,16 +56,16 @@ VG_STATIC void world_add_blob( world_instance *world,
 
    const u32 indices[] = { 0,1,3, 0,3,2, 2,3,5, 2,5,4 };
 
-   if( pscene->vertex_count + vg_list_size(verts) > pscene->max_vertices )
-      vg_fatal_exit_loop( "Scene vertex buffer overflow" );
+   if( scene->vertex_count + vg_list_size(verts) > scene->max_vertices )
+      vg_fatal_error( "Scene vertex buffer overflow" );
 
-   if( pscene->indice_count + vg_list_size(indices) > pscene->max_indices )
-      vg_fatal_exit_loop( "Scene index buffer overflow" );
+   if( scene->indice_count + vg_list_size(indices) > scene->max_indices )
+      vg_fatal_error( "Scene index buffer overflow" );
 
-   scene_vert *dst_verts = &pscene->arrvertices[ pscene->vertex_count ];
-   u32 *dst_indices      = &pscene->arrindices [ pscene->indice_count ];
+   scene_vert *dst_verts = &scene->arrvertices[ scene->vertex_count ];
+   u32 *dst_indices      = &scene->arrindices [ scene->indice_count ];
 
-   scene_vert *ref       = &world->scene_geo->arrvertices[ hit->tri[0] ];
+   scene_vert *ref       = &world->scene_geo.arrvertices[ hit->tri[0] ];
 
    for( u32 i=0; i<vg_list_size(verts); i++ )
    {
@@ -79,14 +79,15 @@ VG_STATIC void world_add_blob( world_instance *world,
    }
 
    for( u32 i=0; i<vg_list_size(indices); i++ )
-      dst_indices[i] = indices[i] + pscene->vertex_count;
+      dst_indices[i] = indices[i] + scene->vertex_count;
 
-   pscene->vertex_count += vg_list_size(verts);
-   pscene->indice_count += vg_list_size(indices);
+   scene->vertex_count += vg_list_size(verts);
+   scene->indice_count += vg_list_size(indices);
 }
 
 /* Sprinkle foliage models over the map on terrain material */
 VG_STATIC void world_apply_procedural_foliage( world_instance *world,
+                                               scene_context *scene,
                                                struct world_surface *mat )
 {
    if( vg.quality_profile == k_quality_profile_low )
@@ -95,7 +96,7 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world,
    vg_info( "Applying foliage (%u)\n", mat->info.pstr_name );
 
    v3f volume;
-   v3_sub( world->scene_geo->bbx[1], world->scene_geo->bbx[0], volume );
+   v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], volume );
    volume[1] = 1.0f;
 
    int count = 0;
@@ -109,7 +110,7 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world,
       v3f pos;
       v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
       pos[1] = 1000.0f;
-      v3_add( pos, world->scene_geo->bbx[0], pos );
+      v3_add( pos, world->scene_geo.bbx[0], pos );
       
       ray_hit hit;
       hit.dist = INFINITY;
@@ -117,7 +118,7 @@ VG_STATIC void world_apply_procedural_foliage( world_instance *world,
       if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &hit )){
          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_add_blob( world, world->scene_no_collide, &hit );
+            world_add_blob( world, scene, &hit );
             count ++;
          }
       }
@@ -131,7 +132,10 @@ VG_STATIC void world_generate( world_instance *world )
    /* 
     * Compile meshes into the world scenes
     */
-   world->scene_geo = scene_init( world->heap, 320000, 1200000 );
+   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 );
+   scene_supply_buffer( &world->scene_geo, buffer );
 
    m4x3f midentity;
    m4x3_identity( midentity );
@@ -147,23 +151,39 @@ VG_STATIC void world_generate( world_instance *world )
       struct world_surface *surf = &world->surfaces[ i ];
 
       if( surf->info.flags & k_material_flag_collision )
-         world_add_all_if_material( midentity, world->scene_geo, 
+         world_add_all_if_material( midentity, &world->scene_geo, 
                                     &world->meta, i );
 
-      scene_copy_slice( world->scene_geo, &surf->sm_geo );
+      scene_copy_slice( &world->scene_geo, &surf->sm_geo );
    }
 
    /* compress that bad boy */
-   world->scene_geo = scene_fix( world->heap, world->scene_geo );
+   u32 new_vert_max = world->scene_geo.vertex_count,
+       new_vert_size = vg_align8(new_vert_max*sizeof(scene_vert)),
+       new_indice_len = world->scene_geo.indice_count*sizeof(u32);
 
-   vg_acquire_thread_sync();
-   {
-      scene_upload( world->scene_geo, &world->mesh_geo );
-   }
-   vg_release_thread_sync();
+   u32 *src_indices = world->scene_geo.arrindices,
+       *dst_indices = (u32 *)(buffer + new_vert_size);
+
+   memmove( dst_indices, src_indices, new_indice_len );
+
+   world->scene_geo.max_indices = world->scene_geo.indice_count;
+   world->scene_geo.max_vertices = world->scene_geo.vertex_count;
+   buf_size = scene_mem_required( &world->scene_geo );
+
+   buffer = vg_linear_resize( world->heap, buffer, buf_size );
+
+   world->scene_geo.arrvertices = (scene_vert *)(buffer);
+   world->scene_geo.arrindices = (u32 *)(buffer + new_vert_size);
+
+   scene_upload_async( &world->scene_geo, &world->mesh_geo );
+
+   /* need send off the memory to the gpu before we can create the bvh. */
+   vg_async_stall();
+   vg_info( "creating bvh\n" );
 
    /* setup spacial mapping and rigidbody */
-   world->geo_bh = scene_bh_create( world->heap, world->scene_geo );
+   world->geo_bh = scene_bh_create( world->heap, &world->scene_geo );
 
    v3_zero( world->rb_geo.rb.co );
    v3_zero( world->rb_geo.rb.v );
@@ -180,38 +200,25 @@ VG_STATIC void world_generate( world_instance *world )
     */
    vg_info( "Generating non-collidable geometry\n" );
 
-   world->scene_no_collide = scene_init( world->heap, 200000, 500000 );
+   vg_async_item *call = scene_alloc_async( &world->scene_no_collide,
+                                            &world->mesh_no_collide,
+                                            200000, 500000 );
 
    for( u32 i=0; i<world->surface_count; i++ ){
-      struct world_surface *mat = &world->surfaces[ i ];
+      struct world_surface *surf = &world->surfaces[ i ];
 
-      if( !(mat->info.flags & k_material_flag_collision) ){
-         world_add_all_if_material( midentity, world->scene_no_collide, 
-                                    &world->meta, i );
+      if( !(surf->info.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( world, mat );
+      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, &mat->sm_no_collide );
+      scene_copy_slice( &world->scene_no_collide, &surf->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; i<mdl_arrcount( &world->ent_traffic ); i++ ){
       ent_traffic *vehc = mdl_arritm( &world->ent_traffic, i );
 
@@ -225,23 +232,15 @@ VG_STATIC void world_generate( world_instance *world )
 
          m4x3f identity;
          m4x3_identity( identity );
-         scene_add_mdl_submesh( world->scene_no_collide, &world->meta
-                                sm, identity );
+         scene_add_mdl_submesh( &world->scene_no_collide
+                                &world->meta, sm, identity );
 
-         scene_copy_slice( world->scene_no_collide, sm );
+         scene_copy_slice( &world->scene_no_collide, sm );
          sm->flags |= k_submesh_flag_consumed;
       }
    }
 
-   /* upload and free that */
-   vg_acquire_thread_sync();
-   {
-      scene_upload( world->scene_no_collide, &world->mesh_no_collide );
-   }
-   vg_release_thread_sync();
-
-   vg_linear_del( world->heap, world->scene_no_collide );
-   world->scene_no_collide = NULL;
+   vg_async_dispatch( call, async_scene_upload );
 }
 
 float fsd_cone_infinite( v3f p, v2f c )
@@ -257,12 +256,32 @@ float fsd_cone_infinite( v3f p, v2f c )
    return d * ((q[0]*c[1]-q[1]*c[0]<0.0f)?-1.0f:1.0f);
 }
 
+struct light_indices_upload_info{
+   world_instance *world;
+   v3i count;
+
+   void *data;
+};
+
+VG_STATIC void async_upload_light_indices( void *payload, u32 size )
+{
+   struct light_indices_upload_info *info = payload;
+
+   glGenTextures( 1, &info->world->tex_light_cubes );
+   glBindTexture( GL_TEXTURE_3D, info->world->tex_light_cubes );
+   glTexImage3D( GL_TEXTURE_3D, 0, GL_RG32UI,
+                 info->count[0], info->count[1], info->count[2],
+                 0, GL_RG_INTEGER, GL_UNSIGNED_INT, info->data );
+   glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+}
+
 VG_STATIC void world_compute_light_indices( world_instance *world )
 {
    /* light cubes */
    v3f cubes_min, cubes_max;
-   v3_muls( world->scene_geo->bbx[0], 1.0f/k_light_cube_size, cubes_min );
-   v3_muls( world->scene_geo->bbx[1], 1.0f/k_light_cube_size, cubes_max );
+   v3_muls( world->scene_geo.bbx[0], 1.0f/k_light_cube_size, cubes_min );
+   v3_muls( world->scene_geo.bbx[1], 1.0f/k_light_cube_size, cubes_max );
 
    v3_sub( cubes_min, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_min );
    v3_add( cubes_max, (v3f){ 0.5f, 0.5f, 0.5f }, cubes_max );
@@ -305,8 +324,17 @@ VG_STATIC void world_compute_light_indices( world_instance *world )
 
    int total_cubes = icubes_count[0]*icubes_count[1]*icubes_count[2];
 
-   u32 *cubes_index = vg_linear_alloc( world->heap,
-                                       vg_align8(total_cubes*sizeof(u32)*2) );
+   u32 data_size = vg_align8(total_cubes*sizeof(u32)*2),
+       hdr_size  = vg_align8(sizeof(struct light_indices_upload_info));
+
+   vg_async_item *call = vg_async_alloc( data_size + hdr_size );
+   struct light_indices_upload_info *info = call->payload;
+   info->data = ((u8*)call->payload) + hdr_size;
+   info->world = world;
+   u32 *cubes_index = info->data;
+
+   for( int i=0; i<3; i++ )
+      info->count[i] = icubes_count[i];
                                        
    vg_info( "Computing light cubes (%d) [%f %f %f] -> [%f %f %f]\n", 
              total_cubes, cubes_min[0], -cubes_min[2], cubes_min[1],
@@ -401,160 +429,129 @@ VG_STATIC void world_compute_light_indices( world_instance *world )
       }
    }
 
-   vg_acquire_thread_sync();
+   vg_async_dispatch( call, async_upload_light_indices );
+}
 
-   glGenTextures( 1, &world->tex_light_cubes );
-   glBindTexture( GL_TEXTURE_3D, world->tex_light_cubes );
-   glTexImage3D( GL_TEXTURE_3D, 0, GL_RG32UI,
-                 icubes_count[0], icubes_count[1], icubes_count[2],
-                 0, GL_RG_INTEGER, GL_UNSIGNED_INT, cubes_index );
-   glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
-   glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+VG_STATIC void async_world_postprocess_render( void *payload, u32 _size )
+{
+   /* create scene lighting buffer */
+   world_instance *world = payload;
 
-   vg_linear_del( world->heap, cubes_index );
+   u32 size = VG_MAX(mdl_arrcount(&world->ent_light),1) * sizeof(float)*12;
+   vg_info( "Upload %ubytes (lighting)\n", size );
 
-   vg_release_thread_sync();
-}
+   glGenBuffers( 1, &world->tbo_light_entities );
+   glBindBuffer( GL_TEXTURE_BUFFER, world->tbo_light_entities );
+   glBufferData( GL_TEXTURE_BUFFER, size, NULL, GL_DYNAMIC_DRAW );
+   
+   /* buffer layout
+    *  
+    *  colour               position                direction (spots)
+    * | .   .   .   .     | .   .   .   .         | .   .   .   .  |
+    * | Re  Ge  Be  Night | Xco Yco Zco Range     | Dx  Dy  Dz  Da |
+    *
+    */
 
-VG_STATIC int reset_player( int argc, char const *argv[] );
-VG_STATIC void world_post_process( world_instance *world )
-{
-   /* initialize audio if need be */
-#if 0
-   audio_lock();
-   for( int i=0; i<world->audio_things_count; i++ )
-   {
-      struct world_audio_thing *thingy = &world->audio_things[ i ];
+   v4f *light_dst = glMapBuffer( GL_TEXTURE_BUFFER, GL_WRITE_ONLY );
+   for( u32 i=0; i<mdl_arrcount(&world->ent_light); i++ ){
+      ent_light *light = mdl_arritm( &world->ent_light, i );
 
-      if( thingy->flags & AUDIO_FLAG_AUTO_START )
-      {
-         audio_channel *ch = 
-            audio_request_channel( &thingy->temp_embedded_clip, thingy->flags );
+      /* colour  + night */
+      v3_muls( light->colour, light->colour[3] * 2.0f, light_dst[i*3+0] );
+      light_dst[i*3+0][3] = 2.0f;
 
-         audio_channel_edit_volume( ch, thingy->volume, 1 );
-         audio_channel_set_spacial( ch, thingy->pos, thingy->range );
+      if( !light->daytime ){
+         u32 hash = (i * 29986577u) & 0xffu;
+         float switch_on = hash;
+               switch_on *= (1.0f/255.0f);
 
-         if( !(ch->flags & AUDIO_FLAG_LOOP) )
-            ch = audio_relinquish_channel( ch );
+         light_dst[i*3+0][3] = 0.44f + switch_on * 0.015f;
       }
+      
+      /* position + 1/range^2 */
+      v3_copy( light->transform.co, light_dst[i*3+1] );
+      light_dst[i*3+1][3] = 1.0f/(light->range*light->range);
+
+      /* direction + angle */
+      q_mulv( light->transform.q, (v3f){0.0f,-1.0f,0.0f}, light_dst[i*3+2]);
+      light_dst[i*3+2][3] = cosf( light->angle );
    }
-   audio_unlock();
-#endif
 
-   world_compute_light_indices( world );
+   glUnmapBuffer( GL_TEXTURE_BUFFER );
 
-   vg_acquire_thread_sync();
-   {
-      /* create scene lighting buffer */
+   glGenTextures( 1, &world->tex_light_entities );
+   glBindTexture( GL_TEXTURE_BUFFER, world->tex_light_entities );
+   glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F, world->tbo_light_entities );
 
-      u32 size = VG_MAX(mdl_arrcount(&world->ent_light),1) * sizeof(float)*12;
-      vg_info( "Upload %ubytes (lighting)\n", size );
+   /* Upload lighting uniform buffer */
+   if( world->water.enabled )
+      v4_copy( world->water.plane, world->ub_lighting.g_water_plane );
 
-      glGenBuffers( 1, &world->tbo_light_entities );
-      glBindBuffer( GL_TEXTURE_BUFFER, world->tbo_light_entities );
-      glBufferData( GL_TEXTURE_BUFFER, size, NULL, GL_DYNAMIC_DRAW );
-      
-      /* buffer layout
-       *  
-       *  colour               position                direction (spots)
-       * | .   .   .   .     | .   .   .   .         | .   .   .   .  |
-       * | Re  Ge  Be  Night | Xco Yco Zco Range     | Dx  Dy  Dz  Da |
-       *
-       */
-
-      v4f *light_dst = glMapBuffer( GL_TEXTURE_BUFFER, GL_WRITE_ONLY );
-      for( u32 i=0; i<mdl_arrcount(&world->ent_light); i++ ){
-         ent_light *light = mdl_arritm( &world->ent_light, i );
-
-         /* colour  + night */
-         v3_muls( light->colour, light->colour[3] * 2.0f, light_dst[i*3+0] );
-         light_dst[i*3+0][3] = 2.0f;
-
-         if( !light->daytime ){
-            u32 hash = (i * 29986577u) & 0xffu;
-            float switch_on = hash;
-                  switch_on *= (1.0f/255.0f);
-
-            light_dst[i*3+0][3] = 0.44f + switch_on * 0.015f;
-         }
-         
-         /* position + 1/range^2 */
-         v3_copy( light->transform.co, light_dst[i*3+1] );
-         light_dst[i*3+1][3] = 1.0f/(light->range*light->range);
-
-         /* direction + angle */
-         q_mulv( light->transform.q, (v3f){0.0f,-1.0f,0.0f}, light_dst[i*3+2]);
-         light_dst[i*3+2][3] = cosf( light->angle );
-      }
+   v4f info_vec;
+   v3f *bounds = world->scene_geo.bbx;
 
-      glUnmapBuffer( GL_TEXTURE_BUFFER );
-
-      glGenTextures( 1, &world->tex_light_entities );
-      glBindTexture( GL_TEXTURE_BUFFER, world->tex_light_entities );
-      glTexBuffer( GL_TEXTURE_BUFFER, GL_RGBA32F, world->tbo_light_entities );
-
-      /* Upload lighting uniform buffer */
-      if( world->water.enabled )
-         v4_copy( world->water.plane, world->ub_lighting.g_water_plane );
-
-      v4f info_vec;
-      v3f *bounds = world->scene_geo->bbx;
-
-      info_vec[0] = bounds[0][0];
-      info_vec[1] = bounds[0][2];
-      info_vec[2] = 1.0f/ (bounds[1][0]-bounds[0][0]);
-      info_vec[3] = 1.0f/ (bounds[1][2]-bounds[0][2]);
-      v4_copy( info_vec, world->ub_lighting.g_depth_bounds );
-
-      /* 
-       * Rendering the depth map
-       */
-      camera ortho;
-
-      v3f extent;
-      v3_sub( world->scene_geo->bbx[1], world->scene_geo->bbx[0], extent );
-
-      float fl = world->scene_geo->bbx[0][0],
-            fr = world->scene_geo->bbx[1][0],
-            fb = world->scene_geo->bbx[0][2],
-            ft = world->scene_geo->bbx[1][2],
-            rl = 1.0f / (fr-fl),
-            tb = 1.0f / (ft-fb);
-
-      m4x4_zero( ortho.mtx.p );
-      ortho.mtx.p[0][0] = 2.0f * rl;
-      ortho.mtx.p[2][1] = 2.0f * tb;
-      ortho.mtx.p[3][0] = (fr + fl) * -rl;
-      ortho.mtx.p[3][1] = (ft + fb) * -tb;
-      ortho.mtx.p[3][3] = 1.0f;
-      m4x3_identity( ortho.transform );
-      camera_update_view( &ortho );
-      camera_finalize( &ortho );
-
-      glDisable(GL_DEPTH_TEST);
-      glDisable(GL_BLEND);
-      glDisable(GL_CULL_FACE);
-      render_fb_bind( &world->heightmap, 0 );
-      shader_blitcolour_use();
-      shader_blitcolour_uColour( (v4f){-9999.0f,-9999.0f,-9999.0f,-9999.0f} );
-      render_fsquad();
-
-      glEnable(GL_BLEND);
-      glBlendFunc(GL_ONE, GL_ONE);
-      glBlendEquation(GL_MAX);
-
-      render_world_position( world, &ortho );
-      glDisable(GL_BLEND);
-      glEnable(GL_DEPTH_TEST);
-      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-
-      /* upload full buffer */
-      glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
-      glBufferSubData( GL_UNIFORM_BUFFER, 0, 
-                       sizeof(struct ub_world_lighting), &world->ub_lighting );
-   }
+   info_vec[0] = bounds[0][0];
+   info_vec[1] = bounds[0][2];
+   info_vec[2] = 1.0f/ (bounds[1][0]-bounds[0][0]);
+   info_vec[3] = 1.0f/ (bounds[1][2]-bounds[0][2]);
+   v4_copy( info_vec, world->ub_lighting.g_depth_bounds );
 
-   vg_release_thread_sync();
+   /* 
+    * Rendering the depth map
+    */
+   camera ortho;
+
+   v3f extent;
+   v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], extent );
+
+   float fl = world->scene_geo.bbx[0][0],
+         fr = world->scene_geo.bbx[1][0],
+         fb = world->scene_geo.bbx[0][2],
+         ft = world->scene_geo.bbx[1][2],
+         rl = 1.0f / (fr-fl),
+         tb = 1.0f / (ft-fb);
+
+   m4x4_zero( ortho.mtx.p );
+   ortho.mtx.p[0][0] = 2.0f * rl;
+   ortho.mtx.p[2][1] = 2.0f * tb;
+   ortho.mtx.p[3][0] = (fr + fl) * -rl;
+   ortho.mtx.p[3][1] = (ft + fb) * -tb;
+   ortho.mtx.p[3][3] = 1.0f;
+   m4x3_identity( ortho.transform );
+   camera_update_view( &ortho );
+   camera_finalize( &ortho );
+
+   glDisable(GL_DEPTH_TEST);
+   glDisable(GL_BLEND);
+   glDisable(GL_CULL_FACE);
+   render_fb_bind( &world->heightmap, 0 );
+   shader_blitcolour_use();
+   shader_blitcolour_uColour( (v4f){-9999.0f,-9999.0f,-9999.0f,-9999.0f} );
+   render_fsquad();
+
+   glEnable(GL_BLEND);
+   glBlendFunc(GL_ONE, GL_ONE);
+   glBlendEquation(GL_MAX);
+
+   render_world_position( world, &ortho );
+   glDisable(GL_BLEND);
+   glEnable(GL_DEPTH_TEST);
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+   /* upload full buffer */
+   glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
+   glBufferSubData( GL_UNIFORM_BUFFER, 0, 
+                    sizeof(struct ub_world_lighting), &world->ub_lighting );
+}
+
+VG_STATIC int reset_player( int argc, char const *argv[] );
+VG_STATIC void world_post_process( world_instance *world )
+{
+   world_compute_light_indices( world );
+
+   vg_async_item *call = vg_async_alloc(0);
+   call->payload = world;
+   vg_async_dispatch( call, async_world_postprocess_render );
 }
 
 VG_STATIC void world_process_resources( world_instance *world )
@@ -567,43 +564,24 @@ 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_tex2d_replace_with_error( &world->textures[0] );
 
-   vg_acquire_thread_sync();
-   {
-      /* error texture */
-      world->textures[0] = vg_tex2d_new();
-      vg_tex2d_set_error();
-      vg_tex2d_nearest();
-      vg_tex2d_repeat();
-
-      for( u32 i=0; i<mdl_arrcount(&world->meta.textures); i++ ){
-         mdl_texture *tex = mdl_arritm( &world->meta.textures, i );
-
-         if( !tex->file.pack_size ){
-            vg_release_thread_sync();
-            vg_fatal_exit_loop( "World models must have packed textures!" );
-         }
+   for( u32 i=0; i<mdl_arrcount(&world->meta.textures); i++ ){
+      mdl_texture *tex = mdl_arritm( &world->meta.textures, i );
 
-         vg_linear_clear( vg_mem.scratch );
-         void *src_data = vg_linear_alloc( vg_mem.scratch, 
-                                           tex->file.pack_size );
-         mdl_fread_pack_file( &world->meta, &tex->file, src_data );
-
-         world->textures[i+1] = vg_tex2d_new();
-         vg_tex2d_set_error();
-         vg_tex2d_qoi( src_data, tex->file.pack_size,
-                       mdl_pstr( &world->meta, tex->file.pstr_path ));
-         vg_tex2d_nearest();
-         vg_tex2d_repeat();
+      if( !tex->file.pack_size ){
+         vg_fatal_error( "World models must have packed textures!" );
       }
+
+      vg_linear_clear( vg_mem.scratch );
+      void *src_data = vg_linear_alloc( vg_mem.scratch, 
+                                        tex->file.pack_size );
+      mdl_fread_pack_file( &world->meta, &tex->file, src_data );
+
+      vg_tex2d_load_qoi_async( src_data, tex->file.pack_size,
+                               VG_TEX2D_NEAREST|VG_TEX2D_REPEAT,
+                               &world->textures[i+1] );
    }
-   vg_release_thread_sync();
 
    vg_info( "Loading materials\n" );
 
@@ -621,6 +599,7 @@ VG_STATIC void world_process_resources( world_instance *world )
    }
 }
 
+#if 0
 VG_STATIC void world_free( world_instance *world )
 {
    vg_acquire_thread_sync();
@@ -644,6 +623,7 @@ VG_STATIC void world_free( world_instance *world )
 
    world->status = k_world_status_unloaded;
 }
+#endif
 
 VG_STATIC void world_init_blank( world_instance *world )
 {
@@ -653,10 +633,6 @@ VG_STATIC void world_init_blank( world_instance *world )
    world->texture_count = 0;
    world->surfaces = NULL;
    world->surface_count = 0;
-   
-   world->scene_geo = NULL;
-   world->scene_no_collide = NULL;
-   world->scene_lines = NULL;
 
    world->geo_bh = NULL;
    world->volume_bh = NULL;
@@ -831,7 +807,7 @@ VG_STATIC void world_load( u32 index, const char *path )
    u32 min_overhead = sizeof(vg_linear_allocator);
 
    if( heap_availible < (min_overhead+1024) ){
-      vg_fatal_exit_loop( "out of memory" );
+      vg_fatal_error( "out of memory" );
    }
 
    u32 size = heap_availible - min_overhead;
index f61974e37e791f0b7384b17ef384416086c791b6..7fb47b0dc2cb580c9ee3fd1a8521d04643018412 100644 (file)
@@ -8,62 +8,60 @@
 #include "camera.h"
 #include "world.h"
 
-/* FIXME */
-VG_STATIC vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
-                                         .flags = VG_TEXTURE_NEAREST };
+VG_STATIC GLuint tex_terrain_noise;
 
-VG_STATIC void world_render_init(void)
+VG_STATIC void async_world_render_init( void *payload, u32 size )
 {
-   vg_info( "Loading default world textures\n" );
-
-   vg_acquire_thread_sync();
-   {
-      vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_noise }, 1 );
-
-
-      vg_info( "Allocate uniform buffers\n" );
-      for( int i=0; i<4; i++ )
-      {
-         world_instance *world = &world_global.worlds[i];
-         world->ubo_bind_point = i;
+   vg_info( "Allocate uniform buffers\n" );
+   for( int i=0; i<4; i++ ){
+      world_instance *world = &world_global.worlds[i];
+      world->ubo_bind_point = i;
+
+      glGenBuffers( 1, &world->ubo_lighting );
+      glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
+      glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting), 
+                    NULL, GL_DYNAMIC_DRAW );
+
+      glBindBufferBase( GL_UNIFORM_BUFFER, i, world->ubo_lighting );
+      VG_CHECK_GL_ERR();
+   }
 
-         glGenBuffers( 1, &world->ubo_lighting );
-         glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting );
-         glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting), 
-                       NULL, GL_DYNAMIC_DRAW );
+   vg_info( "Allocate frame buffers\n" );
+   for( int i=0; i<4; i++ ){
+      world_instance *world = &world_global.worlds[i];
+      struct framebuffer *fb = &world->heightmap;
+
+      fb->display_name = NULL;
+      fb->link = NULL;
+      fb->fixed_w = 1024;
+      fb->fixed_h = 1024;
+      fb->resolution_div = 0;
+
+      fb->attachments[0].display_name     = NULL;
+      fb->attachments[0].purpose = k_framebuffer_attachment_type_texture;
+      fb->attachments[0].internalformat   = GL_RG16F;
+      fb->attachments[0].format           = GL_RG;
+      fb->attachments[0].type             = GL_FLOAT;
+      fb->attachments[0].attachment       = GL_COLOR_ATTACHMENT0;
+
+      fb->attachments[1].purpose = k_framebuffer_attachment_type_none;
+      fb->attachments[2].purpose = k_framebuffer_attachment_type_none;
+      fb->attachments[3].purpose = k_framebuffer_attachment_type_none;
+      fb->attachments[4].purpose = k_framebuffer_attachment_type_none;
+
+      render_fb_allocate( fb );
+   }
+}
 
-         glBindBufferBase( GL_UNIFORM_BUFFER, i, world->ubo_lighting );
-         VG_CHECK_GL_ERR();
-      }
+VG_STATIC void world_render_init(void)
+{
+   vg_info( "Loading default world textures\n" );
 
-      vg_info( "Allocate frame buffers\n" );
-      for( int i=0; i<4; i++ )
-      {
-         world_instance *world = &world_global.worlds[i];
-         struct framebuffer *fb = &world->heightmap;
-
-         fb->display_name = NULL;
-         fb->link = NULL;
-         fb->fixed_w = 1024;
-         fb->fixed_h = 1024;
-         fb->resolution_div = 0;
-
-         fb->attachments[0].display_name     = NULL;
-         fb->attachments[0].purpose = k_framebuffer_attachment_type_texture;
-         fb->attachments[0].internalformat   = GL_RG16F;
-         fb->attachments[0].format           = GL_RG;
-         fb->attachments[0].type             = GL_FLOAT;
-         fb->attachments[0].attachment       = GL_COLOR_ATTACHMENT0;
-
-         fb->attachments[1].purpose = k_framebuffer_attachment_type_none;
-         fb->attachments[2].purpose = k_framebuffer_attachment_type_none;
-         fb->attachments[3].purpose = k_framebuffer_attachment_type_none;
-         fb->attachments[4].purpose = k_framebuffer_attachment_type_none;
-
-         render_fb_allocate( fb );
-      }
-   }
-   vg_release_thread_sync();
+   vg_tex2d_load_qoi_async_file( "textures/garbage.qoi", 
+                                 VG_TEX2D_NEAREST|VG_TEX2D_REPEAT, 
+                                 &tex_terrain_noise );
+   vg_async_item *call = vg_async_alloc(0);
+   vg_async_dispatch( call, async_world_render_init );
 }
 
 VG_STATIC void world_link_lighting_ub( world_instance *world, GLuint shader )
@@ -106,7 +104,8 @@ VG_STATIC void render_world_depth( world_instance *world, camera *cam );
 
 VG_STATIC void bind_terrain_noise(void)
 {
-   vg_tex2d_bind( &tex_terrain_noise, 0 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_terrain_noise );
 }
 
 struct world_pass{
@@ -203,7 +202,8 @@ VG_STATIC void render_world_vb( world_instance *world, camera *cam )
    world_bind_light_index( world, _shader_scene_vertex_blend.id,
                                 _uniform_scene_vertex_blend_uLightsIndex, 4 );
 
-   vg_tex2d_bind( &tex_terrain_noise, 0 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_terrain_noise );
 
    shader_scene_vertex_blend_uPv( cam->mtx.pv );
    shader_scene_vertex_blend_uCamera( cam->transform[3] );
@@ -308,7 +308,8 @@ VG_STATIC void render_terrain( world_instance *world, camera *cam )
    world_bind_light_index( world, _shader_scene_terrain.id,
                            _uniform_scene_terrain_uLightsIndex, 4 );
 
-   vg_tex2d_bind( &tex_terrain_noise, 0 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_terrain_noise );
 
    shader_scene_terrain_uPv( cam->mtx.pv );
    shader_scene_terrain_uCamera( cam->transform[3] );
@@ -360,7 +361,8 @@ VG_STATIC void render_sky( world_instance *world, camera *cam )
    shader_model_sky_uTexGarbage(0);
    world_link_lighting_ub( world, _shader_model_sky.id );
 
-   vg_tex2d_bind( &tex_terrain_noise, 0 );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, tex_terrain_noise );
 
    glDepthMask( GL_FALSE );
    glDisable( GL_DEPTH_TEST );
@@ -376,7 +378,6 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam,
                                    int layer_depth )
 {
    float closest = INFINITY;
-
    struct ent_gate *gate = NULL;
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
index 820501a81c74b82ae514a8afbd33c47446995f85..99edf267254b51a9896c28eb4761e7bf7b704a65 100644 (file)
@@ -228,8 +228,9 @@ VG_STATIC void world_routes_debug( world_instance *world )
    }
 }
 
-VG_STATIC void world_routes_place_curve( world_instance *world,
-                                         v4f h[3], v3f n0, v3f n2 )
+VG_STATIC 
+void world_routes_place_curve( world_instance *world,
+                               v4f h[3], v3f n0, v3f n2, scene_context *scene )
 {
    float t;
    v3f p, pd;
@@ -313,18 +314,18 @@ VG_STATIC void world_routes_place_curve( world_instance *world,
             vb.uv[0] = t1;
             vb.uv[1] = 1.0f;
 
-            scene_push_vert( world->scene_lines, &va );
-            scene_push_vert( world->scene_lines, &vb );
+            scene_push_vert( scene, &va );
+            scene_push_vert( scene, &vb );
 
             if( last_valid ){
                /* Connect them with triangles */
-               scene_push_tri( world->scene_lines, (u32[3]){ 
+               scene_push_tri( scene, (u32[3]){ 
                      last_valid+0-2, last_valid+1-2, last_valid+2-2} );
-               scene_push_tri( world->scene_lines, (u32[3]){ 
+               scene_push_tri( scene, (u32[3]){ 
                      last_valid+1-2, last_valid+3-2, last_valid+2-2} );
             }
             
-            last_valid = world->scene_lines->vertex_count;
+            last_valid = scene->vertex_count;
          }
          else
             last_valid = 0;
@@ -343,7 +344,9 @@ VG_STATIC void world_routes_place_curve( world_instance *world,
    }
 }
 
-VG_STATIC void world_routes_create_mesh( world_instance *world, u32 route_id )
+VG_STATIC 
+void world_routes_create_mesh( world_instance *world, u32 route_id, 
+                               scene_context *sc )
 {
    ent_route *route = mdl_arritm( &world->ent_route, route_id );
    u32 last_valid = 0;
@@ -448,14 +451,14 @@ VG_STATIC void world_routes_create_mesh( world_instance *world, u32 route_id )
          v3_normalize( n0 );
          v3_normalize( n2 );
 
-         world_routes_place_curve( world, p, n0, n2 );
+         world_routes_place_curve( world, p, n0, n2, sc );
 
          /* --- */
          v4_copy( p[2], p[0] );
       }
    }
 
-   scene_copy_slice( world->scene_lines, &route->sm );
+   scene_copy_slice( sc, &route->sm );
 }
 
 /* 
@@ -464,7 +467,9 @@ VG_STATIC void world_routes_create_mesh( world_instance *world, u32 route_id )
 VG_STATIC void world_routes_generate( world_instance *world )
 {
    vg_info( "Generating route meshes\n" );
-   world->scene_lines = scene_init( world->heap, 200000, 300000 );
+   vg_async_item *call = scene_alloc_async( &world->scene_lines, 
+                                            &world->mesh_route_lines,
+                                            200000, 300000 );
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, i );
@@ -506,15 +511,9 @@ VG_STATIC void world_routes_generate( world_instance *world )
    }
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ )
-      world_routes_create_mesh( world, i );
-
-   vg_acquire_thread_sync();
-   {
-      scene_upload( world->scene_lines, &world->mesh_route_lines );
-   }
-   vg_release_thread_sync();
-   vg_linear_del( world->heap, world->scene_lines );
+      world_routes_create_mesh( world, i, &world->scene_lines );
 
+   vg_async_dispatch( call, async_scene_upload );
    world_routes_clear( world );
 }
 
index 98d34b2498ed1ccedf43b4f09b5528cf9ab9a2dd..18789c7e841320a235726cfecad66ae2deaa71d2 100644 (file)
@@ -9,9 +9,7 @@
 #include "shaders/scene_scoretext.h"
 #include "shaders/scene_vertex_blend.h"
 
-vg_tex2d tex_scoretext = { .path = "textures/scoretext.qoi",
-                           .flags = VG_TEXTURE_CLAMP|VG_TEXTURE_NEAREST };
-
+GLuint tex_scoretex;
 float sfd_encode_glyph( char c )
 {
    int value = 0;
@@ -101,7 +99,9 @@ VG_STATIC void sfd_render( world_instance *world, camera *cam, m4x3f transform )
                            _uniform_scene_scoretext_uLightsIndex, 4 );
 
    bind_terrain_noise();
-   vg_tex2d_bind( &tex_scoretext, 1 );
+
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, tex_scoretex );
 
    m4x4f pvm_prev;
    m4x3_expand( transform, pvm_prev );
@@ -131,7 +131,8 @@ VG_STATIC void sfd_render( world_instance *world, camera *cam, m4x3f transform )
    world_bind_light_index( world, _shader_scene_vertex_blend.id,
                                 _uniform_scene_vertex_blend_uLightsIndex, 4 );
    bind_terrain_noise();
-   vg_tex2d_bind( &tex_scoretext, 1 );
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, tex_scoretex );
 
    shader_scene_vertex_blend_uPv( cam->mtx.pv );
    shader_scene_vertex_blend_uPvmPrev( pvm_prev );
@@ -163,9 +164,15 @@ VG_STATIC void world_sfd_init(void)
    mdl_context mscoreboard;
    mdl_open( &mscoreboard, "models/rs_scoretext.mdl", vg_mem.scratch );
    mdl_load_metadata_block( &mscoreboard, vg_mem.scratch );
+   mdl_async_load_glmesh( &mscoreboard, &world_global.sfd.mesh_base );
+
    mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );
 
-   scene *sc = scene_init( vg_mem.scratch, 3000, 8000 );
+   scene_context *scene = &world_global.sfd.scene;
+   vg_async_item *call = scene_alloc_async( scene,
+                                            &world_global.sfd.mesh_display,
+                                            3000, 8000 );
+
 
    mdl_mesh *m_backer = mdl_find_mesh( &mscoreboard, "backer" ),
             *m_card   = mdl_find_mesh( &mscoreboard, "score_card" );
@@ -175,17 +182,15 @@ VG_STATIC void world_sfd_init(void)
       *sm_card   = mdl_arritm( &mscoreboard.submeshs, m_card->submesh_start );
    world_global.sfd.sm_base = *sm_backer;
 
-   mdl_close( &mscoreboard );
-
    m4x3f identity;
    m4x3_identity( identity );
 
    for( int i=0;i<4;i++ ){
-      u32 vert_start = sc->vertex_count;
-      scene_add_mdl_submesh( sc, &mscoreboard, sm_card, identity );
+      u32 vert_start = scene->vertex_count;
+      scene_add_mdl_submesh( scene, &mscoreboard, sm_card, identity );
 
       for( int j=0; j<sm_card->vertex_count; j++ ){
-         scene_vert *vert = &sc->arrvertices[ vert_start+j ];
+         scene_vert *vert = &scene->arrvertices[ vert_start+j ];
 
          float const k_glyph_uvw = 1.0f/64.0f;
          vert->uv[0] -= k_glyph_uvw * (float)(i-1);
@@ -193,13 +198,12 @@ VG_STATIC void world_sfd_init(void)
       }
    }
 
-   vg_acquire_thread_sync();
-   {
-      scene_upload( sc, &world_global.sfd.mesh_display );
-      mdl_unpack_glmesh( &mscoreboard, &world_global.sfd.mesh_base );
-      vg_tex2d_init( (vg_tex2d *[]){ &tex_scoretext }, 1 );
-   }
-   vg_release_thread_sync();
+   vg_async_dispatch( call, async_scene_upload );
+   vg_tex2d_load_qoi_async_file( "textures/scoretext.qoi", 
+                                 VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
+                                 &tex_scoretex );
+
+   mdl_close( &mscoreboard );
 
    int w = 27,
        h = 13;
index 84558a20f392c591449057d404d77f432b176849..14e3cd76409d3c472e7b22374982652f631d8de0 100644 (file)
@@ -11,7 +11,7 @@
 #include "shaders/scene_water_fast.h"
 #include "scene.h"
 
-vg_tex2d tex_water_surf = { .path = "textures/water_surf.qoi" };
+VG_STATIC GLuint tex_water_surf;
 
 VG_STATIC void world_water_init(void)
 {
@@ -19,11 +19,9 @@ VG_STATIC void world_water_init(void)
    shader_scene_water_register();
    shader_scene_water_fast_register();
 
-   vg_acquire_thread_sync();
-   {
-      vg_tex2d_init( (vg_tex2d *[]){&tex_water_surf}, 1 );
-   }
-   vg_release_thread_sync();
+   vg_tex2d_load_qoi_async_file( "textures/water_surf.qoi",
+                                 VG_TEX2D_LINEAR|VG_TEX2D_REPEAT,
+                                 &tex_water_surf );
 
    vg_success( "done\n" );
 }
@@ -135,9 +133,11 @@ VG_STATIC void render_water_surface( world_instance *world, camera *cam )
       
       render_fb_bind_texture( gpipeline.fb_water_reflection, 0, 0 );
       shader_scene_water_uTexMain( 0 );
-
-      vg_tex2d_bind( &tex_water_surf, 1 );
+   
+      glActiveTexture( GL_TEXTURE1 );
+      glBindTexture( GL_TEXTURE_2D, tex_water_surf );
       shader_scene_water_uTexDudv( 1 );
+      
       shader_scene_water_uInvRes( (v2f){
             1.0f / (float)vg.window_x,
             1.0f / (float)vg.window_y });
@@ -185,8 +185,10 @@ VG_STATIC void render_water_surface( world_instance *world, camera *cam )
    else if( vg.quality_profile == k_quality_profile_low ){
       shader_scene_water_fast_use();
 
-      vg_tex2d_bind( &tex_water_surf, 1 );
+      glActiveTexture( GL_TEXTURE1 );
+      glBindTexture( GL_TEXTURE_2D, tex_water_surf );
       shader_scene_water_fast_uTexDudv( 1 );
+
       shader_scene_water_fast_uTime( world_global.time );
       shader_scene_water_fast_uCamera( cam->transform[3] );
       shader_scene_water_fast_uSurfaceY( world->water.height );