+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 );
+
+ 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) );
+
+ 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 } );
+
+ return props;
+}
+
+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 } );
+ 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} );
+ return props;
+}
+
+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} );
+ return props;
+}
+
+bool _mdl_legacy_v105_properties( struct mdl_material_v105 *mat, vg_msg *dst )
+{
+ vg_msg_wkvnum( dst, "tex_diffuse", k_vg_msg_u32, 1, &mat->tex_diffuse );
+
+ if( mat->shader == k_shader_cubemap )
+ {
+ vg_msg_wkvnum( dst, "cubemap", k_vg_msg_u32, 1, &mat->tex_none0 );
+ vg_msg_wkvnum( dst, "tint", k_vg_msg_f32, 4, mat->colour );
+ }
+ else if( mat->shader == k_shader_terrain_blend )
+ {
+ vg_msg_wkvnum( dst, "sand_colour", k_vg_msg_f32, 4, mat->colour );
+ vg_msg_wkvnum( dst, "blend_offset", k_vg_msg_f32, 2, mat->colour1 );
+ }
+ else if( mat->shader == k_shader_standard_vertex_blend )
+ {
+ vg_msg_wkvnum( dst, "blend_offset", k_vg_msg_f32, 2, mat->colour1 );
+ }
+ else if( mat->shader == k_shader_water )
+ {
+ vg_msg_wkvnum( dst, "shore_colour", k_vg_msg_f32, 4, mat->colour );
+ vg_msg_wkvnum( dst, "deep_colour", k_vg_msg_f32, 4, mat->colour1 );
+ }
+
+ return 1;
+}
+
+int mdl_load_materials( mdl_context *mdl, void *lin_alloc )
+{
+ MDL_LOAD_ARRAY( mdl, &mdl->materials, mdl_material, lin_alloc );
+
+#if (MDL_VERSION_MIN <= 105)
+ /* load legacy material data into scratch */
+ mdl_array_ptr legacy_materials;
+ if( mdl->info.version <= 105 )
+ {
+ _mdl_load_array( mdl, &legacy_materials, "mdl_material", vg_mem.scratch,
+ sizeof(struct mdl_material_v105) );
+ }
+#endif
+
+ mdl_array_ptr data;
+ _mdl_load_array( mdl, &data, "shader_data", vg_mem.scratch, 1 );
+
+ for( u32 i=0; i<mdl_arrcount(&mdl->materials); i ++ )
+ {
+ mdl_material *mat = mdl_arritm( &mdl->materials, i );
+ vg_msg msg;
+
+#if (MDL_VERSION_MIN <= 105)
+ u8 legacy_buf[512];
+ if( mdl->info.version <= 105 )
+ {
+ vg_msg_init( &msg, legacy_buf, sizeof(legacy_buf) );
+ _mdl_legacy_v105_properties( mdl_arritm( &legacy_materials,i ), &msg );
+ vg_msg_init( &msg, legacy_buf, msg.cur.co );
+ }
+ else
+#endif
+ {
+ vg_msg_init( &msg, data.data + mat->props.kvs.offset,
+ mat->props.kvs.size );
+ }
+
+ if( mat->shader == k_shader_standard ||
+ mat->shader == k_shader_standard_cutout ||
+ mat->shader == k_shader_foliage ||
+ mat->shader == k_shader_fxglow )
+ {
+ mat->props.compiled = mdl_shader_standard( &msg, lin_alloc );
+ }
+ else if( mat->shader == k_shader_standard_vertex_blend )
+ {
+ mat->props.compiled = mdl_shader_vertex_blend( &msg, lin_alloc );
+ }
+ else if( mat->shader == k_shader_cubemap )
+ {
+ mat->props.compiled = mdl_shader_cubemapped( &msg, lin_alloc );
+ }
+ else if( mat->shader == k_shader_terrain_blend )
+ {
+ mat->props.compiled = mdl_shader_terrain( &msg, lin_alloc );
+ }
+ else if( mat->shader == k_shader_water )
+ {
+ mat->props.compiled = mdl_shader_water( &msg, lin_alloc );
+ }
+ else
+ mat->props.compiled = NULL;
+ }
+
+ return 1;
+}
+