# 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' )
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 );
}
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,
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];
if( !btn->mesh ){
vg_info( "info: %s\n", btn->name );
- vg_fatal_exit_loop( "Menu programming error" );
+ vg_fatal_error( "Menu programming error" );
}
}
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 );
{
fclose( mdl->file );
vg_file_print_invalid( mdl->file );
- vg_fatal_exit_loop( "Corrupt model" );
+ vg_fatal_error( "Corrupt model" );
}
/*
{
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 );
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;
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 );
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 );
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
}
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 );
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;
}
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;
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 );
}
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++ )
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]);
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,
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] );
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 ++ ){
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 );
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 */
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" );
}
vg_error( " status: Generic Error" );
vg_info( "}\n" );
- vg_fatal_exit_loop( "Incomplete framebuffer (see logs)" );
+ vg_fatal_error( "Incomplete framebuffer (see logs)" );
}
}
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,
glEnableVertexAttribArray( 0 );
VG_CHECK_GL_ERR();
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ gpipeline.ready = 1;
}
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 );
}
/*
!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 };
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 );
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;
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 ];
#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)
#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,
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 )
/*
* 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 );
}
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 );
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 );
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] ];
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] ];
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];
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 ] ],
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 ];
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;
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 ];
/*
* 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,
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 );
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"
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 );
#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)
{
steam_update();
- if( vg.is_loaded ){
+ if( skaterift_status == 1 ){
draw_origin_axis();
network_update();
VG_STATIC void vg_update_fixed(void)
{
- if( vg.is_loaded ){
+ if( skaterift_status == 1 ){
world_routes_fixedupdate( get_active_world() );
player__update( &localplayer );
VG_STATIC void vg_update_post(void)
{
- if( vg.is_loaded ){
+ if( skaterift_status == 1 ){
player__post_update( &localplayer );
float dist;
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 );
VG_STATIC void vg_ui(void)
{
+ if( skaterift_status == 0 ){
+ return;
+ }
+
#if 0
player__im_gui( &localplayer );
#endif
}
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;
}
}
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;
}
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 */
*/
/* 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,
glmesh mesh_base, mesh_display;
mdl_submesh sm_base;
u32 active_route_board;
+ scene_context scene;
u32 w, h;
float *buffer;
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" );
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;
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 );
}
/*
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] );
}
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);
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,
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++ ){
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;
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++ )
{
}
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 )
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;
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;
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 ++;
}
}
/*
* 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 );
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 );
*/
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 );
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 )
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 );
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],
}
}
- 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 )
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" );
}
}
+#if 0
VG_STATIC void world_free( world_instance *world )
{
vg_acquire_thread_sync();
world->status = k_world_status_unloaded;
}
+#endif
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;
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;
#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 )
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{
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] );
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] );
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 );
int layer_depth )
{
float closest = INFINITY;
-
struct ent_gate *gate = NULL;
for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
}
}
-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;
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;
}
}
-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;
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 );
}
/*
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 );
}
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 );
}
#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;
_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 );
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 );
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" );
*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);
}
}
- 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;
#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)
{
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" );
}
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 });
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 );