MENY
[carveJwlIkooP6JGAAIwe30JlM.git] / menu.h
1 #ifndef MENU_H
2 #define MENU_H
3
4 #include "common.h"
5 #include "model.h"
6 #include "world_render.h"
7 #include "player.h"
8
9 #include "shaders/menu.h"
10
11 static mdl_header *menu_model;
12 static glmesh menu_glmesh;
13 static v3f menu_cam_pos,
14 menu_target_cam_pos;
15 static v4f menu_cam_q = { 0.0f, 0.0f, 0.0f, 1.0f },
16 menu_target_cam_q;
17 static m4x3f menu_cam, menu_cam_inv;
18 static float menu_opacity = 0.0f;
19
20 static void menu_init(void)
21 {
22 menu_model = mdl_load( "models/rs_menu.mdl" );
23
24 if( !menu_model )
25 vg_fatal_exit_loop( "No menu model" );
26
27 vg_acquire_thread_sync();
28 mdl_unpack_glmesh( menu_model, &menu_glmesh );
29 vg_release_thread_sync();
30
31 shader_menu_register();
32 }
33
34 static void menu_update( int enabled )
35 {
36 static int enabled_last = 0;
37
38 if( enabled && !enabled_last )
39 {
40 v3_copy( player.camera[3], menu_cam_pos );
41 m3x3_q( player.camera, menu_cam_q );
42
43 if( player.phys.on_board )
44 {
45 v4f r90;
46 q_axis_angle( r90, player.phys.rb.up, VG_PIf*-0.5f );
47 q_mul( r90, player.phys.rb.q, menu_target_cam_q );
48 m4x3_mulv( player.phys.rb.to_world, (v3f){-1.0f,1.6f,0.0f},
49 menu_target_cam_pos );
50 }
51 else
52 {
53 v4f r180;
54 q_axis_angle( r180, player.phys.rb.up, VG_PIf );
55 q_mul( r180, player.phys.rb.q, menu_target_cam_q );
56 m4x3_mulv( player.phys.rb.to_world, (v3f){0.0f,1.6f,-1.0f},
57 menu_target_cam_pos );
58 }
59
60 q_normalize( menu_target_cam_q );
61 q_normalize( menu_cam_q );
62 menu_opacity = 0.0f;
63 }
64
65 if( enabled_last && !enabled )
66 {
67 m3x3_q( player.camera, menu_target_cam_q );
68 v3_copy( player.camera[3], menu_target_cam_pos );
69 }
70
71 float dt = vg.time_delta * 6.0f;
72
73 q_nlerp( menu_cam_q, menu_target_cam_q, dt, menu_cam_q );
74 v3_lerp( menu_cam_pos, menu_target_cam_pos, dt, menu_cam_pos );
75
76 q_m3x3( menu_cam_q, menu_cam );
77 v3_copy( menu_cam_pos, menu_cam[3] );
78 m4x3_invert_affine( menu_cam, menu_cam_inv );
79 menu_opacity = vg_lerpf( menu_opacity, enabled, dt );
80
81 enabled_last = enabled;
82 }
83
84 static void menu_render( m4x4f projection )
85 {
86 glEnable(GL_BLEND);
87 glDisable(GL_DEPTH_TEST);
88 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
89 glBlendEquation(GL_FUNC_ADD);
90
91 shader_fscolour_use();
92 shader_fscolour_uColour( (v4f){ 0.1f, 0.1f, 0.3f, menu_opacity*0.5f } );
93 render_fsquad();
94
95 glEnable( GL_DEPTH_TEST );
96 glDisable( GL_BLEND );
97
98 m4x3f mtx;
99
100 shader_menu_use();
101 shader_menu_uColour( (v4f){ 1.0f,1.0f,1.0f,1.0f} );
102 shader_menu_uTexMain( 1 );
103 vg_tex2d_bind( &tex_graffiti, 1 );
104
105 shader_menu_uPv( projection );
106 mesh_bind( &menu_glmesh );
107
108 m4x3_identity( mtx );
109 shader_menu_uMdl( mtx );
110 mesh_draw( &menu_glmesh );
111
112 for( int i=0; i<menu_model->node_count; i++ )
113 {
114 mdl_node *pnode = mdl_node_from_id( menu_model, i );
115
116 for( int j=0; j<pnode->submesh_count; j++ )
117 {
118 mdl_submesh *sm =
119 mdl_submesh_from_id( menu_model, pnode->submesh_start+j );
120
121 mdl_node_transform( pnode, mtx );
122 m4x3_mul( player.phys.rb.to_world, mtx, mtx );
123 shader_menu_uMdl( mtx );
124
125 mdl_draw_submesh( sm );
126 }
127 }
128 }
129
130 static void menu_free(void *_)
131 {
132 mesh_free( &menu_glmesh );
133 }
134
135 #endif /* MENU_H */