cleanup+walgrid init
[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 = "debugcam",
105 .data = &sv_debugcam,
106 .data_type = k_convar_dtype_i32,
107 .opt_i32 = { .min=0, .max=1, .clamp=0 },
108 .persistent = 1
109 });
110
111 vg_convar_push( (struct vg_convar){
112 .name = "debugview",
113 .data = &debugview,
114 .data_type = k_convar_dtype_i32,
115 .opt_i32 = { .min=0, .max=1, .clamp=0 },
116 .persistent = 1
117 });
118
119 vg_function_push( (struct vg_cmd){
120 .name = "reset",
121 .function = reset_player
122 });
123
124 vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
125
126 render_init();
127 gate_init();
128 terrain_init();
129 character_init();
130
131 character_load( &player.mdl, "ch_default" );
132 character_init_ragdoll( &player.mdl );
133
134 world_load();
135
136 reset_player( 1, (const char *[]){ "tutorial" } );
137 player_transform_update();
138 }
139
140 void vg_update(void)
141 {
142 player_update();
143 }
144
145 static void vg_framebuffer_resize( int w, int h )
146 {
147 render_fb_resize();
148 gate_fb_resize();
149 water_fb_resize();
150 }
151
152 void vg_render(void)
153 {
154 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
155 glViewport( 0,0, vg_window_x, vg_window_y );
156
157 glDisable( GL_DEPTH_TEST );
158 glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
159 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
160
161 float speed = freecam? 0.0f: v3_length( player.v );
162 v3f shake = { vg_randf()-0.5f, vg_randf()-0.5f, vg_randf()-0.5f };
163 v3_muls( shake, speed*0.01f, shake );
164
165 if( player.is_dead )
166 {
167 #if 0
168 v3f delta;
169 v3_sub( player.mdl.ragdoll[k_chpart_head].co, player.follow, delta );
170 v3_normalize(delta);
171
172 v3f follow_pos;
173 v3_muladds( player.mdl.ragdoll[k_chpart_head].co, delta,
174 -1.5f, follow_pos );
175 v3_lerp( player.follow, follow_pos, 0.1f, player.follow );
176 v3_negate( player.follow, final );
177
178
179 float yaw = atan2f( delta[0], -delta[2] );
180 float pitch = asinf( delta[1] );
181 m4x3_rotate_x( world_matrix, -pitch );
182 m4x3_rotate_y( world_matrix, yaw );
183 #endif
184 }
185 else
186 {
187 }
188
189 m4x4f world_4x4;
190 m4x3_expand( player.camera_inverse, world_4x4 );
191
192 gpipeline.fov = freecam? 60.0f: 120.0f;
193 m4x4_projection( vg_pv, gpipeline.fov,
194 (float)vg_window_x / (float)vg_window_y,
195 0.025f, 1000.0f );
196
197 m4x4_mul( vg_pv, world_4x4, vg_pv );
198
199 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 );
200 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
201 vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
202
203 glEnable( GL_DEPTH_TEST );
204
205 /*
206 * Draw world
207 */
208
209 render_world( vg_pv, player.camera );
210 render_water_texture( player.camera );
211
212 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
213 render_water_surface( vg_pv );
214
215 #if 0
216 vg_tex2d_bind( &tex_water, 1 );
217 render_gate( &gate_a, cam_transform );
218 #endif
219
220
221 /* Copy the RGB of what we have into the background buffer */
222 glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
223 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, gpipeline.fb_background );
224 glBlitFramebuffer( 0,0, vg_window_x, vg_window_y,
225 0,0, vg_window_x, vg_window_y,
226 GL_COLOR_BUFFER_BIT,
227 GL_LINEAR );
228
229 /* Clear out the colour buffer, but keep depth */
230 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
231 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
232
233 if( !player.is_dead )
234 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
235 else
236 glClear( GL_COLOR_BUFFER_BIT );
237
238 draw_player();
239
240 /* Draw back in the background */
241 glEnable(GL_BLEND);
242 glDisable(GL_DEPTH_TEST);
243 glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
244 glBlendEquation(GL_FUNC_ADD);
245
246 shader_blit_use();
247 shader_blit_uTexMain( 0 );
248 glActiveTexture(GL_TEXTURE0);
249 glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
250
251 render_fsquad();
252 glDisable(GL_BLEND);
253
254 /* Other shite */
255 glDisable( GL_DEPTH_TEST );
256 vg_lines_drawall( (float *)vg_pv );
257
258 /* Debugger camera */
259 #if 0
260 glViewport( 0,0, 800, 800 );
261 glClearColor( 0.1f, 0.0f, 0.2f, 1.0f );
262 glClear( GL_DEPTH_BUFFER_BIT );
263
264 m4x3_identity( world_matrix );
265
266 v3f debugcam;
267 v3_negate( player.co, debugcam );
268 debugcam[2] -= 2.0f;
269 debugcam[1] -= 0.7f;
270
271 m4x3_translate( world_matrix, debugcam );
272 m4x3_expand( world_matrix, world_4x4 );
273
274 m4x4_projection( vg_pv,
275 100.0f,
276 (float)128.0f / (float)128.0f,
277 0.1f, 1000.0f );
278 m4x4_mul( vg_pv, world_4x4, vg_pv );
279
280 if(sv_debugcam)
281 {
282 glEnable( GL_DEPTH_TEST );
283 draw_player();
284 }
285 #endif
286
287 glDisable( GL_DEPTH_TEST );
288 vg_lines_drawall( (float *)vg_pv );
289
290 glViewport( 0,0, vg_window_x, vg_window_y );
291 }
292
293 void vg_ui(void)
294 {
295 char buf[20];
296
297 snprintf( buf, 20, "%.2fm/s", v3_length( player.v ) );
298 gui_text( (ui_px [2]){ 0, 0 }, buf, 1, k_text_align_left );
299
300 snprintf( buf, 20, "%.2f %.2f %.2f m/s",
301 player.a[0], player.a[1], player.a[2] );
302 gui_text( (ui_px [2]){ 0, 20 }, buf, 1, k_text_align_left );
303
304 snprintf( buf, 20, "pos %.2f %.2f %.2f",
305 player.co[0], player.co[1], player.co[2] );
306 gui_text( (ui_px [2]){ 0, 40 }, buf, 1, k_text_align_left );
307
308 if( vg_gamepad_ready )
309 {
310 for( int i=0; i<6; i++ )
311 {
312 snprintf( buf, 20, "%.2f", vg_gamepad.axes[i] );
313 gui_text( (ui_px [2]){ 0, (i+3)*20 }, buf, 1, k_text_align_left );
314 }
315 }
316 else
317 {
318 gui_text( (ui_px [2]){ 0, 60 },
319 "Gamepad not ready", 1, k_text_align_left );
320 }
321 }
322
323 void vg_free(void){}