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