6b38fc5401b69366bb36a1872d3b81c7c4451b06
[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 #endif
72
73 static int playermodel( int argc, char const *argv[] )
74 {
75 if( argc < 1 ) return 0;
76
77 glmesh old_mesh = player.mdl.mesh;
78
79 if( character_load( &player.mdl, argv[0] ) )
80 mesh_free( &old_mesh );
81
82 return 1;
83 }
84
85 void vg_start(void)
86 {
87 vg_convar_push( (struct vg_convar){
88 .name = "freecam",
89 .data = &freecam,
90 .data_type = k_convar_dtype_i32,
91 .opt_i32 = { .min=0, .max=1, .clamp=1 },
92 .persistent = 1
93 });
94
95 vg_convar_push( (struct vg_convar){
96 .name = "grid",
97 .data = &walk_grid_iterations,
98 .data_type = k_convar_dtype_i32,
99 .opt_i32 = { .min=0, .max=1, .clamp=0 },
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 | GL_STENCIL_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: 120.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 vg_tex2d_bind( &tex_water, 1 );
224
225 for( int i=0; i<world.gate_count; i++ )
226 {
227 render_gate( &world.gates[i], player.camera );
228 }
229
230
231 /* Copy the RGB of what we have into the background buffer */
232 glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
233 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, gpipeline.fb_background );
234 glBlitFramebuffer( 0,0, vg_window_x, vg_window_y,
235 0,0, vg_window_x, vg_window_y,
236 GL_COLOR_BUFFER_BIT,
237 GL_LINEAR );
238
239 /* Clear out the colour buffer, but keep depth */
240 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
241 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
242
243 if( !player.is_dead )
244 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
245 else
246 glClear( GL_COLOR_BUFFER_BIT );
247
248 draw_player();
249
250 /* Draw back in the background */
251 glEnable(GL_BLEND);
252 glDisable(GL_DEPTH_TEST);
253 glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
254 glBlendEquation(GL_FUNC_ADD);
255
256 shader_blit_use();
257 shader_blit_uTexMain( 0 );
258 glActiveTexture(GL_TEXTURE0);
259 glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
260
261 render_fsquad();
262 glDisable(GL_BLEND);
263
264 /* Other shite */
265 glDisable( GL_DEPTH_TEST );
266 vg_lines_drawall( (float *)vg_pv );
267
268 /* Debugger camera */
269 #if 0
270 glViewport( 0,0, 800, 800 );
271 glClearColor( 0.1f, 0.0f, 0.2f, 1.0f );
272 glClear( GL_DEPTH_BUFFER_BIT );
273
274 m4x3_identity( world_matrix );
275
276 v3f debugcam;
277 v3_negate( player.co, debugcam );
278 debugcam[2] -= 2.0f;
279 debugcam[1] -= 0.7f;
280
281 m4x3_translate( world_matrix, debugcam );
282 m4x3_expand( world_matrix, world_4x4 );
283
284 m4x4_projection( vg_pv,
285 100.0f,
286 (float)128.0f / (float)128.0f,
287 0.1f, 1000.0f );
288 m4x4_mul( vg_pv, world_4x4, vg_pv );
289
290 if(sv_debugcam)
291 {
292 glEnable( GL_DEPTH_TEST );
293 draw_player();
294 }
295 #endif
296
297 glDisable( GL_DEPTH_TEST );
298 vg_lines_drawall( (float *)vg_pv );
299
300 glViewport( 0,0, vg_window_x, vg_window_y );
301 }
302
303 void vg_ui(void)
304 {
305 char buf[20];
306
307 snprintf( buf, 20, "%.2fm/s", v3_length( player.v ) );
308 gui_text( (ui_px [2]){ 0, 0 }, buf, 1, k_text_align_left );
309
310 snprintf( buf, 20, "%.2f %.2f %.2f m/s",
311 player.a[0], player.a[1], player.a[2] );
312 gui_text( (ui_px [2]){ 0, 20 }, buf, 1, k_text_align_left );
313
314 snprintf( buf, 20, "pos %.2f %.2f %.2f",
315 player.co[0], player.co[1], player.co[2] );
316 gui_text( (ui_px [2]){ 0, 40 }, buf, 1, k_text_align_left );
317
318 if( vg_gamepad_ready )
319 {
320 for( int i=0; i<6; i++ )
321 {
322 snprintf( buf, 20, "%.2f", vg_gamepad.axes[i] );
323 gui_text( (ui_px [2]){ 0, (i+3)*20 }, buf, 1, k_text_align_left );
324 }
325 }
326 else
327 {
328 gui_text( (ui_px [2]){ 0, 60 },
329 "Gamepad not ready", 1, k_text_align_left );
330 }
331 }
332
333 void vg_free(void){}