board compositor basics
authorhgn <hgodden00@gmail.com>
Wed, 19 Mar 2025 03:14:28 +0000 (03:14 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 19 Mar 2025 03:14:28 +0000 (03:14 +0000)
22 files changed:
build.c
content_skaterift/maps/dev_flatworld/main.mdl
content_skaterift/maps/mp_spawn/main.mdl
content_skaterift/models/workshop/regular.mdl [new file with mode: 0644]
shaders/workshop_compositor.fs [new file with mode: 0644]
shaders/workshop_compositor.vs [new file with mode: 0644]
skaterift_blender/sr_main.py
skaterift_blender/sr_mat.py
src/board_maker.c [new file with mode: 0644]
src/board_maker.h [new file with mode: 0644]
src/menu.c
src/model.c
src/model.h
src/player_remote.c
src/scripts/generic.c [new file with mode: 0644]
src/shader_props.h
src/skaterift.c
src/skaterift_script.c
src/utest.c
src/workshop.c
src/world.h
src/world_render.c

diff --git a/build.c b/build.c
index 3ea8b8def702936a027edd04c5a92be57782515e..59ea1a045ce5c690ec8650d31c4d26950d0dda41 100644 (file)
--- a/build.c
+++ b/build.c
@@ -189,6 +189,7 @@ void build_shaders(void){
 
    /* 2D */
    //_S( "blit",      "blit.vs",      "blit.fs" );
+   _S( "workshop_compositor", "workshop_compositor.vs", "workshop_compositor.fs" );
    _S( "blitblur",  "blit.vs",      "blitblur.fs" );
    _S( "blitcolour","blit.vs",      "colour.fs" );
    _S( "blit_transition", "blit.vs", "blit_transition.fs" );
index f9c326c23a11b9d075b46f34f7c6a37b42530e59..36d5e52ff875c595226faa3f43ca7352281fe3c3 100644 (file)
Binary files a/content_skaterift/maps/dev_flatworld/main.mdl and b/content_skaterift/maps/dev_flatworld/main.mdl differ
index 5862ad453581cb8e668e79a1457e9dabf23051e4..99025d207b2c736700d03c69700667c7373ad355 100644 (file)
Binary files a/content_skaterift/maps/mp_spawn/main.mdl and b/content_skaterift/maps/mp_spawn/main.mdl differ
diff --git a/content_skaterift/models/workshop/regular.mdl b/content_skaterift/models/workshop/regular.mdl
new file mode 100644 (file)
index 0000000..dc4952f
Binary files /dev/null and b/content_skaterift/models/workshop/regular.mdl differ
diff --git a/shaders/workshop_compositor.fs b/shaders/workshop_compositor.fs
new file mode 100644 (file)
index 0000000..7011c33
--- /dev/null
@@ -0,0 +1,11 @@
+out vec4 FragColor;
+uniform sampler2D uTexMain;
+
+uniform vec4 uColour;
+
+in vec2 aUv;
+
+void main()
+{
+   FragColor = texture( uTexMain, aUv ) * uColour;
+}
diff --git a/shaders/workshop_compositor.vs b/shaders/workshop_compositor.vs
new file mode 100644 (file)
index 0000000..2593725
--- /dev/null
@@ -0,0 +1,8 @@
+layout (location=0) in vec2 a_co;
+out vec2 aUv;
+
+void main()
+{
+   gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);
+   aUv = a_co;
+}
index c84112cf6c77081b9d468c662ea8059a3b9e2ddf..0ced07b2fd2ae47e75ab0f9fe994131b1e30bc95 100644 (file)
@@ -1089,9 +1089,12 @@ class SR_MATERIAL_PANEL(bpy.types.Panel):
 
       info = material_info( active_mat )
 
-      if 'tex_diffuse' in info:#{
-         _.layout.label( icon='INFO', \
-            text=F"{info['tex_diffuse'].name} will be compiled" )
+      for prop in info:
+      #{
+         if type(info[prop]) == bpy.types.Image:
+         #{
+            _.layout.label( icon='INFO', text=F"{info[prop].name} will be compiled" )
+         #}
       #}
 
       _.layout.prop( active_mat.SR_data, "shader" )
@@ -2175,7 +2178,8 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup):
       ('fxglow','FX Glow',''),
       ('cubemap','Cubemap',''),
       ('walking','Walking',''),
-      ('foliage','Foliage','')
+      ('foliage','Foliage',''),
+      ('workshop','Workshop','')
       ])
 
    surface_prop: bpy.props.EnumProperty(
index 66e926181ac5b49e69c865197796de49a2eb161c..35396666570f7a38fcbb22c19ac59ebbcc19608f 100644 (file)
@@ -38,6 +38,18 @@ cxr_graph_mapping = \
    "Emission":
    {
       "Color": material_tex_image("tex_diffuse")
+   },
+   "Workshop":
+   {
+      "Truck1": material_tex_image("truck1"),
+      "Truck2": material_tex_image("truck2"),
+      "Wheel1": material_tex_image("wheel1"),
+      "Wheel2": material_tex_image("wheel2"),
+      "Wheel3": material_tex_image("wheel3"),
+      "Wheel4": material_tex_image("wheel4"),
+      "Edge": material_tex_image("edge"),
+      "Griptape": material_tex_image("griptape"),
+      "Deck": material_tex_image("deck"),
    }
 }
 
@@ -232,6 +244,18 @@ def sr_compile_material( mat ):
    #{
       m.shader = 9
    #}
+   if mat.SR_data.shader == 'workshop':
+   #{
+      m.shader = 11
+      
+      for prop in inf:
+      #{
+         if type(inf[prop]) == bpy.types.Image:
+         #{
+            shader_prop_texture( msg, prop, inf[prop] )
+         #}
+      #}
+   #}
 
    # sr_lib.vg_msg_print( byref(msg), msg.cur.co )
 
diff --git a/src/board_maker.c b/src/board_maker.c
new file mode 100644 (file)
index 0000000..e8b8a1f
--- /dev/null
@@ -0,0 +1,336 @@
+#include "board_maker.h"
+#include "shaders/workshop_compositor.h"
+
+struct _board_maker _board_maker = 
+{
+   .compositor_fb =
+   {
+      .display_name = "Workshop Compositor texture",
+      .resolution_div = 0,
+      .fixed_w = 512, .fixed_h = 512,
+      .attachments = (vg_framebuffer_attachment[])
+      {
+         {
+            .display_name = "RGBA",
+            .purpose = k_framebuffer_attachment_type_texture,
+            .quality = k_framebuffer_quality_all,
+            .internalformat = GL_RGBA,
+            .format         = GL_RGBA,
+            .type           = GL_UNSIGNED_BYTE,
+            .attachment     = GL_COLOR_ATTACHMENT0
+         }
+      },
+      .attachment_count = 1
+   }
+};
+
+/* model loader thread 
+ * ----------------------------------------- */
+
+static void _async_board_maker_load_finish( void *payload, u32 size )
+{
+   _board_maker.state = k_board_maker_state_none;
+   _board_maker.model_loaded = 1;
+   _board_maker.compositor_state = k_board_maker_compositor_dirty;
+
+   _board_maker.base_shader = NULL;
+
+   mdl_context *mdl = &_board_maker.template_mdl;
+   if( mdl->version <= 105 ) 
+      return;
+
+   if( mdl->material_count < 1 )
+      return;
+
+   mdl_material *mat0 = &mdl->materials[0];
+   if( mat0->shader != k_shader_workshop )
+      return;
+
+   _board_maker.base_shader = mat0->props.compiled;
+}
+
+static void _board_maker_load_template( void *_ )
+{
+   vg_linear_clear( _board_maker.template_heap );
+
+   const char *mdl_path = "models/workshop/regular.mdl";
+
+   if( _board_maker.board_type == k_board_maker_type_regular ){}
+
+   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 );
+   mdl_async_full_load_std( mdl, NULL );
+   mdl_close( mdl );
+
+   vg_async_call( _async_board_maker_load_finish, NULL, 0 );
+}
+
+/* system init thread 
+ * ----------------------------------------------------- */
+
+static void _async_board_maker_init_finish( void *payload, u32 size )
+{
+   _board_maker.state = k_board_maker_state_none;
+}
+
+static void _board_maker_init_thread( void *_ )
+{
+   vg_framebuffer_create( &_board_maker.compositor_fb );
+   vg_async_call( _async_board_maker_init_finish, NULL, 0 );
+}
+
+/* update loop */
+void _board_maker_pre_update(void)
+{
+   if( _world.event != k_world_event_board_maker )
+      return;
+
+   if( _board_maker.state == k_board_maker_state_none )
+   {
+      if( _board_maker.model_loaded )
+      {
+         if( _board_maker.compositor_state == k_board_maker_compositor_dirty )
+         {
+            vg_framebuffer_bind( &_board_maker.compositor_fb, 1.0f );
+            glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+            glClear( GL_COLOR_BUFFER_BIT );
+
+            glEnable(GL_BLEND);
+            glDisable(GL_DEPTH_TEST);
+            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glBlendEquation(GL_FUNC_ADD);
+
+            shader_workshop_compositor_use();
+            shader_workshop_compositor_uTexMain( 0 );
+
+            glActiveTexture( GL_TEXTURE0 );
+
+            if( _board_maker.base_shader )
+            {
+               for( u32 i=0; i<k_workshop_shader_part_max; i ++ )
+               {
+                  u32 tex_id = _board_maker.base_shader->tex_all[i];
+
+                  if( tex_id )
+                  {
+                     mdl_texture *tex = &_board_maker.template_mdl.textures[ tex_id-1 ];
+                     shader_workshop_compositor_uColour( _board_maker.colours[i] );
+                     glBindTexture( GL_TEXTURE_2D, tex->glname );
+                     vg_render_fullscreen_quad();
+                  }
+               }
+            }
+
+            glDisable(GL_BLEND);
+            glEnable(GL_DEPTH_TEST);
+
+            _board_maker.compositor_state = k_board_maker_compositor_done;
+         }
+      }
+      else
+      {
+         if( vg_loader_availible() )
+         {
+            _board_maker.state = k_board_maker_state_loading_template;
+            vg_loader_start( _board_maker_load_template, NULL );
+         }
+      }
+   }
+   else
+   {
+      if( _board_maker.state == k_board_maker_state_not_ready )
+      {
+         if( vg_loader_availible() )
+         {
+            _board_maker.state = k_board_maker_state_initializing;
+            vg_loader_start( _board_maker_init_thread, NULL );
+            return;
+         }
+      }
+   }
+
+   //vg_camera temp;
+   //ent_camera_unpack( af_arritm( &world->ent_camera, mdl_entity_id_id(challenge->camera_id) ), &temp );
+   //world_set_entity_driven_camera( &temp );
+}
+
+void _board_maker_render( world_instance *world, vg_camera *cam )
+{
+   if( _world.event != k_world_event_board_maker )
+      return;
+
+   if( _board_maker.model_loaded )
+   {
+      vg_framebuffer_bind_texture( &_board_maker.compositor_fb, 0, 0 );
+
+      shader_model_entity_use();
+      shader_model_entity_uTexMain( 0 );
+      shader_model_entity_uCamera( cam->transform[3] );
+      shader_model_entity_uPv( cam->mtx.pv );
+      
+      WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_entity );
+
+      m4x3f root_mmdl;
+      m4x3_identity( root_mmdl );
+
+      v4f qx, qy, qq;
+      q_axis_angle( qx, (v3f){1,0,0}, vg.time*0.1f );
+      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 );
+
+      v3_copy( _board_maker.origin, root_mmdl[3] );
+
+      mdl_context *mdl = &_board_maker.template_mdl;
+      mesh_bind( &mdl->mesh );
+
+      for( u32 i=0; i<mdl->mesh_count; i ++ )
+      {
+         mdl_mesh *mesh = &mdl->meshes[ i ];
+
+         m4x3f mmdl;
+         mdl_transform_m4x3( &mesh->transform, mmdl );
+         m4x3_mul( root_mmdl, mmdl, mmdl );
+
+         m4x4f m4mdl;
+         m4x3_expand( mmdl, m4mdl );
+         m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
+         shader_model_entity_uPvmPrev( m4mdl );
+         shader_model_entity_uMdl( mmdl );
+         
+         for( u32 j=0; j<mesh->submesh_count; j ++ )
+         {
+            mdl_submesh *sm = &mdl->submeshes[ mesh->submesh_start + j ];
+            mdl_draw_submesh( sm );
+         }
+      }
+   }
+}
+
+static void _board_maker_colour_button( ui_context *ctx, ui_rect rect, f32 *colour_pointer )
+{
+   enum ui_button_state state = ui_button_base( ctx, rect );
+
+   u32 colour = v4f_u32_colour( colour_pointer );
+   ui_fill( ctx, rect, colour );
+
+   if( state == k_ui_button_hover )
+      ui_outline( ctx, rect, -1, ui_colour( ctx, k_ui_fg ), 0 );
+
+   if( state == k_ui_button_click )
+   {
+      _board_maker.ui_target_colour = colour_pointer;
+      _board_maker.ui_state = k_board_maker_ui_state_pick_colour;
+      _board_maker.picker_panel[1] = rect[1];
+   }
+
+   if( state == k_ui_button_holding_outside )
+   {
+      _board_maker.ui_dropper_colour = colour_pointer;
+   }
+
+   if( ui_inside_rect( rect, ctx->mouse ) )
+   {
+      if( ui_click_up( ctx, UI_MOUSE_LEFT ) )
+      {
+         if( _board_maker.ui_dropper_colour )
+         {
+            v4_copy( _board_maker.ui_dropper_colour, colour_pointer );
+            _board_maker.compositor_state = k_board_maker_compositor_dirty;
+         }
+      }
+   }
+}
+
+void _board_maker_ui( ui_context *ctx )
+{
+   if( _world.event != k_world_event_board_maker )
+      return;
+
+   ui_capture_mouse( ctx, 1 );
+
+   ui_rect panel = { 8, 8, 200, 600 };
+
+   if( !ui_click_up( ctx, UI_MOUSE_LEFT ) )
+      _board_maker.ui_dropper_colour = NULL;
+
+   ui_info( ctx, panel, "Wheels" );
+   ui_rect w1, w2, w3, w4, wheel_row;
+   ui_standard_widget( ctx, panel, wheel_row, 1 );
+   ui_split_ratio( wheel_row, k_ui_axis_v, 0.5f, 2, w1, w3 );
+   ui_split_ratio( w1, k_ui_axis_v, 0.5f, 2, w1, w2 );
+   ui_split_ratio( w3, k_ui_axis_v, 0.5f, 2, w3, w4 );
+   _board_maker_colour_button( ctx, w1, _board_maker.colours[ k_workshop_shader_part_wheel1 ] );
+   _board_maker_colour_button( ctx, w2, _board_maker.colours[ k_workshop_shader_part_wheel2 ] );
+   _board_maker_colour_button( ctx, w3, _board_maker.colours[ k_workshop_shader_part_wheel3 ] );
+   _board_maker_colour_button( ctx, w4, _board_maker.colours[ k_workshop_shader_part_wheel4 ] );
+
+   ui_info( ctx, panel, "Trucks" );
+   ui_rect truck_row, t1, t2;
+   ui_standard_widget( ctx, panel, truck_row, 1 );
+   ui_split_ratio( truck_row, k_ui_axis_v, 0.5f, 2, t1, t2 );
+   _board_maker_colour_button( ctx, t1, _board_maker.colours[ k_workshop_shader_part_truck1 ] );
+   _board_maker_colour_button( ctx, t2, _board_maker.colours[ k_workshop_shader_part_truck2 ] );
+
+   ui_info( ctx, panel, "Deck" );
+   ui_rect deck_row, deckc, decki, decke;
+   ui_standard_widget( ctx, panel, deck_row, 1 );
+   ui_split_ratio( deck_row, k_ui_axis_v, 0.66666f, 2, deckc, decke );
+   ui_split_ratio( deckc, k_ui_axis_v, 0.5f, 2, deckc, decki );
+   _board_maker_colour_button( ctx, deckc, _board_maker.colours[ k_workshop_shader_part_deck ] );
+   _board_maker_colour_button( ctx, decke, _board_maker.colours[ k_workshop_shader_part_edge ] );
+
+   ui_info( ctx, panel, "Griptape" );
+   ui_rect griptape_row, gtc, gti;
+   ui_standard_widget( ctx, panel, griptape_row, 1 );
+   ui_split_ratio( griptape_row, k_ui_axis_v, 0.5f, 2, gtc, gti );
+   _board_maker_colour_button( ctx, gtc, _board_maker.colours[ k_workshop_shader_part_griptape ] );
+
+   if( _board_maker.ui_dropper_colour )
+   {
+      ui_rect bib = { ctx->mouse[0], ctx->mouse[1], 16, 16 };
+      u32 colour = v4f_u32_colour( _board_maker.ui_dropper_colour );
+      ui_fill( ctx, bib, colour );
+   }
+
+   if( _board_maker.ui_state == k_board_maker_ui_state_pick_colour )
+   {
+      _board_maker.picker_panel[0] = panel[0] + panel[2] + 8;
+      _board_maker.picker_panel[2] = 300;
+      _board_maker.picker_panel[3] = 160;
+
+      ui_rect picker_panel, ok_box;
+      rect_copy( _board_maker.picker_panel, picker_panel );
+      ui_outline( ctx, picker_panel, 1, ui_colour( ctx, k_ui_fg ), 0 );
+
+      if( ui_colourpicker( ctx, picker_panel, NULL, _board_maker.ui_target_colour, k_ui_colour_type_rgb ) )
+         _board_maker.compositor_state = k_board_maker_compositor_dirty;
+
+      ui_split( picker_panel, k_ui_axis_h, -24, 0, picker_panel, ok_box );
+
+      ctx->font = &vgf_default_large;
+      if( ui_button_text( ctx, ok_box, "\xb3", 1 ) == k_ui_button_click )
+      {
+         _board_maker.ui_state = k_board_maker_ui_state_default;
+      }
+      ctx->font = &vgf_default_small;
+   }
+}
+
+void _board_maker_open(void)
+{
+   VG_ASSERT( _board_maker.state == k_board_maker_state_not_ready );
+   VG_ASSERT( _board_maker.model_loaded == 0 );
+   VG_ASSERT( _board_maker.static_heap == NULL );
+   VG_ASSERT( _board_maker.template_heap == NULL );
+
+   _board_maker.static_heap = _vg_create_linear_allocator( NULL, 8*1024*1024, VG_MEMORY_SYSTEM, "Board maker static" );
+   _board_maker.template_heap = _vg_create_linear_allocator( NULL, 16*1024*1024, VG_MEMORY_SYSTEM, "Board maker dynamic" );
+
+   for( u32 i=0; i<k_workshop_shader_part_max; i ++ )
+   {
+      v4_copy( _board_maker_default_colours[i], _board_maker.colours[i] ); 
+   }
+}
diff --git a/src/board_maker.h b/src/board_maker.h
new file mode 100644 (file)
index 0000000..4a6a754
--- /dev/null
@@ -0,0 +1,73 @@
+#pragma once
+#include "vg/vg_framebuffer.h"
+#include "shader_props.h"
+
+v4f _board_maker_default_colours[] = 
+{
+   [k_workshop_shader_part_truck1  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_truck2  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_wheel1  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_wheel2  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_wheel3  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_wheel4  ] = { 1,1,1,1 },
+   [k_workshop_shader_part_edge    ] = { 1,1,1,1 },
+   [k_workshop_shader_part_griptape] = { 0.5f,0.5f,0.5f,1 },
+   [k_workshop_shader_part_deck    ] = { 1,1,1,1 },
+};
+
+struct _board_maker
+{
+   enum board_maker_type
+   {
+      k_board_maker_type_regular
+   }
+   board_type;
+
+   v3f origin;
+   v3f angles;
+
+   mdl_context template_mdl;
+   array_file_ptr template_mdl_shader_data;
+   bool model_loaded;
+
+   enum board_maker_state
+   {
+      k_board_maker_state_not_ready,
+      k_board_maker_state_initializing,
+      k_board_maker_state_none,
+      k_board_maker_state_load_template,
+      k_board_maker_state_loading_template,
+   }
+   state;
+
+   void *static_heap;
+   void *template_heap;
+
+   enum board_maker_compositor_state
+   {
+      k_board_maker_compositor_dirty,
+      k_board_maker_compositor_done,
+   }
+   compositor_state;
+
+   vg_framebuffer compositor_fb;
+
+   v4f colours[ k_workshop_shader_part_max ];
+   struct shader_props_workshop *base_shader;
+
+   ui_rect picker_panel;
+   f32 *ui_target_colour;
+   f32 *ui_dropper_colour;
+   enum board_maker_ui_state
+   {
+      k_board_maker_ui_state_default,
+      k_board_maker_ui_state_pick_colour
+   }
+   ui_state;
+}
+extern _board_maker;
+
+void _board_maker_pre_update(void);
+void _board_maker_render( world_instance *world, vg_camera *cam );
+void _board_maker_ui( ui_context *ctx );
+void _board_maker_open(void);
index d98ddaed159cd855946336c8d3199ac6a569884e..5d52ff6ba661b5d83dc52f4f7102a185e2bc8b83 100644 (file)
@@ -138,7 +138,7 @@ static bool menu_slider( ui_context *ctx,
    ui_label( ctx, rect, label, 1, 8, box );
 
    f32 t;
-   enum ui_button_state state = ui_slider_base( ctx, box, 0, 1, value, &t ),
+   enum ui_button_state state = ui_slider_base( ctx, box, k_ui_axis_h, 0, 1, value, &t ),
          mask_using = 
          k_ui_button_holding_inside |
          k_ui_button_holding_outside |
index ebe4e04e8e51071cb4edd7ea2e25a36b837af2cd..5f06e24f7e0b7fd6851fc35cdca0f941bc05e02b 100644 (file)
@@ -97,12 +97,9 @@ 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 } );
+   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;
 }
@@ -153,8 +150,33 @@ void *mdl_shader_cubemapped( vg_msg *msg, void *alloc )
    return props;
 }
 
-static bool mdl_legacy_v105_properties( struct mdl_material_v105 *mat, 
-                                        vg_msg *dst )
+// TODO: Shitty place for this to be
+const char *_shader_prop_workshop_keys[] =
+{
+   [k_workshop_shader_part_truck1  ] = "truck1",
+   [k_workshop_shader_part_truck2  ] = "truck2",
+   [k_workshop_shader_part_wheel1  ] = "wheel1",
+   [k_workshop_shader_part_wheel2  ] = "wheel2",
+   [k_workshop_shader_part_wheel3  ] = "wheel3",
+   [k_workshop_shader_part_wheel4  ] = "wheel4",
+   [k_workshop_shader_part_edge    ] = "edge",
+   [k_workshop_shader_part_griptape] = "griptape",
+   [k_workshop_shader_part_deck    ] = "deck"
+};
+
+void *mdl_shader_workshop( vg_msg *msg, void *alloc )
+{
+   struct shader_props_workshop *props = vg_linear_alloc( alloc, sizeof(struct shader_props_workshop) );
+
+   for( u32 i=0; i<k_workshop_shader_part_max; i ++ )
+   {
+      vg_msg_getkvintg( msg, _shader_prop_workshop_keys[i], k_vg_msg_u32, &props->tex_all[i], NULL );
+   }
+
+   return props;
+}
+
+static 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 );
 
@@ -220,8 +242,7 @@ void mdl_load_materials( mdl_context *mdl, void *lin_alloc )
       else
 #endif
       {
-         vg_msg_init( &msg, data.data + mat->props.kvs.offset, 
-                      mat->props.kvs.size );
+         vg_msg_init( &msg, data.data + mat->props.kvs.offset, mat->props.kvs.size );
       }
 
       if( mat->shader == k_shader_standard || 
@@ -247,6 +268,10 @@ void mdl_load_materials( mdl_context *mdl, void *lin_alloc )
       {
          mat->props.compiled = mdl_shader_water( &msg, lin_alloc );
       }
+      else if( mat->shader == k_shader_workshop )
+      {
+         mat->props.compiled = mdl_shader_workshop( &msg, lin_alloc );
+      }
       else
          mat->props.compiled = NULL;
    }
index 690bb901184dd8f9b98723ce9e304837abd8f2ed..4e79695ff681176131ac4b5a2c837ba984e1e7a6 100644 (file)
@@ -21,6 +21,7 @@ enum mdl_shader{
    k_shader_cubemap                 = 8,
    k_shader_walking                 = 9,
    k_shader_foliage                 = 10,
+   k_shader_workshop                = 11,
    k_shader_override                = 30000
 };
 
index 903ba98966ce7b316f1135f0b892e21e2d305f17..88dbb6cf8fac575868404c275622481becaa0016 100644 (file)
@@ -943,14 +943,14 @@ void remote_players_imgui_world( ui_context *ctx,
    ui_flush( ctx, k_ui_shader_colour, NULL );
 }
 
-static void chat_escape( ui_context *ctx )
+static void chat_escape( ui_context *ctx, void *userdata )
 {
    netplayers.chatting = -1;
 }
 
-static void chat_enter( ui_context *ctx, char *buf, u32 len ){
-   vg_strncpy( buf, netplayers.chat_message, NETWORK_MAX_CHAT, 
-               k_strncpy_always_add_null );
+static void chat_enter( ui_context *ctx, char *buf, u32 len, void *userdata )
+{
+   vg_strncpy( buf, netplayers.chat_message, NETWORK_MAX_CHAT, k_strncpy_always_add_null );
    netplayers.chatting = -1;
    netplayers.chat_time = vg.time_real;
    chat_send_message( buf );
diff --git a/src/scripts/generic.c b/src/scripts/generic.c
new file mode 100644 (file)
index 0000000..9c983cb
--- /dev/null
@@ -0,0 +1,28 @@
+
+static bool _skaterift_script_board_maker( ent_script_event *event )
+{
+   if( on_function_trigger( event, 0 ) )
+   {
+      v3_zero( _board_maker.angles );
+
+      if( world_set_event( k_world_event_board_maker ) )
+      {
+         ent_list *list = event->entity_list;
+         for( u32 i=0; i<list->entity_ref_count; i ++ )
+         {
+            file_entity_ref *ref = af_arritm( &event->world->file_entity_ref, list->entity_ref_start + i );
+            
+            u32 type = mdl_entity_id_type( ref->entity_id ),
+                index = mdl_entity_id_id( ref->entity_id );
+
+            if( type == k_ent_marker )
+            {
+               ent_marker *marker = af_arritm( &event->world->ent_marker, index );
+               v3_copy( marker->transform.co, _board_maker.origin );
+            }
+         }
+         _board_maker_open();
+      }
+   }
+   return 1;
+}
index 29e79f54023b6df2987ad784617de929662654ec..05f9ef03eef5ac178e31cab6801d8eef38b152fc 100644 (file)
@@ -35,3 +35,22 @@ struct shader_props_cubemapped
    u32 cubemap_entity;
    v4f tint;
 };
+
+enum workshop_shader_part
+{
+   k_workshop_shader_part_truck1,
+   k_workshop_shader_part_truck2,
+   k_workshop_shader_part_wheel1,
+   k_workshop_shader_part_wheel2,
+   k_workshop_shader_part_wheel3,
+   k_workshop_shader_part_wheel4,
+   k_workshop_shader_part_edge,
+   k_workshop_shader_part_griptape,
+   k_workshop_shader_part_deck,
+   k_workshop_shader_part_max
+};
+struct shader_props_workshop
+{
+   u32 tex_all[k_workshop_shader_part_max];
+};
+extern const char *_shader_prop_workshop_keys[k_workshop_shader_part_max];
index 63b70890d3794933e1e07bcfd1ddceb85a5571d9..3aab6acaa8175595c2af319700f3bc16c5898860 100644 (file)
@@ -53,6 +53,7 @@
 #include "skaterift_script.h"
 #include "ent_challenge.h"
 #include "ent_script.h"
+#include "board_maker.h"
 
 struct skaterift_globals skaterift = 
 { 
@@ -184,6 +185,7 @@ void vg_pre_update(void)
       target = 0;
 
    world_update( &_world.main, localplayer.rb.co );
+   _board_maker_pre_update();
 
    cutscene_update( vg.time_rate * vg.time_frame_delta );
 
@@ -528,6 +530,7 @@ void vg_gui( ui_context *ctx )
    vg_framebuffer_inverse_ratio( _vg_render.fb_main, vg_ui.bg_inverse_ratio );
 
    _cutscene_gui( ctx );
+   _board_maker_ui( ctx );
    menu_gui( ctx );
    player__im_gui( ctx );
    world_instance *world = &_world.main;
@@ -613,3 +616,4 @@ void vg_framebuffer_resize( int w, int h )
 #include "control_overlay.c"
 #include "ent_camera.c"
 #include "skaterift_script.c"
+#include "board_maker.c"
index 0ed9e47765d0dfc3fbf2d8476c62061a641c0df3..e9dc62da7ce6f62594dad4f0589d1db3b829a6fc 100644 (file)
@@ -691,7 +691,9 @@ enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutsce
    return cs_event;
 }
 
+#include "scripts/generic.c"
 #include "scripts/blocker_break.c"
+
 #include "scripts/heaven.c"
 #include "scripts/hub.c"
 #include "scripts/tutorial_island.c"
@@ -704,6 +706,8 @@ enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutsce
 
 struct ent_script_table_entry _ent_script_table[] =
 {
+   { "board_maker", _skaterift_script_board_maker },
+
    { "intro", _skaterift_script_intro },
    { "hub", _skaterift_script_hub },
 
index fcf768d5a56911c165b427c5644651a8c0849f0e..c28578c007b5cae7866a09558bf7aac22c17c41b 100644 (file)
@@ -87,6 +87,9 @@ void vg_render(void)
 void vg_gui( ui_context *ctx )
 {
    ui_capture_mouse( ctx, 1 );
+
+   ui_rect rect = { 8,8, vg.window_x-16, vg.window_y-16 };
+
 }
 
 void vg_framebuffer_resize( int w, int h ){}
index a2c1ef3442dd88d1dafe1d4937c2a1588e914b62..6c3e7ebe52e0a7120c22bc7d22a96b584e4ee36b 100644 (file)
@@ -1071,17 +1071,17 @@ static void workshop_render_board_preview(void)
  * -----------------------------------------------------------------------------
  */
 
-static void workshop_changed_model_path( ui_context *ctx, char *buf, u32 len )
+static void workshop_changed_model_path( ui_context *ctx, char *buf, u32 len, void *userdata )
 {
    workshop_form.submission.submit_file_and_image = 1;
 }
 
-static void workshop_changed_title( ui_context *ctx, char *buf, u32 len )
+static void workshop_changed_title( ui_context *ctx, char *buf, u32 len, void *userdata )
 {
    workshop_form.submission.submit_title = 1;
 }
 
-static void workshop_changed_description( ui_context *ctx, char *buf, u32 len )
+static void workshop_changed_description( ui_context *ctx, char *buf, u32 len, void *userdata )
 {
    workshop_form.submission.submit_description = 1;
 }
index cc329f885cebf6c476de622556f153fc868bd0b4..2c99f1b66da184584109a75df1b47ab5445cd73a 100644 (file)
@@ -263,7 +263,8 @@ struct world_static
       k_world_event_challenge,
       k_world_event_shop,
       k_world_event_route_leaderboard,
-      k_world_event_interact
+      k_world_event_interact,
+      k_world_event_board_maker
    }
    event;
 
index 02008d5fbfd0b37158f0d7d8528f2749ade0ec95..c18406b46930383e84e8b2576be9e8181e3b7a0b 100644 (file)
@@ -14,6 +14,7 @@
 #include "shaders/model_sky_cubemap.h"
 #include "shaders/scene_preview.h"
 #include "shaders/scene_override.h"
+#include "board_maker.h"
 
 struct world_render world_render;
 
@@ -1153,8 +1154,7 @@ void render_world( world_instance *world, vg_camera *cam,
          glDisable(GL_BLEND);
          glEnable(GL_DEPTH_TEST);
          glDepthMask(GL_TRUE);
-         glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, 
-                                       GL_COLOR_ATTACHMENT1 } );
+         glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } );
       }
 
       render_world_fxglow( world, world, cam, NULL, 1, 1, 0 );
@@ -1182,6 +1182,7 @@ void render_world( world_instance *world, vg_camera *cam,
    render_remote_players( world, cam );
    render_other_entities( world, cam );
    ent_miniworld_render( world, cam );
+   _board_maker_render( world, cam );
 
    if( stenciled )
    {
@@ -1577,8 +1578,7 @@ void imgui_world_light_edit( ui_context *ctx, world_instance *world )
 
    static i32 option_to_edit = 0;
    ui_enum( ctx, panel, "option", skybox_setting_options, 5, &option_to_edit );
-   ui_colourpicker( ctx, panel, "colour", 
-                    skybox_prop_location( world, option_to_edit ) );
+   ui_colourpicker( ctx, panel, "colour", skybox_prop_location( world, option_to_edit ), k_ui_colour_type_rgba );
 
    if( ui_button( ctx, panel, "save tweaker file ('/tmp/tweaker.txt')\n" ) == 1 )
    {