df shadows
[carveJwlIkooP6JGAAIwe30JlM.git] / world_render.h
1 /*
2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 */
4
5 #ifndef WORLD_RENDER_H
6 #define WORLD_RENDER_H
7
8 #include "camera.h"
9 #include "world.h"
10
11 /* FIXME */
12 VG_STATIC vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
13 .flags = VG_TEXTURE_NEAREST };
14
15 VG_STATIC void world_render_init(void)
16 {
17 vg_info( "Loading default world textures\n" );
18
19 vg_acquire_thread_sync();
20 {
21 vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_noise }, 1 );
22 }
23 vg_release_thread_sync();
24 }
25
26 VG_STATIC void render_world_depth( camera *cam );
27
28 /*
29 * Rendering
30 */
31
32 VG_STATIC void bind_terrain_noise(void)
33 {
34 vg_tex2d_bind( &tex_terrain_noise, 0 );
35 }
36
37 VG_STATIC void world_render_if( enum mdl_shader shader,
38 enum geo_type geo_type,
39 void (*bind_point)(struct world_material *mat))
40 {
41
42 for( int i=0; i<world.material_count; i++ )
43 {
44 struct world_material *mat = &world.materials[i];
45
46 if( mat->info.shader == shader )
47 {
48 mdl_submesh *sm;
49
50 if( geo_type == k_geo_type_solid )
51 sm = &mat->sm_geo;
52 else
53 sm = &mat->sm_no_collide;
54
55 if( !sm->indice_count )
56 continue;
57
58 bind_point( mat );
59 mdl_draw_submesh( sm );
60 }
61 }
62 }
63
64 VG_STATIC void world_render_both_stages( enum mdl_shader shader,
65 void (*bind_point)(struct world_material *mat))
66 {
67 mesh_bind( &world.mesh_geo );
68 world_render_if( shader, k_geo_type_solid, bind_point );
69
70 glDisable( GL_CULL_FACE );
71 mesh_bind( &world.mesh_no_collide );
72 world_render_if( shader, k_geo_type_nonsolid, bind_point );
73 glEnable( GL_CULL_FACE );
74 }
75
76 VG_STATIC void bindpoint_diffuse_texture1( struct world_material *mat )
77 {
78 glActiveTexture( GL_TEXTURE1 );
79 glBindTexture( GL_TEXTURE_2D, world.textures[ mat->info.tex_diffuse ] );
80 }
81
82 VG_STATIC void render_world_vb( camera *cam )
83 {
84 m4x3f identity_matrix;
85 m4x3_identity( identity_matrix );
86
87 shader_vblend_use();
88 shader_vblend_uTexGarbage(0);
89 shader_vblend_uTexGradients(1);
90 shader_link_standard_ub( _shader_vblend.id, 2 );
91 vg_tex2d_bind( &tex_terrain_noise, 0 );
92
93 shader_vblend_uPv( cam->mtx.pv );
94 shader_vblend_uPvmPrev( cam->mtx_prev.pv );
95 shader_vblend_uMdl( identity_matrix );
96 shader_vblend_uCamera( cam->transform[3] );
97 shader_vblend_uBoard0( TEMP_BOARD_0 );
98 shader_vblend_uBoard1( TEMP_BOARD_1 );
99
100 world_render_both_stages( k_shader_standard_vertex_blend,
101 bindpoint_diffuse_texture1 );
102 }
103
104 VG_STATIC void render_world_standard( camera *cam )
105 {
106 m4x3f identity_matrix;
107 m4x3_identity( identity_matrix );
108
109 shader_standard_use();
110 shader_standard_uTexGarbage(0);
111 shader_standard_uTexMain(1);
112 shader_standard_uPv( cam->mtx.pv );
113 shader_standard_uPvmPrev( cam->mtx_prev.pv );
114 shader_link_standard_ub( _shader_standard.id, 2 );
115 bind_terrain_noise();
116
117 shader_standard_uMdl( identity_matrix );
118 shader_standard_uCamera( cam->transform[3] );
119 shader_standard_uBoard0( TEMP_BOARD_0 );
120 shader_standard_uBoard1( TEMP_BOARD_1 );
121
122 world_render_both_stages( k_shader_standard,
123 bindpoint_diffuse_texture1 );
124 }
125
126 VG_STATIC void render_world_alphatest( camera *cam )
127 {
128 m4x3f identity_matrix;
129 m4x3_identity( identity_matrix );
130
131 shader_alphatest_use();
132 shader_alphatest_uTexGarbage(0);
133 shader_alphatest_uTexMain(1);
134 shader_alphatest_uPv( cam->mtx.pv );
135 shader_alphatest_uPvmPrev( cam->mtx_prev.pv );
136 shader_link_standard_ub( _shader_alphatest.id, 2 );
137 bind_terrain_noise();
138
139 shader_alphatest_uMdl( identity_matrix );
140 shader_alphatest_uCamera( cam->transform[3] );
141 shader_alphatest_uBoard0( TEMP_BOARD_0 );
142 shader_alphatest_uBoard1( TEMP_BOARD_1 );
143
144 glDisable(GL_CULL_FACE);
145
146 world_render_both_stages( k_shader_standard_cutout,
147 bindpoint_diffuse_texture1 );
148
149 glEnable(GL_CULL_FACE);
150 }
151
152 VG_STATIC void bindpoint_terrain( struct world_material *mat )
153 {
154 glActiveTexture( GL_TEXTURE1 );
155 glBindTexture( GL_TEXTURE_2D, world.textures[ mat->info.tex_diffuse ] );
156
157 shader_terrain_uSandColour( mat->info.colour );
158 shader_terrain_uBlendOffset( mat->info.colour1 );
159 }
160
161 VG_STATIC void render_terrain( camera *cam )
162 {
163 m4x3f identity_matrix;
164 m4x3_identity( identity_matrix );
165
166 shader_terrain_use();
167 shader_terrain_uTexGarbage(0);
168 shader_terrain_uTexGradients(1);
169 shader_link_standard_ub( _shader_terrain.id, 2 );
170
171 vg_tex2d_bind( &tex_terrain_noise, 0 );
172
173 shader_terrain_uPv( cam->mtx.pv );
174 shader_terrain_uPvmPrev( cam->mtx_prev.pv );
175
176 shader_terrain_uMdl( identity_matrix );
177 shader_terrain_uCamera( cam->transform[3] );
178 shader_terrain_uBoard0( TEMP_BOARD_0 );
179 shader_terrain_uBoard1( TEMP_BOARD_1 );
180
181 world_render_both_stages( k_shader_terrain_blend, bindpoint_terrain );
182 }
183
184 VG_STATIC void render_sky( camera *cam )
185 {
186 /*
187 * Modify matrix to remove clipping and view translation
188 */
189 m4x4f v,
190 v_prev,
191 pv,
192 pv_prev;
193
194 m4x4_copy( cam->mtx.v, v );
195 m4x4_copy( cam->mtx_prev.v, v_prev );
196 v3_zero( v[3] );
197 v3_zero( v_prev[3] );
198
199 m4x4_copy( cam->mtx.p, pv );
200 m4x4_copy( cam->mtx_prev.p, pv_prev );
201 m4x4_reset_clipping( pv, cam->farz, cam->nearz );
202 m4x4_reset_clipping( pv_prev, cam->farz, cam->nearz );
203
204 m4x4_mul( pv, v, pv );
205 m4x4_mul( pv_prev, v_prev, pv_prev );
206
207 m4x3f identity_matrix;
208 m4x3_identity( identity_matrix );
209
210 /*
211 * Draw
212 */
213 shader_sky_use();
214 shader_sky_uMdl( identity_matrix );
215 shader_sky_uPv( pv );
216 shader_sky_uPvmPrev( pv_prev );
217 shader_sky_uTexGarbage(0);
218 shader_sky_uTime( world.sky_time );
219
220 vg_tex2d_bind( &tex_terrain_noise, 0 );
221
222 glDepthMask( GL_FALSE );
223 glDisable( GL_DEPTH_TEST );
224
225 mesh_bind( &world.skydome );
226 mdl_draw_submesh( &world.dome_upper );
227
228 glEnable( GL_DEPTH_TEST );
229 glDepthMask( GL_TRUE );
230 }
231
232 VG_STATIC void render_world_gates( camera *cam )
233 {
234 if( !world.gate_count )
235 return;
236
237 float closest = INFINITY;
238 int id = 0;
239
240 for( int i=0; i<world.gate_count; i++ )
241 {
242 struct route_gate *rg = &world.gates[i];
243 float dist = v3_dist2( rg->gate.co[0], cam->transform[3] );
244
245 if( dist < closest )
246 {
247 closest = dist;
248 id = i;
249 }
250 }
251
252 render_gate( &world.gates[id].gate, cam );
253 v3_lerp( world.render_gate_pos,
254 world.gates[id].gate.co[0],
255 1.0f,
256 world.render_gate_pos );
257 }
258
259 VG_STATIC void render_world( camera *cam )
260 {
261 render_sky( cam );
262
263 render_world_routes( cam );
264 render_world_standard( cam );
265 render_world_vb( cam );
266 render_world_alphatest( cam );
267 render_terrain( cam );
268
269 /* Render SFD's */
270 int closest = 0;
271 float min_dist = INFINITY;
272
273 if( !world.route_count )
274 return;
275
276 for( int i=0; i<world.route_count; i++ )
277 {
278 float dist = v3_dist2(world.routes[i].scoreboard_transform[3], cam->pos);
279
280 if( dist < min_dist )
281 {
282 min_dist = dist;
283 closest = i;
284 }
285 }
286
287 sfd_render( cam, world.routes[closest].scoreboard_transform );
288 }
289
290 VG_STATIC void render_world_depth( camera *cam )
291 {
292 m4x3f identity_matrix;
293 m4x3_identity( identity_matrix );
294
295 shader_gpos_use();
296 shader_gpos_uCamera( cam->transform[3] );
297 shader_gpos_uPv( cam->mtx.pv );
298 shader_gpos_uPvmPrev( cam->mtx_prev.pv );
299 shader_gpos_uMdl( identity_matrix );
300
301 mesh_bind( &world.mesh_geo );
302 mesh_draw( &world.mesh_geo );
303
304 #if 0
305 glDisable(GL_CULL_FACE);
306 scene_bind( &world.foliage );
307 scene_draw( &world.foliage );
308 glEnable(GL_CULL_FACE);
309 #endif
310 }
311
312 #endif /* WORLD_RENDER_H */