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