the walk manifold is alive
[carveJwlIkooP6JGAAIwe30JlM.git] / main.c
1 #include "common.h"
2
3 /* Resources */
4 vg_tex2d tex_norwey = { .path = "textures/norway_foliage.qoi" };
5 vg_tex2d tex_grid = { .path = "textures/grid.qoi" };
6 vg_tex2d tex_sky = { .path = "textures/sky.qoi" };
7 vg_tex2d tex_gradients = { .path = "textures/gradients.qoi",
8 .flags = VG_TEXTURE_CLAMP };
9 vg_tex2d tex_cement = { .path = "textures/cement512.qoi" };
10 vg_tex2d tex_water = { .path = "textures/water.qoi" };
11
12 /* Convars */
13 static int debugview = 0;
14 static int sv_debugcam = 0;
15
16 /* Components */
17 #include "road.h"
18 #include "scene.h"
19 #include "ik.h"
20 #include "terrain.h"
21 #include "character.h"
22 #include "ragdoll.h"
23 #include "rigidbody.h"
24 #include "render.h"
25 #include "gate.h"
26 #include "water.h"
27 #include "world.h"
28 #include "player.h"
29
30 #include "shaders/blit.h"
31 #include "shaders/standard.h"
32 #include "shaders/unlit.h"
33
34 void vg_register(void)
35 {
36 shader_blit_register();
37 shader_standard_register();
38 shader_unlit_register();
39
40 terrain_register();
41 character_register();
42 water_register();
43 gate_register();
44 }
45
46 vg_tex2d *texture_list[] =
47 {
48 &tex_norwey,
49 &tex_gradients,
50 &tex_grid,
51 &tex_sky,
52 &tex_cement,
53 &tex_water,
54 &tex_water_surf
55 };
56
57 int main( int argc, char *argv[] )
58 {
59 vg_init( argc, argv, "Voyager Game Engine" );
60 }
61
62 #if 0
63 rigidbody mr_box = {
64 .bbx = {{ -1.0f, -0.25f, -0.25f }, { 1.0f, 0.25f, 0.25f }}
65 };
66
67 rigidbody mrs_box = {
68 .bbx = {{ -0.5f, -0.25f, -0.25f }, { 0.5f, 0.25f, 0.25f }}
69 };
70
71 teleport_gate gate_a = {
72 .co = { 0.0f, -3.0f, -15.0f },
73 .q = { 0.0f, 0.0f, 0.0f, 1.0f }
74 },
75 gate_b = {
76 .co = { -8.0f, -3.0f, -17.0f },
77 .q = { 0.0f, 0.0f, 0.0f, 1.0f }
78 };
79 #endif
80
81 static int playermodel( int argc, char const *argv[] )
82 {
83 if( argc < 1 ) return 0;
84
85 glmesh old_mesh = player.mdl.mesh;
86
87 if( character_load( &player.mdl, argv[0] ) )
88 mesh_free( &old_mesh );
89
90 return 1;
91 }
92
93 void vg_start(void)
94 {
95 vg_convar_push( (struct vg_convar){
96 .name = "freecam",
97 .data = &freecam,
98 .data_type = k_convar_dtype_i32,
99 .opt_i32 = { .min=0, .max=1, .clamp=1 },
100 .persistent = 1
101 });
102
103 vg_convar_push( (struct vg_convar){
104 .name = "walk_speed",
105 .data = &k_walkspeed,
106 .data_type = k_convar_dtype_f32,
107 .opt_f32 = { .clamp = 0 },
108 .persistent = 1
109 });
110
111 vg_convar_push( (struct vg_convar){
112 .name = "debugcam",
113 .data = &sv_debugcam,
114 .data_type = k_convar_dtype_i32,
115 .opt_i32 = { .min=0, .max=1, .clamp=0 },
116 .persistent = 1
117 });
118
119 vg_convar_push( (struct vg_convar){
120 .name = "debugview",
121 .data = &debugview,
122 .data_type = k_convar_dtype_i32,
123 .opt_i32 = { .min=0, .max=1, .clamp=0 },
124 .persistent = 1
125 });
126
127 vg_function_push( (struct vg_cmd){
128 .name = "reset",
129 .function = reset_player
130 });
131
132 vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
133
134 render_init();
135 gate_init();
136 terrain_init();
137 character_init();
138
139 character_load( &player.mdl, "ch_default" );
140 character_init_ragdoll( &player.mdl );
141
142 world_load();
143
144 reset_player( 1, (const char *[]){ "tutorial" } );
145 player_transform_update();
146 }
147
148 void vg_update(void)
149 {
150 player_update();
151 }
152
153 static void vg_framebuffer_resize( int w, int h )
154 {
155 render_fb_resize();
156 gate_fb_resize();
157 water_fb_resize();
158 }
159
160 void vg_render(void)
161 {
162 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
163 glViewport( 0,0, vg_window_x, vg_window_y );
164
165 glDisable( GL_DEPTH_TEST );
166 glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
167 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
168
169 float speed = freecam? 0.0f: v3_length( player.v );
170 v3f shake = { vg_randf()-0.5f, vg_randf()-0.5f, vg_randf()-0.5f };
171 v3_muls( shake, speed*0.01f, shake );
172
173 if( player.is_dead )
174 {
175 #if 0
176 v3f delta;
177 v3_sub( player.mdl.ragdoll[k_chpart_head].co, player.follow, delta );
178 v3_normalize(delta);
179
180 v3f follow_pos;
181 v3_muladds( player.mdl.ragdoll[k_chpart_head].co, delta,
182 -1.5f, follow_pos );
183 v3_lerp( player.follow, follow_pos, 0.1f, player.follow );
184 v3_negate( player.follow, final );
185
186
187 float yaw = atan2f( delta[0], -delta[2] );
188 float pitch = asinf( delta[1] );
189 m4x3_rotate_x( world_matrix, -pitch );
190 m4x3_rotate_y( world_matrix, yaw );
191 #endif
192 }
193 else
194 {
195 }
196
197 m4x4f world_4x4;
198 m4x3_expand( player.camera_inverse, world_4x4 );
199
200 gpipeline.fov = freecam? 60.0f: 100.0f; /* 120 */
201 m4x4_projection( vg_pv, gpipeline.fov,
202 (float)vg_window_x / (float)vg_window_y,
203 0.025f, 1000.0f );
204
205 m4x4_mul( vg_pv, world_4x4, vg_pv );
206
207 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 );
208 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
209 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
210
211 glEnable( GL_DEPTH_TEST );
212
213 /*
214 * Draw world
215 */
216
217 render_world( vg_pv, player.camera );
218 render_water_texture( player.camera );
219
220 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
221 render_water_surface( vg_pv );
222
223 #if 0
224 vg_tex2d_bind( &tex_water, 1 );
225 render_gate( &gate_a, cam_transform );
226 #endif
227
228
229 /* Copy the RGB of what we have into the background buffer */
230 glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
231 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, gpipeline.fb_background );
232 glBlitFramebuffer( 0,0, vg_window_x, vg_window_y,
233 0,0, vg_window_x, vg_window_y,
234 GL_COLOR_BUFFER_BIT,
235 GL_LINEAR );
236
237 /* Clear out the colour buffer, but keep depth */
238 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
239 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
240
241 if( !player.is_dead )
242 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
243 else
244 glClear( GL_COLOR_BUFFER_BIT );
245
246 draw_player();
247
248 /* Draw back in the background */
249 glEnable(GL_BLEND);
250 glDisable(GL_DEPTH_TEST);
251 glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
252 glBlendEquation(GL_FUNC_ADD);
253
254 shader_blit_use();
255 shader_blit_uTexMain( 0 );
256 glActiveTexture(GL_TEXTURE0);
257 glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
258
259 render_fsquad();
260 glDisable(GL_BLEND);
261
262 /* Other shite */
263 glDisable( GL_DEPTH_TEST );
264 vg_lines_drawall( (float *)vg_pv );
265
266 /* Debugger camera */
267 #if 0
268 glViewport( 0,0, 800, 800 );
269 glClearColor( 0.1f, 0.0f, 0.2f, 1.0f );
270 glClear( GL_DEPTH_BUFFER_BIT );
271
272 m4x3_identity( world_matrix );
273
274 v3f debugcam;
275 v3_negate( player.co, debugcam );
276 debugcam[2] -= 2.0f;
277 debugcam[1] -= 0.7f;
278
279 m4x3_translate( world_matrix, debugcam );
280 m4x3_expand( world_matrix, world_4x4 );
281
282 m4x4_projection( vg_pv,
283 100.0f,
284 (float)128.0f / (float)128.0f,
285 0.1f, 1000.0f );
286 m4x4_mul( vg_pv, world_4x4, vg_pv );
287
288 if(sv_debugcam)
289 {
290 glEnable( GL_DEPTH_TEST );
291 draw_player();
292 }
293 #endif
294
295 glDisable( GL_DEPTH_TEST );
296 vg_lines_drawall( (float *)vg_pv );
297
298 glViewport( 0,0, vg_window_x, vg_window_y );
299 }
300
301 void vg_ui(void)
302 {
303 char buf[20];
304
305 snprintf( buf, 20, "%.2fm/s", v3_length( player.v ) );
306 gui_text( (ui_px [2]){ 0, 0 }, buf, 1, k_text_align_left );
307
308 snprintf( buf, 20, "%.2f %.2f %.2f m/s",
309 player.a[0], player.a[1], player.a[2] );
310 gui_text( (ui_px [2]){ 0, 20 }, buf, 1, k_text_align_left );
311
312 snprintf( buf, 20, "pos %.2f %.2f %.2f",
313 player.co[0], player.co[1], player.co[2] );
314 gui_text( (ui_px [2]){ 0, 40 }, buf, 1, k_text_align_left );
315
316 if( vg_gamepad_ready )
317 {
318 for( int i=0; i<6; i++ )
319 {
320 snprintf( buf, 20, "%.2f", vg_gamepad.axes[i] );
321 gui_text( (ui_px [2]){ 0, (i+3)*20 }, buf, 1, k_text_align_left );
322 }
323 }
324 else
325 {
326 gui_text( (ui_px [2]){ 0, 60 },
327 "Gamepad not ready", 1, k_text_align_left );
328 }
329 }
330
331 void vg_free(void){}