From 2c7c270c4d60627ae20fed295ea164e52d83f199 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 22 Mar 2025 02:45:51 +0000 Subject: [PATCH] Array file compiler for C side, board maker compiler --- build.c | 4 +- skaterift_blender/sr_bin.py | 4 +- skaterift_blender/sr_mdl.py | 3 +- src/array_file.c | 217 ++++++++++++++++++++++++++++++++++ src/array_file.h | 51 +++++++- src/board_maker.c | 87 +++++++++++++- src/board_maker.h | 5 +- src/model.c | 229 ++++++++++++++++++++++++++---------- src/model.h | 18 +++ src/player_render.c | 1 - src/skaterift.c | 3 + 11 files changed, 540 insertions(+), 82 deletions(-) diff --git a/build.c b/build.c index 59ea1a0..8024a3b 100644 --- a/build.c +++ b/build.c @@ -232,7 +232,7 @@ void build_game_bin( struct vg_project *proj, struct vg_compiler_env *env ) if( env->platform == k_platform_windows ) { - vg_strcat( &conf.link, "-lws2_32 " ); + vg_strcat( &conf.link, "-lws2_32 -lole32 " ); } vg_make_app( proj, &(struct vg_engine_config ) @@ -379,7 +379,7 @@ void s_utest_build(void) if( env->platform == k_platform_windows ) { - vg_strcat( &conf.link, "-lws2_32 " ); + vg_strcat( &conf.link, "-lws2_32 -lole32 " ); } vg_make_app( &test_proj, &(struct vg_engine_config ) diff --git a/skaterift_blender/sr_bin.py b/skaterift_blender/sr_bin.py index 74e452f..882b2db 100644 --- a/skaterift_blender/sr_bin.py +++ b/skaterift_blender/sr_bin.py @@ -111,7 +111,7 @@ def array_file_write( path, header, padding=8 ): # Header & index ptr # header.index.file_offset = header_size - header.index.item_count = len(_af_compiler.arrays) + header.index.item_count = num_arrays header.index.item_size = sizeof(array_file_meta) str_into_buf( 'index', header.index.name ) fp.write( header ) @@ -133,7 +133,7 @@ def array_file_write( path, header, padding=8 ): if type(arr) is bytearray: meta.item_size = 1 else: - meta.item_size = sizeof(arr[0]) if len(arr) else 0 + meta.item_size = sizeof(arr[0]) print( F'[AF] {name:>16}| {meta.item_count: 8} 0x{file_offset:02x}' ) file_offset += int_align_to( meta.item_size*meta.item_count, padding ) diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index 4ea8827..b08faad 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -396,8 +396,7 @@ def mdl_compile_mesh( obj ): node.entity_id = (ent_id_upr << 16) | ent_id_lwr #} - node.submesh_start, node.submesh_count, node.armature_id = \ - mdl_compile_mesh_internal( obj ) + node.submesh_start, node.submesh_count, node.armature_id = mdl_compile_mesh_internal( obj ) _mdl_compiler.meshes.append( node ) #} diff --git a/src/array_file.c b/src/array_file.c index 79a8f82..c786d5a 100644 --- a/src/array_file.c +++ b/src/array_file.c @@ -169,3 +169,220 @@ void af_close( array_file_context *ctx ) fclose( ctx->fp ); ctx->fp = NULL; } + +/* compiler + * ---------------------------------------------------------------------- */ + +struct af_compiler_iter +{ + u32 i, j; + af_compiler_index *index; + af_compiler_item *current_item; + void *data; +}; + +static void af_init_iterator( struct af_compiler_iter *iter, af_compiler_index *index ) +{ + iter->i = 0; + iter->j = 0; + iter->index = index; + iter->current_item = NULL; + iter->data = NULL; +} + +static bool af_next( struct af_compiler_iter *iter ) +{ + if( iter->i == 0 ) + { + if( iter->index->first == NULL ) + return 0; + iter->current_item = iter->index->first; + } + + if( iter->j >= iter->current_item->count ) + { + if( iter->current_item->next == NULL ) + return 0; + + iter->current_item = iter->current_item->next; + iter->j = 0; + } + + iter->data = iter->current_item->data + (iter->j * iter->index->element_size); + iter->j ++; + iter->i ++; + return 1; +} + +af_compiler_item *af_compiler_allocate_items( af_compiler *compiler, af_compiler_index *index, u32 count ) +{ + af_compiler_item *entry = vg_linear_alloc( compiler->allocator, sizeof(af_compiler_item) ); + entry->next = NULL; + + u32 data_size = count * index->element_size; + index->element_count += count; + + entry->data = vg_linear_alloc( compiler->allocator, data_size ); + entry->count = count; + + for( u32 i=0; idata)[i] = 0xab; + + if( index->last ) + index->last->next = entry; + index->last = entry; + + if( !index->first ) + index->first = entry; + + return entry; +} + +static void af_compiler_init_index( af_compiler_index *index, const char *alias, u32 element_size ) +{ + VG_ASSERT( element_size ); + vg_strncpy( alias, index->name, sizeof(index->name), k_strncpy_overflow_fatal ); + index->element_size = element_size; + index->element_count = 0; + index->first = NULL; + index->last = NULL; +} + +af_compiler_index *af_compiler_create_index( af_compiler *compiler, const char *alias, u32 element_size ) +{ + af_compiler_item *item = af_compiler_allocate_items( compiler, &compiler->index, 1 ); + af_compiler_index *index = item->data; + af_compiler_init_index( index, alias, element_size ); + return index; +} + +u32 af_compile_string( af_compiler *compiler, const char *string ) +{ + u32 string_hash = vg_strdjb2( string ); + + // TODO: Hash table against existing strings (low priority) + + u32 offset = offset = compiler->strings_index->element_count; + u32 bytes = vg_align4( strlen( string )+1 + 4 ); + af_compiler_item *item = af_compiler_allocate_items( compiler, compiler->strings_index, bytes ); + *((u32 *)item->data) = string_hash; + strcpy( item->data+4, string ); + return offset; +} + +void af_compiler_init( af_compiler *compiler, void *allocator ) +{ + compiler->allocator = allocator; + af_compiler_init_index( &compiler->index, "index", sizeof(af_compiler_index) ); + compiler->strings_index = af_compiler_create_index( compiler, "strings", 1 ); + af_compile_string( compiler, "nul" ); +} + +static void af_write_bin( af_compiler *compiler, void *data, u32 data_len, u32 padding ) +{ + if( data ) + { + fwrite( data, data_len, 1, compiler->fp ); + compiler->file_offset += data_len; + } + + if( padding ) + { + while( compiler->file_offset % padding ) + { + const u8 pad_byte = 0xac; + fwrite( &pad_byte, 1, 1, compiler->fp ); + compiler->file_offset ++; + } + } +} + +af_compiler_index *af_get_or_make_index( af_compiler *compiler, const char *alias, u32 element_size ) +{ + struct af_compiler_iter iter; + af_init_iterator( &iter, &compiler->index ); + while( af_next( &iter ) ) + { + af_compiler_index *index = iter.data; + + if( !strcmp( index->name, alias ) ) + { + return index; + } + } + + return af_compiler_create_index( compiler, alias, element_size ); +} + +bool af_write( af_compiler *compiler, const char *path, u32 version ) +{ + u32 indices_to_write = 0; + + struct af_compiler_iter iter; + af_init_iterator( &iter, &compiler->index ); + while( af_next( &iter ) ) + { + af_compiler_index *index = iter.data; + + if( index->element_count ) + indices_to_write ++; + } + + u32 header_size = vg_align8( sizeof( array_file_header ) ); + u32 index_size = vg_align8( sizeof( array_file_meta ) * indices_to_write ); + + compiler->fp = fopen( path, "wb" ); + if( !compiler->fp ) + return 0; + compiler->file_offset = 0; + + array_file_header header; + header.version = version; + header.index.file_offset = header_size; + header.index.item_count = indices_to_write; + header.index.item_size = sizeof(array_file_meta); + strcpy( header.index.name, "index" ); + af_write_bin( compiler, &header, sizeof(array_file_header), 8 ); + + /* write index */ + u32 file_offset = header_size + index_size; + af_init_iterator( &iter, &compiler->index ); + while( af_next( &iter ) ) + { + af_compiler_index *index = iter.data; + + if( index->element_count ) + { + array_file_meta meta; + strcpy( meta.name, index->name ); + meta.item_count = index->element_count; + meta.item_size = index->element_size; + meta.file_offset = file_offset; + + file_offset += vg_align8( meta.item_size*meta.item_count ); + af_write_bin( compiler, &meta, sizeof(array_file_meta), 0 ); + } + } + af_write_bin( compiler, NULL, 0, 8 ); + + + af_init_iterator( &iter, &compiler->index ); + while( af_next( &iter ) ) + { + af_compiler_index *index = iter.data; + + if( index->element_count ) + { + struct af_compiler_iter item_iter; + af_init_iterator( &item_iter, index ); + + while( af_next( &item_iter ) ) + af_write_bin( compiler, item_iter.data, index->element_size, 0 ); + + af_write_bin( compiler, NULL, 0, 8 ); + } + } + + fclose( compiler->fp ); + return 1; +} diff --git a/src/array_file.h b/src/array_file.h index 1dfa185..973a282 100644 --- a/src/array_file.h +++ b/src/array_file.h @@ -1,10 +1,10 @@ #pragma once +//#include "vg/submodules/hashmap.c/hashmap.h" typedef struct array_file_ptr array_file_ptr; typedef struct array_file_meta array_file_meta; typedef struct array_file_header array_file_header; typedef struct array_file_context array_file_context; - struct array_file_ptr { void *data; @@ -34,8 +34,7 @@ struct array_file_context const void *strings; }; -void af_open( array_file_context *ctx, const char *path, - u32 min_version, u32 max_version, void *lin_alloc ); +void af_open( array_file_context *ctx, const char *path, u32 min_version, u32 max_version, void *lin_alloc ); void af_close( array_file_context *ctx ); /* array loading */ @@ -56,8 +55,50 @@ u32 af_arrcount( array_file_ptr *arr ); /* packed string buffer access (with djb2 hash prefix) */ const char *af_str( array_file_context *af, u32 pstr ); u32 af_str_hash( array_file_context *af, u32 pstr ); -bool af_str_eq( array_file_context *af, u32 pstr, - const char *str, u32 str_hash ); +bool af_str_eq( array_file_context *af, u32 pstr, const char *str, u32 str_hash ); #define AF_STR_EQ( CTX, PSTR, CONSTR ) \ af_str_eq( CTX, PSTR, CONSTR, vg_strdjb2( CONSTR ) ) + + +/* COmpiler + * ------------------------------------ */ + +typedef struct af_compiler af_compiler; +typedef struct af_compiler_item af_compiler_item; +typedef struct af_compiler_index af_compiler_index; + +struct af_compiler_item +{ + void *data; + u32 count; + af_compiler_item *next; +}; + +struct af_compiler_index +{ + char name[16]; + u32 element_size, element_count; + + af_compiler_item *first, *last; +}; + +struct af_compiler +{ + void *allocator; + + af_compiler_index index, + *strings_index; + + af_compiler_item *most_recent_item; + + FILE *fp; + u32 file_offset; +}; + +void af_compiler_init( af_compiler *compiler, void *allocator ); +af_compiler_item *af_compiler_allocate_items( af_compiler *compiler, af_compiler_index *index, u32 count ); +af_compiler_index *af_compiler_create_index( af_compiler *compiler, const char *alias, u32 element_size ); +bool af_write( af_compiler *compiler, const char *path, u32 version ); +af_compiler_index *af_get_or_make_index( af_compiler *compiler, const char *alias, u32 element_size ); +u32 af_compile_string( af_compiler *compiler, const char *string ); diff --git a/src/board_maker.c b/src/board_maker.c index 1d6cde5..af05a51 100644 --- a/src/board_maker.c +++ b/src/board_maker.c @@ -107,6 +107,11 @@ static void _board_maker_load_template( void *_ ) mdl_context *mdl = &_board_maker.template_mdl; mdl_open( mdl, mdl_path, _board_maker.template_heap ); mdl_load_metadata_block( mdl, _board_maker.template_heap ); + + /* we need this for compiling it back down */ + mdl_load_mesh_block( mdl, _board_maker.template_heap ); + AF_LOAD_ARRAY_STRUCT( &mdl->af, &_board_maker.template_mdl_markers, ent_marker, _board_maker.template_heap ); + mdl_async_full_load_std( mdl, NULL ); mdl_close( mdl ); @@ -127,6 +132,75 @@ static void _board_maker_init_thread( void *_ ) vg_async_call( _async_board_maker_init_finish, NULL, 0 ); } +static void _board_maker_export(void) +{ + mdl_compiler compiler; + mdl_compiler_init( &compiler ); + + qoi_desc desc = { + .width = 512, + .height = 512, + .channels = 3, + .colorspace = QOI_SRGB + }; + + void *raw_data = malloc( 512*512*3 ), + *qoi_data = malloc( vg_query_qoi_storage_size( &desc ) ); + + vg_framebuffer_bind( &_board_maker.compositor_fb, 1.0f ); + glReadBuffer( GL_COLOR_ATTACHMENT0 ); + glReadPixels( 0,0, 512,512, GL_RGB, GL_UNSIGNED_BYTE, raw_data ); + + i32 qoi_len; + if( !vg_encode_qoi2( raw_data, &desc, qoi_data, &qoi_len ) ) + { + free( raw_data ); + free( qoi_data ); + return; + } + + u32 onetex = mdl_compiler_compile_texture_qoi( &compiler, "Maker Tex", qoi_data, qoi_len ); + + free( raw_data ); + free( qoi_data ); + + u8 shader_buf[ 512 ]; + vg_msg shader_kvs; + vg_msg_init( &shader_kvs, shader_buf, sizeof(shader_buf) ); + vg_msg_wkvnum( &shader_kvs, "tex_diffuse", k_vg_msg_u32, 1, &onetex ); + + u32 onemat = mdl_compiler_start_material( &compiler, "Maker Mat" ); + mdl_compiler_push_shaderdata( &compiler, k_shader_standard, &shader_kvs ); + + for( u32 i=0; i<_board_maker.template_mdl.mesh_count; i ++ ) + { + mdl_mesh *ref_mesh = &_board_maker.template_mdl.meshes[i]; + if( mdl_entity_id_type( ref_mesh->entity_id ) != k_ent_marker ) + continue; + + mdl_submesh *ref_submesh = &_board_maker.template_mdl.submeshes[ ref_mesh->submesh_start ]; + + u32 ref_marker_index = mdl_entity_id_id( ref_mesh->entity_id ); + ent_marker *ref_marker = af_arritm( &_board_maker.template_mdl_markers, ref_marker_index ); + const char *ref_marker_alias = af_str( &_board_maker.template_mdl.af, ref_marker->pstr_alias ); + + ent_marker copy_marker = *ref_marker; + copy_marker.pstr_alias = af_compile_string( &compiler.af, ref_marker_alias ); + + u32 new_marker_id = mdl_compiler_push_entity( &compiler, k_ent_marker, + "ent_marker", ©_marker, sizeof(ent_marker) ); + mdl_compiler_start_mesh( &compiler, "", new_marker_id, 0 ); + mdl_compiler_start_submesh( &compiler, onemat, 0 ); + mdl_compiler_push_meshdata( &compiler, _board_maker.template_mdl.verts + ref_submesh->vertex_start, + ref_submesh->vertex_count, + _board_maker.template_mdl.indices + ref_submesh->indice_start, + ref_submesh->indice_count ); + } + + af_write( &compiler.af, "/tmp/hello.mdl", MDL_VERSION_NR ); + mdl_compiler_free( &compiler ); +} + /* update loop */ void _board_maker_pre_update(void) { @@ -223,6 +297,11 @@ void _board_maker_pre_update(void) _board_maker.state = k_board_maker_state_loading_image; } } + else if( _board_maker.state == k_board_maker_state_export ) + { + _board_maker_export(); + _board_maker.state = k_board_maker_state_none; + } } //vg_camera temp; @@ -254,7 +333,7 @@ void _board_maker_render( world_instance *world, vg_camera *cam ) q_axis_angle( qy, (v3f){0,1,0}, vg.time*0.2f ); q_mul( qx, qy, qq ); q_normalize( qq ); - q_m3x3( qq, root_mmdl ); + q_m3x3( qq, root_mmdl ); v3_copy( _board_maker.origin, root_mmdl[3] ); @@ -610,8 +689,10 @@ void _board_maker_ui( ui_context *ctx ) if( quit_me ) { - if( world_clear_event( k_world_event_board_maker ) ) - _board_maker_close(); + _board_maker.state = k_board_maker_state_export; + + //if( world_clear_event( k_world_event_board_maker ) ) + // _board_maker_close(); } } diff --git a/src/board_maker.h b/src/board_maker.h index 48763da..c8c0ef3 100644 --- a/src/board_maker.h +++ b/src/board_maker.h @@ -27,7 +27,7 @@ struct _board_maker v3f angles; mdl_context template_mdl; - array_file_ptr template_mdl_shader_data; + array_file_ptr template_mdl_markers; bool model_loaded; enum board_maker_state @@ -37,7 +37,8 @@ struct _board_maker k_board_maker_state_none, k_board_maker_state_loading_template, k_board_maker_state_load_image, - k_board_maker_state_loading_image + k_board_maker_state_loading_image, + k_board_maker_state_export } state; diff --git a/src/model.c b/src/model.c index 5f06e24..200452c 100644 --- a/src/model.c +++ b/src/model.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved + * Copyright (C) 2021-2025 Mt.ZERO Software, Harry Godden - All Rights Reserved */ #pragma once @@ -34,7 +34,7 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst ) vg_fatal_exit(); } - fseek( mdl->af.fp, mdl->pack_base_offset+info->pack_offset, SEEK_SET ); + fseek( mdl->af.fp, mdl->pack_base_offset + info->pack_offset, SEEK_SET ); u64 l = fread( dst, info->pack_size, 1, mdl->af.fp ); if( l != 1 ) @@ -84,19 +84,14 @@ void mdl_load_metadata_block( mdl_context *mdl, void *lin_alloc ) void *mdl_shader_standard( vg_msg *msg, void *alloc ) { - struct shader_props_standard *props = - vg_linear_alloc( alloc, sizeof(struct shader_props_standard) ); - - vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, - NULL ); + struct shader_props_standard *props = vg_linear_alloc( alloc, sizeof(struct shader_props_standard) ); + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, NULL ); return props; } void *mdl_shader_terrain( vg_msg *msg, void *alloc ) { - struct shader_props_terrain *props = - vg_linear_alloc( alloc, sizeof(struct shader_props_terrain) ); - + struct shader_props_terrain *props = vg_linear_alloc( alloc, sizeof(struct shader_props_terrain) ); vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, NULL ); vg_msg_getkvvecf( msg, "sand_colour", k_vg_msg_v4f, props->sand_colour, (v4f){ 0.79, 0.63, 0.48, 1.0 } ); vg_msg_getkvvecf( msg, "blend_offset", k_vg_msg_v2f, props->blend_offset, (v2f){ 0.5, 0.0 } ); @@ -106,33 +101,21 @@ void *mdl_shader_terrain( vg_msg *msg, void *alloc ) void *mdl_shader_vertex_blend( vg_msg *msg, void *alloc ) { - struct shader_props_vertex_blend *props = - vg_linear_alloc( alloc, sizeof(struct shader_props_vertex_blend) ); - - vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, - NULL ); - vg_msg_getkvvecf( msg, "blend_offset", k_vg_msg_v2f, - props->blend_offset, (v2f){ 0.5, 0.0 } ); + struct shader_props_vertex_blend *props = vg_linear_alloc( alloc, sizeof(struct shader_props_vertex_blend) ); + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, NULL ); + vg_msg_getkvvecf( msg, "blend_offset", k_vg_msg_v2f, props->blend_offset, (v2f){ 0.5, 0.0 } ); return props; } void *mdl_shader_water( vg_msg *msg, void *alloc ) { - struct shader_props_water *props = - vg_linear_alloc( alloc, sizeof(struct shader_props_water) ); - - vg_msg_getkvvecf( msg, "shore_colour", k_vg_msg_v4f, - props->shore_colour, (v4f){0.03,0.32,0.61,1.0} ); - vg_msg_getkvvecf( msg, "deep_colour", k_vg_msg_v4f, - props->deep_colour, (v4f){0.0,0.006,0.03,1.0} ); - vg_msg_getkvintg( msg, "fog_scale", k_vg_msg_f32, &props->fog_scale, - (f32[]){0.04} ); - vg_msg_getkvintg( msg, "fresnel", k_vg_msg_f32, &props->fresnel, - (f32[]){5.0} ); - vg_msg_getkvintg( msg, "water_scale", k_vg_msg_f32, &props->water_sale, - (f32[]){ 0.008 } ); - vg_msg_getkvvecf( msg, "wave_speed", k_vg_msg_v4f, - props->wave_speed, (v4f){0.008,0.006,0.003,0.03} ); + struct shader_props_water *props = vg_linear_alloc( alloc, sizeof(struct shader_props_water) ); + vg_msg_getkvvecf( msg, "shore_colour", k_vg_msg_v4f, props->shore_colour, (v4f){0.03,0.32,0.61,1.0} ); + vg_msg_getkvvecf( msg, "deep_colour", k_vg_msg_v4f, props->deep_colour, (v4f){0.0,0.006,0.03,1.0} ); + vg_msg_getkvintg( msg, "fog_scale", k_vg_msg_f32, &props->fog_scale, (f32[]){0.04} ); + vg_msg_getkvintg( msg, "fresnel", k_vg_msg_f32, &props->fresnel, (f32[]){5.0} ); + vg_msg_getkvintg( msg, "water_scale", k_vg_msg_f32, &props->water_sale, (f32[]){ 0.008 } ); + vg_msg_getkvvecf( msg, "wave_speed", k_vg_msg_v4f, props->wave_speed, (v4f){0.008,0.006,0.003,0.03} ); return props; } @@ -141,12 +124,9 @@ void *mdl_shader_cubemapped( vg_msg *msg, void *alloc ) struct shader_props_cubemapped *props = vg_linear_alloc( alloc, sizeof(struct shader_props_cubemapped) ); - vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, - NULL ); - vg_msg_getkvintg( msg, "cubemap_entity", k_vg_msg_u32, - &props->cubemap_entity, NULL ); - vg_msg_getkvvecf( msg, "tint", k_vg_msg_v4f, - props->tint, (v4f){1.0,1.0,1.0,1.0} ); + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, NULL ); + vg_msg_getkvintg( msg, "cubemap_entity", k_vg_msg_u32, &props->cubemap_entity, NULL ); + vg_msg_getkvvecf( msg, "tint", k_vg_msg_v4f, props->tint, (v4f){1.0,1.0,1.0,1.0} ); return props; } @@ -215,8 +195,7 @@ void mdl_load_materials( mdl_context *mdl, void *lin_alloc ) array_file_ptr legacy_materials; if( mdl->version <= 105 ) { - af_load_array( &mdl->af, &legacy_materials, "mdl_material", - vg_mem.scratch, sizeof(struct mdl_material_v105) ); + af_load_array( &mdl->af, &legacy_materials, "mdl_material", vg_mem.scratch, sizeof(struct mdl_material_v105) ); } #endif @@ -287,8 +266,10 @@ void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc ) mdl->version = mdl->af.header.version; array_file_meta *pack = af_find_array( &mdl->af, "pack" ); - if( pack ) mdl->pack_base_offset = pack->file_offset; - else mdl->pack_base_offset = 0; + if( pack ) + mdl->pack_base_offset = pack->file_offset; + else + mdl->pack_base_offset = 0; } /* @@ -316,9 +297,7 @@ void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx ) */ #ifdef VG_3D -static void mesh_upload( glmesh *mesh, - mdl_vert *verts, u32 vert_count, - u32 *indices, u32 indice_count ) +static void mesh_upload( glmesh *mesh, mdl_vert *verts, u32 vert_count, u32 *indices, u32 indice_count ) { glGenVertexArrays( 1, &mesh->vao ); glGenBuffers( 1, &mesh->vbo ); @@ -332,36 +311,30 @@ static void mesh_upload( glmesh *mesh, glBindVertexArray( mesh->vao ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32), - indices, GL_STATIC_DRAW ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32), indices, GL_STATIC_DRAW ); /* 0: coordinates */ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0 ); glEnableVertexAttribArray( 0 ); /* 1: normal */ - glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, - stride, (void *)offsetof(mdl_vert, norm) ); + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, (void *)offsetof(mdl_vert, norm) ); glEnableVertexAttribArray( 1 ); /* 2: uv */ - glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, - stride, (void *)offsetof(mdl_vert, uv) ); + glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, stride, (void *)offsetof(mdl_vert, uv) ); glEnableVertexAttribArray( 2 ); /* 3: colour */ - glVertexAttribPointer( 3, 4, GL_UNSIGNED_BYTE, GL_TRUE, - stride, (void *)offsetof(mdl_vert, colour) ); + glVertexAttribPointer( 3, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void *)offsetof(mdl_vert, colour) ); glEnableVertexAttribArray( 3 ); /* 4: weights */ - glVertexAttribPointer( 4, 4, GL_UNSIGNED_SHORT, GL_TRUE, - stride, (void *)offsetof(mdl_vert, weights) ); + glVertexAttribPointer( 4, 4, GL_UNSIGNED_SHORT, GL_TRUE, stride, (void *)offsetof(mdl_vert, weights) ); glEnableVertexAttribArray( 4 ); /* 5: groups */ - glVertexAttribIPointer( 5, 4, GL_UNSIGNED_BYTE, - stride, (void *)offsetof(mdl_vert, groups) ); + glVertexAttribIPointer( 5, 4, GL_UNSIGNED_BYTE, stride, (void *)offsetof(mdl_vert, groups) ); glEnableVertexAttribArray( 5 ); mesh->indice_count = indice_count; @@ -375,8 +348,7 @@ void mesh_bind( glmesh *mesh ) void mesh_drawn( u32 start, u32 count ) { - glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, - (void *)(start*sizeof(u32)) ); + glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, (void *)(start*sizeof(u32)) ); } void mesh_draw( glmesh *mesh ) @@ -438,8 +410,7 @@ struct payload_glmesh_load static void _sync_mdl_load_glmesh( void *payload, u32 size ) { struct payload_glmesh_load *job = payload; - mesh_upload( job->mesh, job->verts, job->vertex_count, - job->indices, job->indice_count ); + mesh_upload( job->mesh, job->verts, job->vertex_count, job->indices, job->indice_count ); } void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table ) @@ -465,10 +436,8 @@ void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table ) job->vertex_count = arr_vertices->item_count; job->indice_count = arr_indices->item_count; - af_load_array_file_buffer( &mdl->af, arr_vertices, - job->verts, sizeof(mdl_vert) ); - af_load_array_file_buffer( &mdl->af, arr_indices, job->indices, - sizeof(mdl_indice) ); + af_load_array_file_buffer( &mdl->af, arr_vertices, job->verts, sizeof(mdl_vert) ); + af_load_array_file_buffer( &mdl->af, arr_indices, job->indices, sizeof(mdl_indice) ); if( fixup_table ) { @@ -548,3 +517,133 @@ void mdl_sync_std_unload( mdl_context *mdl ) } #endif + +void mdl_compiler_init( mdl_compiler *compiler ) +{ + af_compiler_init( &compiler->af, _vg_create_linear_allocator( NULL, 10*1024*1024, VG_MEMORY_SYSTEM, "MDL Compile" ) ); + compiler->meshes = af_compiler_create_index( &compiler->af, "mdl_mesh", sizeof(mdl_mesh) ); + compiler->submeshes = af_compiler_create_index( &compiler->af, "mdl_submesh", sizeof(mdl_submesh) ); + compiler->vertices = af_compiler_create_index( &compiler->af, "mdl_vert", sizeof(mdl_vert) ); + compiler->indices = af_compiler_create_index( &compiler->af, "mdl_indice", sizeof(u32) ); + compiler->bones = af_compiler_create_index( &compiler->af, "mdl_bone", sizeof(mdl_bone) ); + compiler->materials = af_compiler_create_index( &compiler->af, "mdl_material", sizeof(mdl_material) ); + compiler->shader_data = af_compiler_create_index( &compiler->af, "shader_data", 1 ); + compiler->armatures = af_compiler_create_index( &compiler->af, "mdl_armature", sizeof(mdl_armature) ); + compiler->textures = af_compiler_create_index( &compiler->af, "mdl_texture", sizeof(mdl_texture) ); + compiler->pack_data = af_compiler_create_index( &compiler->af, "pack", 1 ); +} + +u32 mdl_compiler_push_entity( mdl_compiler *compiler, u32 entity_type, const char *entity_type_string, + void *data, u32 data_size ) +{ + af_compiler_index *index = af_get_or_make_index( &compiler->af, entity_type_string, data_size ); + + u32 index_part = index->element_count, + id = (entity_type & 0xfffff)<<16 | (index_part & 0xfffff); //TODO + + af_compiler_item *item = af_compiler_allocate_items( &compiler->af, index, 1 ); + memcpy( item->data, data, data_size ); + return id; +} + +void mdl_compiler_start_mesh( mdl_compiler *compiler, const char *name, u32 associated_entity, u32 associated_armature ) +{ + mdl_mesh *mesh = af_compiler_allocate_items( &compiler->af, compiler->meshes, 1 )->data; + transform_identity( &mesh->transform ); + mesh->submesh_start = compiler->submeshes->element_count; + mesh->submesh_count = 0; + mesh->pstr_name = af_compile_string( &compiler->af, name ); + mesh->entity_id = associated_entity; + mesh->armature_id = associated_armature; +} + +void mdl_compiler_start_submesh( mdl_compiler *compiler, u32 material_id, u32 flags ) +{ + mdl_mesh *current_mesh = compiler->meshes->last->data; + current_mesh->submesh_count ++; + + mdl_submesh *sm = af_compiler_allocate_items( &compiler->af, compiler->submeshes, 1 )->data; + sm->indice_start = compiler->indices->element_count; + sm->vertex_start = compiler->vertices->element_count; + sm->indice_count = 0; + sm->vertex_count = 0; + sm->material_id = material_id; + sm->flags = flags; + box_init_inf( sm->bbx ); +} + +void mdl_compiler_push_meshdata( mdl_compiler *compiler, mdl_vert *vertex_buffer, u32 vertex_count, + u32 *indice_buffer, u32 indice_count ) +{ + mdl_submesh *current_submesh = compiler->submeshes->last->data; + current_submesh->vertex_count += vertex_count; + current_submesh->indice_count += indice_count; + + mdl_vert *dest_verts = af_compiler_allocate_items( &compiler->af, compiler->vertices, vertex_count )->data; + u32 *dest_indices = af_compiler_allocate_items( &compiler->af, compiler->indices, indice_count )->data; + + for( u32 i=0; ibbx, vertex_buffer[i].co ); + + memcpy( dest_verts, vertex_buffer, vertex_count * sizeof(mdl_vert) ); + memcpy( dest_indices, indice_buffer, indice_count * sizeof(u32) ); +} + +static void mdl_compiler_pack_data( mdl_compiler *compiler, const char *path, void *data, + u32 data_length, mdl_file *out_file ) +{ + out_file->pstr_path = af_compile_string( &compiler->af, path ); + out_file->pack_offset = compiler->pack_data->element_count; + out_file->pack_size = data_length; + + void *dest = af_compiler_allocate_items( &compiler->af, compiler->pack_data, vg_align16(data_length) )->data; + memcpy( dest, data, data_length ); +} + +u32 mdl_compiler_start_material( mdl_compiler *compiler, const char *name ) +{ + u32 material_id = compiler->materials->element_count + 1; + + mdl_material *material = af_compiler_allocate_items( &compiler->af, compiler->materials, 1 )->data; + material->pstr_name = af_compile_string( &compiler->af, name ); + material->shader = 0; + material->flags = 0; + material->surface_prop = 0; + material->props.kvs.offset = 0; + material->props.kvs.size = 0; + + return material_id; +} + +void mdl_compiler_set_surface_info( mdl_compiler *compiler, u32 flags, u32 surface_prop ) +{ + mdl_material *current_material = compiler->materials->last->data; + current_material->flags = flags; + current_material->surface_prop = surface_prop; +} + +u32 mdl_compiler_compile_texture_qoi( mdl_compiler *compiler, const char *name, void *data, u32 data_len ) +{ + u32 texture_id = compiler->textures->element_count + 1; + + mdl_texture *texture = af_compiler_allocate_items( &compiler->af, compiler->textures, 1 )->data; + texture->glname = 0; + mdl_compiler_pack_data( compiler, name, data, data_len, &texture->file ); + return texture_id; +} + +void mdl_compiler_push_shaderdata( mdl_compiler *compiler, u32 shader_id, vg_msg *shader_kvs ) +{ + mdl_material *current_material = compiler->materials->last->data; + current_material->shader = shader_id; + current_material->props.kvs.offset = compiler->shader_data->element_count; + current_material->props.kvs.size = shader_kvs->cur.co; + + void *dest = af_compiler_allocate_items( &compiler->af, compiler->shader_data, vg_align8(shader_kvs->cur.co) )->data; + memcpy( dest, shader_kvs->buf, shader_kvs->cur.co ); +} + +void mdl_compiler_free( mdl_compiler *compiler ) +{ + vg_allocator_free( compiler->af.allocator ); +} diff --git a/src/model.h b/src/model.h index 4e79695..43dd7fa 100644 --- a/src/model.h +++ b/src/model.h @@ -315,3 +315,21 @@ mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name ); void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx ); +/* model compiler + * --------------------------------- */ + +typedef struct mdl_compiler mdl_compiler; +struct mdl_compiler +{ + af_compiler af; + af_compiler_index *meshes, + *submeshes, + *vertices, + *indices, + *bones, + *materials, + *shader_data, + *armatures, + *textures, + *pack_data; +}; diff --git a/src/player_render.c b/src/player_render.c index 01350be..3eb0ba1 100644 --- a/src/player_render.c +++ b/src/player_render.c @@ -125,7 +125,6 @@ void player_board_load( player_board *board, const char *path, void *arena ) array_file_ptr markers; AF_LOAD_ARRAY_STRUCT( &board->mdl.af, &markers, ent_marker, vg_mem.scratch ); - /* TODO: you get put into a new section, the above is standard mdl loads. */ for( int i=0; i<4; i++ ) board->wheels[i].indice_count = 0; for( int i=0; i<2; i++ ) diff --git a/src/skaterift.c b/src/skaterift.c index 9ca0420..ad67833 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -618,3 +618,6 @@ void vg_framebuffer_resize( int w, int h ) #include "ent_camera.c" #include "skaterift_script.c" #include "board_maker.c" + +//TODO +//#include "vg/submodules/hashmap.c/hashmap.c" -- 2.25.1