audio&island
[carveJwlIkooP6JGAAIwe30JlM.git] / main.c
1 /*
2 * Copyright (C) Mount0 Software, Harry Godden - All Rights Reserved
3 */
4
5 #include "common.h"
6
7 /* Resources */
8 vg_tex2d tex_norwey = { .path = "textures/norway_foliage.qoi" };
9 vg_tex2d tex_grid = { .path = "textures/grid.qoi" };
10 vg_tex2d tex_sky = { .path = "textures/sky.qoi" };
11 vg_tex2d tex_gradients = { .path = "textures/gradients.qoi",
12 .flags = VG_TEXTURE_CLAMP };
13 vg_tex2d tex_cement = { .path = "textures/cement512.qoi" };
14 vg_tex2d tex_water = { .path = "textures/water.qoi" };
15
16 /* Convars */
17 static int debugview = 0;
18 static int sv_debugcam = 0;
19
20 /* Components */
21 #include "road.h"
22 #include "scene.h"
23 #include "ik.h"
24 #include "audio.h"
25 #include "terrain.h"
26 #include "character.h"
27 #include "ragdoll.h"
28 #include "rigidbody.h"
29 #include "render.h"
30 #include "gate.h"
31 #include "water.h"
32 #include "world.h"
33 #include "player.h"
34
35 #include "shaders/blit.h"
36 #include "shaders/standard.h"
37 #include "shaders/unlit.h"
38
39 void vg_register(void)
40 {
41 shader_blit_register();
42 shader_standard_register();
43 shader_unlit_register();
44
45 terrain_register();
46 character_register();
47 water_register();
48 gate_register();
49 }
50
51 static void init_other(void)
52 {
53 render_init();
54 gate_init();
55 terrain_init();
56 character_init();
57 audio_init();
58 }
59
60 vg_tex2d *texture_list[] =
61 {
62 &tex_norwey,
63 &tex_gradients,
64 &tex_grid,
65 &tex_sky,
66 &tex_cement,
67 &tex_water,
68 &tex_water_surf
69 };
70
71 int main( int argc, char *argv[] )
72 {
73 vg_init( argc, argv, "Voyager Game Engine" );
74 }
75
76 static int playermodel( int argc, char const *argv[] )
77 {
78 if( argc < 1 ) return 0;
79
80 glmesh old_mesh = player.mdl.mesh;
81
82 if( character_load( &player.mdl, argv[0] ) )
83 mesh_free( &old_mesh );
84
85 return 1;
86 }
87
88 void vg_start(void)
89 {
90 vg_convar_push( (struct vg_convar){
91 .name = "freecam",
92 .data = &freecam,
93 .data_type = k_convar_dtype_i32,
94 .opt_i32 = { .min=0, .max=1, .clamp=1 },
95 .persistent = 1
96 });
97
98 vg_convar_push( (struct vg_convar){
99 .name = "grid",
100 .data = &walk_grid_iterations,
101 .data_type = k_convar_dtype_i32,
102 .opt_i32 = { .min=0, .max=1, .clamp=0 },
103 .persistent = 1
104 });
105
106 vg_convar_push( (struct vg_convar){
107 .name = "walk_speed",
108 .data = &k_walkspeed,
109 .data_type = k_convar_dtype_f32,
110 .opt_f32 = { .clamp = 0 },
111 .persistent = 1
112 });
113
114 vg_convar_push( (struct vg_convar){
115 .name = "debugcam",
116 .data = &sv_debugcam,
117 .data_type = k_convar_dtype_i32,
118 .opt_i32 = { .min=0, .max=1, .clamp=0 },
119 .persistent = 1
120 });
121
122 vg_convar_push( (struct vg_convar){
123 .name = "debugview",
124 .data = &debugview,
125 .data_type = k_convar_dtype_i32,
126 .opt_i32 = { .min=0, .max=1, .clamp=0 },
127 .persistent = 1
128 });
129
130 vg_function_push( (struct vg_cmd){
131 .name = "reset",
132 .function = reset_player
133 });
134
135 vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
136
137 init_other();
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_free(void)
149 {
150 vg_tex2d_free( texture_list, vg_list_size(texture_list) );
151 }
152
153 void vg_update(void)
154 {
155 player_update();
156 }
157
158 static void vg_framebuffer_resize( int w, int h )
159 {
160 render_fb_resize();
161 gate_fb_resize();
162 water_fb_resize();
163 }
164
165 void vg_render(void)
166 {
167 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
168 glViewport( 0,0, vg_window_x, vg_window_y );
169
170 glDisable( GL_DEPTH_TEST );
171 glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
172 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
173
174 float speed = freecam? 0.0f: v3_length( player.v );
175 v3f shake = { vg_randf()-0.5f, vg_randf()-0.5f, vg_randf()-0.5f };
176 v3_muls( shake, speed*0.01f, shake );
177
178 m4x4f world_4x4;
179 m4x3_expand( player.camera_inverse, world_4x4 );
180
181 gpipeline.fov = freecam? 60.0f: 135.0f; /* 120 */
182 m4x4_projection( vg_pv, gpipeline.fov,
183 (float)vg_window_x / (float)vg_window_y,
184 0.1f, 1500.0f );
185
186 m4x4_mul( vg_pv, world_4x4, vg_pv );
187
188 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 );
189 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
190 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
191
192 glEnable( GL_DEPTH_TEST );
193
194 /*
195 * Draw world
196 */
197
198 render_world( vg_pv, player.camera );
199 render_water_texture( player.camera );
200
201 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
202 render_water_surface( vg_pv, player.camera );
203
204 vg_tex2d_bind( &tex_water, 1 );
205
206 for( int i=0; i<world.gate_count; i++ )
207 {
208 render_gate( &world.gates[i], player.camera );
209 }
210
211
212 /* Copy the RGB of what we have into the background buffer */
213 glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
214 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, gpipeline.fb_background );
215 glBlitFramebuffer( 0,0, vg_window_x, vg_window_y,
216 0,0, vg_window_x, vg_window_y,
217 GL_COLOR_BUFFER_BIT,
218 GL_LINEAR );
219
220 /* Clear out the colour buffer, but keep depth */
221 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
222 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
223
224 if( !player.is_dead )
225 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
226 else
227 glClear( GL_COLOR_BUFFER_BIT );
228
229 draw_player();
230
231 /* Draw back in the background
232 *
233 * TODO: need to disable alpha write in the terrain shader so this works
234 * again.
235 */
236 glEnable(GL_BLEND);
237 glDisable(GL_DEPTH_TEST);
238 glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
239 glBlendEquation(GL_FUNC_ADD);
240
241 shader_blit_use();
242 shader_blit_uTexMain( 0 );
243 glActiveTexture(GL_TEXTURE0);
244 glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
245
246 render_fsquad();
247 glDisable(GL_BLEND);
248
249 /* Other shite */
250 glDisable( GL_DEPTH_TEST );
251 vg_lines_drawall( (float *)vg_pv );
252 glViewport( 0,0, vg_window_x, vg_window_y );
253 }
254
255 void vg_ui(void)
256 {
257 char buf[20];
258
259 snprintf( buf, 20, "%.2fm/s", v3_length( player.v ) );
260 gui_text( (ui_px [2]){ 0, 0 }, buf, 1, k_text_align_left );
261
262 snprintf( buf, 20, "%.2f %.2f %.2f m/s",
263 player.a[0], player.a[1], player.a[2] );
264 gui_text( (ui_px [2]){ 0, 20 }, buf, 1, k_text_align_left );
265
266 snprintf( buf, 20, "pos %.2f %.2f %.2f",
267 player.co[0], player.co[1], player.co[2] );
268 gui_text( (ui_px [2]){ 0, 40 }, buf, 1, k_text_align_left );
269
270 if( vg_gamepad_ready )
271 {
272 for( int i=0; i<6; i++ )
273 {
274 snprintf( buf, 20, "%.2f", vg_gamepad.axes[i] );
275 gui_text( (ui_px [2]){ 0, (i+3)*20 }, buf, 1, k_text_align_left );
276 }
277 }
278 else
279 {
280 gui_text( (ui_px [2]){ 0, 60 },
281 "Gamepad not ready", 1, k_text_align_left );
282 }
283 }