_S( "workshop_compositor", "workshop_compositor.vs", "workshop_compositor.fs" );
_S( "blitblur", "blit.vs", "blitblur.fs" );
_S( "blitcolour","blit.vs", "colour.fs" );
+ _S( "compass","compass.vs", "compass.fs" );
_S( "blit_transition", "blit.vs", "blit_transition.fs" );
_S( "routeui", "routeui.vs", "routeui.fs" );
--- /dev/null
+out vec4 FragColor;
+uniform sampler2D uTexMain;
+uniform vec4 uColour;
+
+in vec4 aUv;
+
+void main()
+{
+ vec4 c = texture( uTexMain, aUv.xy );
+ c.a *= min( 1.0, (1.0-abs(aUv.z)) * 4.0 );
+ FragColor = c * uColour;
+}
--- /dev/null
+layout (location=0) in vec3 a_co;
+//layout (location=1) in vec3 a_norm;
+layout (location=2) in vec2 a_uv;
+//layout (location=3) in vec4 a_colour;
+//layout (location=4) in vec4 a_weights;
+//layout (location=5) in ivec4 a_groups;
+
+out vec4 aUv;
+
+uniform mat3 uProjection;
+
+void main()
+{
+ vec3 co = uProjection * vec3(a_co.xy,1.0);
+ gl_Position = vec4(co.xy,0.0,1.0);
+ aUv = vec4(a_uv, co.xy);
+}
--- /dev/null
+#include "compass.h"
+#include "shaders/compass.h"
+#include "world.h"
+
+struct _compass _compass = { .alpha = 1 };
+
+void compass_init(void)
+{
+ mdl_context *mdl = &_compass.mdl;
+ void *allocator = vg_mem.rtmemory;
+
+ mdl_open( mdl, "models/rs_compass.mdl", allocator );
+ mdl_load_metadata_block( mdl, allocator );
+ mdl_async_full_load_std( mdl, NULL );
+ _compass.sm_comp = mdl_get_submesh_index( mdl, "comp" );
+ _compass.sm_comp_bar = mdl_get_submesh_index( mdl, "comp_bar" );
+ _compass.sm_comp_dot = mdl_get_submesh_index( mdl, "comp_dot" );
+ _compass.sm_comp_e = mdl_get_submesh_index( mdl, "comp_e" );
+ _compass.sm_comp_fade = mdl_get_submesh_index( mdl, "comp_fade" );
+ _compass.sm_comp_friend = mdl_get_submesh_index( mdl, "comp_friend" );
+ _compass.sm_comp_gate = mdl_get_submesh_index( mdl, "comp_gate" );
+ _compass.sm_comp_n = mdl_get_submesh_index( mdl, "comp_n" );
+ _compass.sm_comp_notify = mdl_get_submesh_index( mdl, "comp_notify" );
+ _compass.sm_comp_person = mdl_get_submesh_index( mdl, "comp_person" );
+ _compass.sm_comp_s = mdl_get_submesh_index( mdl, "comp_s" );
+ _compass.sm_comp_w = mdl_get_submesh_index( mdl, "comp_w" );
+ mdl_close( mdl );
+
+ vg_console_reg_var( "compass_alpha", &_compass.alpha, k_var_dtype_f32, VG_VAR_PERSISTENT );
+}
+
+static void compass_project( m3x3f base_projection, f32 x, f32 height )
+{
+ base_projection[2][0] = x;
+ base_projection[2][1] = height;
+ shader_compass_uProjection( base_projection );
+}
+
+static bool compass_a( m3x3f base_projection, f32 angle, f32 height )
+{
+ f32 a = vg_angle_diff( g_render.cam.angles[0], angle ) / (VG_PIf/3.0f);
+ if( fabsf(a) > 1.0f )
+ return 0;
+
+ compass_project( base_projection, a, height );
+ return 1;
+}
+
+static bool compass_co( m3x3f base_projection, v3f co, f32 height )
+{
+ v3f v0;
+ v3_sub( co, g_render.cam.pos, v0 );
+ v0[1] = 0.0f;
+ v3_normalize( v0 );
+ f32 a = atan2f( v0[0], -v0[2] );
+ return compass_a( base_projection, a, height );
+}
+
+void compass_render_texture(void)
+{
+ if( skaterift.activity == k_skaterift_replay )
+ return;
+
+ vg_framebuffer_bind( g_render.fb_compass, 1.0f );
+
+ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
+ glClear( GL_COLOR_BUFFER_BIT );
+ glDisable( GL_DEPTH_TEST );
+ glDisable( GL_BLEND );
+
+ m3x3f projection;
+ m3x3_identity( projection );
+ projection[0][0] = 512.0f/400.0f;
+ projection[1][1] = 512.0f/50.0f;
+
+ mdl_context *mdl = &_compass.mdl;
+ mesh_bind( &mdl->mesh );
+
+ shader_compass_use();
+ shader_compass_uTexMain( 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, mdl->textures[0].glname );
+
+ /* base */
+ shader_compass_uColour( (v4f){ 1,1,1,0.4 } );
+ compass_project( projection, 0,0 );
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_bar ] );
+
+ if( compass_a( projection, 0.0f, 0 ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_n ] );
+
+ if( compass_a( projection, VG_PIf/2.0f, 0 ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_e ] );
+
+ if( compass_a( projection, VG_PIf, 0 ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_s ] );
+
+ if( compass_a( projection, -VG_PIf/2.0f, 0 ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_w ] );
+
+ for( u32 i=0; i<4; i ++ )
+ {
+ f32 a = VG_PIf/4.0f + (f32)i * (VG_PIf/2.0f);
+ if( compass_a( projection, a, 0 ) )
+ {
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_dot ] );
+ }
+ }
+
+ /* TODO: Players and friends */
+ shader_compass_uColour( (v4f){ 1,1,1,1 } );
+
+ world_instance *world = &_world.main;
+
+ /* story markers */
+ for( u32 i=0; i<af_arrcount(&world->ent_marker); i ++ )
+ {
+ ent_marker *marker = af_arritm( &world->ent_marker, i );
+ if( marker->flags & k_ent_marker_flag_hidden )
+ continue;
+
+ if( marker->flags & k_ent_marker_flag_gui_icon )
+ {
+ if( compass_co( projection, marker->transform.co, 0.0f ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_notify ] );
+ }
+ }
+
+ /* gates n shit */
+ f32 t = (_world.time - _world.last_gate_hit_time) / 30.0f;
+ f32 alpha = vg_clampf( 2.0f-t, 0.0f, 1.0f );
+ if( alpha > 0.001f )
+ {
+ for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
+ {
+ ent_route *route = af_arritm( &world->ent_route, i );
+
+ if( route->active_checkpoint != 0xffff )
+ {
+ v4f colour;
+ v3_copy( route->colour, colour );
+
+ colour[3] = alpha;
+ shader_compass_uColour( colour );
+
+ u32 next = route->active_checkpoint+1;
+ next = next % route->checkpoints_count;
+ next += route->checkpoints_start;
+
+ ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, next );
+ ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index );
+
+ if( compass_co( projection, gate->co[0], 0.0f ) )
+ mdl_draw_submesh( &mdl->submeshes[ _compass.sm_comp_gate ] );
+ }
+ }
+ }
+}
+
+void compass_render_imgui( ui_context *ctx )
+{
+ if( skaterift.activity == k_skaterift_replay )
+ return;
+
+ ui_rect rect = { 0,0, 800, 100 };
+ ui_rect_center( (ui_rect){0,0,vg.window_x,100}, rect );
+ ui_flush( ctx, k_ui_shader_colour, NULL );
+ vg_ui.colour[3] = _compass.alpha;
+ ui_image( ctx, rect, &g_render.fb_compass->attachments[0].id );
+ vg_ui.colour[3] = 1.0f;
+}
--- /dev/null
+#pragma once
+#include "vg/vg_framebuffer.h"
+
+struct _compass
+{
+ mdl_context mdl;
+
+ i32 sm_comp,
+ sm_comp_bar,
+ sm_comp_dot,
+ sm_comp_e,
+ sm_comp_fade,
+ sm_comp_friend,
+ sm_comp_gate,
+ sm_comp_n,
+ sm_comp_notify,
+ sm_comp_person,
+ sm_comp_s,
+ sm_comp_w;
+
+ f32 alpha;
+}
+extern _compass;
+
+void compass_init(void);
+void compass_render_texture(void);
+void compass_render_imgui( ui_context *ctx );
GLuint icons_texture;
glmesh icons_mesh;
- mdl_submesh *icons[ k_gui_icon_count ];
+ i32 icon_submeshes[ k_gui_icon_count ];
}
static gui = {.cur_icon_colour = {1.0f,1.0f,1.0f,1.0f},.colour_changed=1};
glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
shader_model_font_uTexMain( 0 );
- for( u32 i=0; i<gui.icon_draw_count; i++ ){
+ for( u32 i=0; i<gui.icon_draw_count; i++ )
+ {
struct icon_call *call = &gui.icon_draw_buffer[i];
if( call->colour_changed )
shader_model_font_uColour( call->colour );
-
shader_model_font_uOffset( call->location );
- mdl_submesh *sm = gui.icons[ call->icon ];
+ i32 index = gui.icon_submeshes[ call->icon ];
+ mdl_submesh *sm = &gui.model_icons.submeshes[ index ];
if( sm )
mdl_draw_submesh( sm );
}
v4_copy( colour, gui.cur_icon_colour );
}
-static mdl_submesh *gui_find_icon( const char *name )
-{
- mdl_mesh *mesh = mdl_find_mesh( &gui.model_icons, name );
- if( mesh )
- if( mesh->submesh_count )
- return &gui.model_icons.submeshes[ mesh->submesh_start ];
-
- return NULL;
-}
-
static void gui_init(void)
{
font3d_load( &gui.font, "models/rs_font.mdl", vg_mem.rtmemory );
/* load icons */
void *alloc = vg_mem.rtmemory;
- mdl_open( &gui.model_icons, "models/rs_icons.mdl", alloc );
- mdl_load_metadata_block( &gui.model_icons, alloc );
-
- gui.icons[ k_gui_icon_tick ] = gui_find_icon( "icon_tick" );
- gui.icons[ k_gui_icon_tick_2d ] = gui_find_icon( "icon_tick2d" );
- gui.icons[ k_gui_icon_exclaim ] = gui_find_icon( "icon_exclaim" );
- gui.icons[ k_gui_icon_exclaim_2d ] = gui_find_icon( "icon_exclaim2d" );
- gui.icons[ k_gui_icon_board ] = gui_find_icon( "icon_board" );
- gui.icons[ k_gui_icon_world ] = gui_find_icon( "icon_world" );
- gui.icons[ k_gui_icon_rift ] = gui_find_icon( "icon_rift" );
- gui.icons[ k_gui_icon_rift_run ] = gui_find_icon( "icon_rift_run" );
- gui.icons[ k_gui_icon_rift_run_2d ] = gui_find_icon( "icon_rift_run2d" );
- gui.icons[ k_gui_icon_friend ] = gui_find_icon( "icon_friend" );
- gui.icons[ k_gui_icon_player ] = gui_find_icon( "icon_player" );
- gui.icons[ k_gui_icon_player2d ] = gui_find_icon( "icon_player2d" );
- gui.icons[ k_gui_icon_glider ] = gui_find_icon( "icon_glider" );
- gui.icons[ k_gui_icon_spawn ] = gui_find_icon( "icon_spawn" );
- gui.icons[ k_gui_icon_spawn_select ] = gui_find_icon( "icon_spawn_select" );
- gui.icons[ k_gui_icon_rift_run_gold ] = gui_find_icon("icon_rift_run_medal_gold");
- gui.icons[ k_gui_icon_rift_run_silver]= gui_find_icon("icon_rift_run_medal_silver");
- gui.icons[ k_gui_icon_story2d ]= gui_find_icon("icon_story2d");
- gui.icons[ k_gui_icon_story_done2d ]= gui_find_icon("icon_story_done2d");
+
+ mdl_context *mdl = &gui.model_icons;
+ mdl_open( mdl, "models/rs_icons.mdl", alloc );
+ mdl_load_metadata_block( mdl, alloc );
+
+ gui.icon_submeshes[ k_gui_icon_tick ] = mdl_get_submesh_index( mdl, "icon_tick" );
+ gui.icon_submeshes[ k_gui_icon_tick_2d ] = mdl_get_submesh_index( mdl, "icon_tick2d" );
+ gui.icon_submeshes[ k_gui_icon_exclaim ] = mdl_get_submesh_index( mdl, "icon_exclaim" );
+ gui.icon_submeshes[ k_gui_icon_exclaim_2d ] = mdl_get_submesh_index( mdl, "icon_exclaim2d" );
+ gui.icon_submeshes[ k_gui_icon_board ] = mdl_get_submesh_index( mdl, "icon_board" );
+ gui.icon_submeshes[ k_gui_icon_world ] = mdl_get_submesh_index( mdl, "icon_world" );
+ gui.icon_submeshes[ k_gui_icon_rift ] = mdl_get_submesh_index( mdl, "icon_rift" );
+ gui.icon_submeshes[ k_gui_icon_rift_run ] = mdl_get_submesh_index( mdl, "icon_rift_run" );
+ gui.icon_submeshes[ k_gui_icon_rift_run_2d ] = mdl_get_submesh_index( mdl, "icon_rift_run2d" );
+ gui.icon_submeshes[ k_gui_icon_friend ] = mdl_get_submesh_index( mdl, "icon_friend" );
+ gui.icon_submeshes[ k_gui_icon_player ] = mdl_get_submesh_index( mdl, "icon_player" );
+ gui.icon_submeshes[ k_gui_icon_player2d ] = mdl_get_submesh_index( mdl, "icon_player2d" );
+ gui.icon_submeshes[ k_gui_icon_glider ] = mdl_get_submesh_index( mdl, "icon_glider" );
+ gui.icon_submeshes[ k_gui_icon_spawn ] = mdl_get_submesh_index( mdl, "icon_spawn" );
+ gui.icon_submeshes[ k_gui_icon_spawn_select ] = mdl_get_submesh_index( mdl, "icon_spawn_select" );
+ gui.icon_submeshes[ k_gui_icon_rift_run_gold ] = mdl_get_submesh_index( mdl,"icon_rift_run_medal_gold");
+ gui.icon_submeshes[ k_gui_icon_rift_run_silver]= mdl_get_submesh_index( mdl,"icon_rift_run_medal_silver");
+ gui.icon_submeshes[ k_gui_icon_story2d ]= mdl_get_submesh_index( mdl,"icon_story2d");
+ gui.icon_submeshes[ k_gui_icon_story_done2d ]= mdl_get_submesh_index( mdl,"icon_story_done2d");
vg_linear_clear( vg_mem.scratch );
if( !gui.model_icons.texture_count )
mdl_texture *tex0 = &gui.model_icons.textures[ 0 ];
void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
mdl_fread_pack_file( &gui.model_icons, &tex0->file, data );
- vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
- VG_TEX2D_LINEAR|VG_TEX2D_CLAMP,
- &gui.icons_texture );
-
+ vg_tex2d_load_qoi_async( data, tex0->file.pack_size, VG_TEX2D_LINEAR|VG_TEX2D_CLAMP, &gui.icons_texture );
mdl_async_load_glmesh( &gui.model_icons, &gui.icons_mesh, NULL );
mdl_close( &gui.model_icons );
}
}
#endif
-mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name )
+i32 mdl_get_mesh_index( mdl_context *mdl, const char *name )
{
u32 hash = vg_strdjb2( name );
for( u32 i=0; i<mdl->mesh_count; i++ )
{
mdl_mesh *mesh = &mdl->meshes[ i ];
if( af_str_eq( &mdl->af, mesh->pstr_name, name, hash ) )
- return mesh;
+ return i;
}
- return NULL;
+ return -1;
}
-mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name )
+i32 mdl_get_submesh_index( mdl_context *mdl, const char *mesh_name )
{
- mdl_mesh *mesh = mdl_find_mesh( mdl, mesh_name );
+ i32 mesh_index = mdl_get_mesh_index( mdl, mesh_name );
+ if( mesh_index == -1 )
+ return -1;
- if( !mesh ) return NULL;
- if( !mesh->submesh_count ) return NULL;
+ mdl_mesh *mesh = &mdl->meshes[ mesh_index ];
+ if( !mesh->submesh_count )
+ return -1;
- return &mdl->submeshes[ mesh->submesh_start ];
+ return mesh->submesh_start;
}
#ifdef VG_3D
/* rendering */
void mdl_draw_submesh( mdl_submesh *sm );
-mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name );
-mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name );
+i32 mdl_get_mesh_index( mdl_context *mdl, const char *name );
+i32 mdl_get_submesh_index( mdl_context *mdl, const char *mesh_name );
void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx );
for( u32 i=0; i<af_arrcount( &markers ); i ++ )
{
ent_marker *marker = af_arritm( &markers, i );
- v3_copy( marker->transform.co,
- player_glide.trail_positions[ player_glide.trail_count ++ ] );
+ v3_copy( marker->transform.co, player_glide.trail_positions[ player_glide.trail_count ++ ] );
if( player_glide.trail_count == VG_ARRAY_LEN(trails_glider) )
break;
};
vg_framebuffer_create( g_render.fb_network_status );
+ g_render.fb_compass = vg_framebuffer_allocate( alloc, 1, 1 );
+ g_render.fb_compass->display_name = "compass";
+ g_render.fb_compass->resolution_div = 0;
+ g_render.fb_compass->fixed_w = 800;
+ g_render.fb_compass->fixed_h = 100;
+ g_render.fb_compass->attachments[0] = (vg_framebuffer_attachment)
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+ .internalformat = GL_RGBA,
+ .format = GL_RGBA,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ };
+ vg_framebuffer_create( g_render.fb_compass );
+
vg_async_call( async_render_init, NULL, 0 );
}
glmesh fsquad;
vg_framebuffer *fb_workshop_preview,
- *fb_network_status;
+ *fb_network_status,
+ *fb_compass;
int ready;
v2f blur_override;
#include "ent_challenge.h"
#include "ent_script.h"
#include "board_maker.h"
+#include "compass.h"
struct skaterift_globals skaterift =
{
vg_loader_step( world_init, NULL );
vg_loader_step( vehicle_init, NULL );
vg_loader_step( gui_init, NULL );
+ vg_loader_step( compass_init, NULL );
vg_loader_step( player_init, NULL );
vg_loader_step( player_ragdoll_init, NULL );
glViewport( 0,0, vg.window_x, vg.window_y );
gui_render_icons();
+
+ compass_render_texture();
}
void vg_gui( ui_context *ctx )
if( g_client.unreadyness )
return;
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glViewport( 0,0, vg.window_x, vg.window_y );
+
gui_draw( ctx );
+ compass_render_imgui( ctx );
if( k_light_editor )
imgui_world_light_edit( ctx, &_world.main );
#include "ent_camera.c"
#include "skaterift_script.c"
#include "board_maker.c"
+#include "compass.c"
//TODO
//#include "vg/submodules/hashmap.c/hashmap.c"
mdl_open( &mgate, "models/rs_gate.mdl", vg_mem.scratch );
mdl_load_metadata_block( &mgate, vg_mem.scratch );
- mdl_mesh *surface = mdl_find_mesh( &mgate, "rs_gate" );
- mdl_submesh *sm = &mgate.submeshes[ surface->submesh_start ];
- world_gates.sm_surface = *sm;
+ world_gates.sm_surface = mgate.submeshes[ mdl_get_submesh_index( &mgate, "rs_gate" ) ];
const char *names[] = { "rs_gate_marker", "rs_gate_marker.001",
"rs_gate_marker.002", "rs_gate_marker.003" };
for( int i=0; i<4; i++ )
- {
- mdl_mesh *marker = mdl_find_mesh( &mgate, names[i] );
- sm = &mgate.submeshes[ marker->submesh_start ];
- world_gates.sm_marker[i] = *sm;
- }
+ world_gates.sm_marker[i] = mgate.submeshes[ mdl_get_submesh_index( &mgate, names[i] ) ];
mdl_async_load_glmesh( &mgate, &world_gates.mesh, NULL );
mdl_close( &mgate );
mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
mdl_load_metadata_block( &msky, vg_mem.scratch );
mdl_async_load_glmesh( &msky, &world_render.skydome, NULL );
- world_render.skydome_complete_mesh = *mdl_find_submesh( &msky, "dome_complete" );
- world_render.skydome_squanched_mesh = *mdl_find_submesh( &msky, "dome_squanched" );
+ world_render.skydome_complete_mesh = msky.submeshes[ mdl_get_submesh_index( &msky, "dome_complete" ) ];
+ world_render.skydome_squanched_mesh = msky.submeshes[ mdl_get_submesh_index( &msky, "dome_squanched" ) ];
mdl_close( &msky );
vg_info( "Loading default world textures\n" );
mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );
scene_context *scene = &world_sfd.scene;
- vg_async_item *call = scene_alloc_async( scene, &world_sfd.mesh_display,
- 3000, 8000 );
+ vg_async_item *call = scene_alloc_async( scene, &world_sfd.mesh_display, 3000, 8000 );
-
- mdl_mesh *m_backer = mdl_find_mesh( &mscoreboard, "backer" ),
- *m_card = mdl_find_mesh( &mscoreboard, "score_card" );
-
- mdl_submesh
- *sm_backer = &mscoreboard.submeshes[ m_backer->submesh_start ],
- *sm_card = &mscoreboard.submeshes[ m_card->submesh_start ];
- world_sfd.sm_base = *sm_backer;
+ mdl_submesh *sm_card = &mscoreboard.submeshes[ mdl_get_submesh_index( &mscoreboard, "score_card" ) ];
+ world_sfd.sm_base = mscoreboard.submeshes[ mdl_get_submesh_index( &mscoreboard, "backer" ) ];
m4x3f identity;
m4x3_identity( identity );
- for( int i=0;i<4;i++ ){
+ for( int i=0;i<4;i++ )
+ {
u32 vert_start = scene->vertex_count;
scene_add_mdl_submesh( scene, &mscoreboard, sm_card, identity );
- for( int j=0; j<sm_card->vertex_count; j++ ){
+ for( int j=0; j<sm_card->vertex_count; j++ )
+ {
scene_vert *vert = &scene->arrvertices[ vert_start+j ];
float const k_glyph_uvw = 1.0f/64.0f;