Array file compiler for C side, board maker compiler
authorhgn <hgodden00@gmail.com>
Sat, 22 Mar 2025 02:45:51 +0000 (02:45 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 22 Mar 2025 02:45:51 +0000 (02:45 +0000)
build.c
skaterift_blender/sr_bin.py
skaterift_blender/sr_mdl.py
src/array_file.c
src/array_file.h
src/board_maker.c
src/board_maker.h
src/model.c
src/model.h
src/player_render.c
src/skaterift.c

diff --git a/build.c b/build.c
index 59ea1a045ce5c690ec8650d31c4d26950d0dda41..8024a3b3d651a56126d4309e6263884a6c57bea4 100644 (file)
--- 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 ) 
index 74e452f0ebf3ca2a62b80678eea4777f50c7249b..882b2db3ce2495f3266ceeb9c03e257f683a395b 100644 (file)
@@ -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 )
index 4ea8827b43267eb2ae21911f6b4c1f4403426357..b08faaddff44e5bf692452fa188466f63e88dc41 100644 (file)
@@ -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 )
 #}
index 79a8f82e24541139c8a51e42a7389d9dd58bddd4..c786d5a7f6dde4900fdfc80f266f0d074a0e5a11 100644 (file)
@@ -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; i<data_size; i ++ )
+      ((u8 *)entry->data)[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;
+}
index 1dfa185d76e9817048e2c27b27cab3c392dcf8ee..973a282f33fcfcef49263f10dee1b99dc79f9706 100644 (file)
@@ -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 );
index 1d6cde53c3c3cea1eb9ee251201207cc3e158fba..af05a514c517d30da322fdb641849158152d9c15 100644 (file)
@@ -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", &copy_marker, sizeof(ent_marker) );
+      mdl_compiler_start_mesh( &compiler, "<board_maker>", 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();
    }
 }
 
index 48763dac5cfa874ed2b5ef44a962227974c90d50..c8c0ef3c8846ae27ea232ad88e386132e3d4602d 100644 (file)
@@ -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;
 
index 5f06e24f7e0b7fd6851fc35cdca0f941bc05e02b..200452c1b2401da29fb4793300f3cdb8acc28225 100644 (file)
@@ -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; i<vertex_count; i ++ )
+      box_addpt( current_submesh->bbx, 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 );
+}
index 4e79695ff681176131ac4b5a2c837ba984e1e7a6..43dd7fa36e16c9db2c50d7676002998ac3540062 100644 (file)
@@ -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;
+};
index 01350be8fba6a4851c2ba709fb2c6ff2561ed5cf..3eb0ba1f61f605e9ba800ab0f3c717876e208edf 100644 (file)
@@ -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++ )
index 9ca042097d624514114050427944ac8161052ab0..ad678330437ba899305ab73946b5d92ef3445a18 100644 (file)
@@ -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"