model fmt & heisenbug
[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 "world.h"
9
10 vg_tex2d tex_terrain_colours = { .path = "textures/gradients.qoi",
11 .flags = VG_TEXTURE_CLAMP|VG_TEXTURE_NEAREST };
12
13 vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
14 .flags = VG_TEXTURE_NEAREST };
15
16 vg_tex2d tex_alphatest = { .path = "textures/alphatest.qoi",
17 .flags = VG_TEXTURE_NEAREST };
18
19 vg_tex2d tex_graffiti = { .path = "textures/graffitibox.qoi",
20 .flags = VG_TEXTURE_NEAREST };
21
22 VG_STATIC void world_render_init(void)
23 {
24 vg_info( "Loading default world textures\n" );
25
26 vg_acquire_thread_sync();
27 {
28 vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_colours,
29 &tex_terrain_noise,
30 &tex_alphatest,
31 &tex_graffiti }, 4 );
32 }
33 vg_release_thread_sync();
34 }
35
36 VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera );
37
38 /*
39 * Rendering
40 */
41
42 VG_STATIC void bind_terrain_textures(void)
43 {
44 vg_tex2d_bind( &tex_terrain_noise, 0 );
45 vg_tex2d_bind( &tex_terrain_colours, 1 );
46 }
47
48 VG_STATIC void render_world_vb( m4x4f projection, v3f camera )
49 {
50 m4x3f identity_matrix;
51 m4x3_identity( identity_matrix );
52
53 shader_vblend_use();
54 shader_vblend_uTexGarbage(0);
55 shader_vblend_uTexGradients(1);
56 shader_link_standard_ub( _shader_vblend.id, 2 );
57 bind_terrain_textures();
58
59 shader_vblend_uPv( projection );
60 shader_vblend_uMdl( identity_matrix );
61 shader_vblend_uCamera( camera );
62
63 mesh_bind( &world.mesh_geo );
64 mdl_draw_submesh( &world.sm_geo_vb );
65 }
66
67 VG_STATIC void render_world_alphatest( m4x4f projection, v3f camera )
68 {
69 m4x3f identity_matrix;
70 m4x3_identity( identity_matrix );
71
72 shader_alphatest_use();
73 shader_alphatest_uTexGarbage(0);
74 shader_alphatest_uTexMain(1);
75 shader_link_standard_ub( _shader_alphatest.id, 2 );
76
77 vg_tex2d_bind( &tex_terrain_noise, 0 );
78 vg_tex2d_bind( &tex_alphatest, 1 );
79
80 shader_alphatest_uPv( projection );
81 shader_alphatest_uMdl( identity_matrix );
82 shader_alphatest_uCamera( camera );
83
84 glDisable(GL_CULL_FACE);
85 mesh_bind( &world.mesh_no_collide );
86 mdl_draw_submesh( &world.sm_foliage_alphatest );
87
88 vg_tex2d_bind( &tex_graffiti, 1 );
89 mdl_draw_submesh( &world.sm_graffiti );
90
91 glEnable(GL_CULL_FACE);
92 }
93
94 VG_STATIC void render_terrain( m4x4f projection, v3f camera )
95 {
96 m4x3f identity_matrix;
97 m4x3_identity( identity_matrix );
98
99 shader_terrain_use();
100 shader_terrain_uTexGarbage(0);
101 shader_terrain_uTexGradients(1);
102 shader_link_standard_ub( _shader_terrain.id, 2 );
103 bind_terrain_textures();
104
105 shader_terrain_uPv( projection );
106 shader_terrain_uMdl( identity_matrix );
107 shader_terrain_uCamera( camera );
108
109 mesh_bind( &world.mesh_geo );
110 mdl_draw_submesh( &world.sm_terrain );
111 mdl_draw_submesh( &world.sm_geo_std_oob );
112 mdl_draw_submesh( &world.sm_geo_std );
113 mdl_draw_submesh( &world.sm_subworld );
114
115 /* TODO: Dont draw in reflection */
116 glDisable( GL_CULL_FACE );
117 mesh_bind( &world.mesh_no_collide );
118 mdl_draw_submesh( &world.sm_foliage_main );
119 glEnable( GL_CULL_FACE );
120 }
121
122 VG_STATIC void render_lowerdome( m4x3f camera )
123 {
124 m4x4f projection, full;
125 pipeline_projection( projection, 0.4f, 1000.0f );
126
127 m4x3f inverse;
128 m3x3_transpose( camera, inverse );
129 v3_copy((v3f){0.0f,0.0f,0.0f}, inverse[3]);
130 m4x3_expand( inverse, full );
131 m4x4_mul( projection, full, full );
132
133 m4x3f identity_matrix;
134 m4x3_identity( identity_matrix );
135
136 shader_planeinf_use();
137 shader_planeinf_uMdl(identity_matrix);
138 shader_planeinf_uPv(full);
139 shader_planeinf_uCamera(camera[3]);
140 shader_planeinf_uPlane( (v4f){0.0f,1.0f,0.0f,0.0f} );
141
142 mdl_draw_submesh( &world.dome_lower );
143 }
144
145 VG_STATIC void render_sky(m4x3f camera)
146 {
147 m4x4f projection, full;
148 pipeline_projection( projection, 0.4f, 1000.0f );
149
150 m4x3f inverse;
151 m3x3_transpose( camera, inverse );
152 v3_copy((v3f){0.0f,0.0f,0.0f}, inverse[3]);
153 m4x3_expand( inverse, full );
154 m4x4_mul( projection, full, full );
155
156 m4x3f identity_matrix;
157 m4x3_identity( identity_matrix );
158
159 shader_sky_use();
160 shader_sky_uMdl(identity_matrix);
161 shader_sky_uPv(full);
162 shader_sky_uTexGarbage(0);
163 shader_sky_uTime( world.sky_time );
164
165 vg_tex2d_bind( &tex_terrain_noise, 0 );
166
167 glDepthMask( GL_FALSE );
168 glDisable( GL_DEPTH_TEST );
169
170 mesh_bind( &world.skydome );
171 mdl_draw_submesh( &world.dome_upper );
172
173 glEnable( GL_DEPTH_TEST );
174 glDepthMask( GL_TRUE );
175 }
176
177 VG_STATIC void render_world_gates( m4x4f projection, v3f playerco, m4x3f camera )
178 {
179 if( !world.gate_count )
180 return;
181
182 float closest = INFINITY;
183 int id = 0;
184
185 for( int i=0; i<world.gate_count; i++ )
186 {
187 struct route_gate *rg = &world.gates[i];
188 float dist = v3_dist2( rg->gate.co[0], camera[3] );
189
190 if( dist < closest )
191 {
192 closest = dist;
193 id = i;
194 }
195 }
196
197 render_gate( &world.gates[id].gate, playerco, camera );
198 v3_lerp( world.render_gate_pos,
199 world.gates[id].gate.co[0],
200 1.0f,
201 world.render_gate_pos );
202 }
203
204 VG_STATIC void render_world( m4x4f projection, m4x3f camera )
205 {
206 render_sky( camera );
207 render_world_routes( projection, camera[3] );
208 render_world_vb( projection, camera[3] );
209 render_world_alphatest( projection, camera[3] );
210 render_terrain( projection, camera[3] );
211
212 int closest = 0;
213 float min_dist = INFINITY;
214
215 if( !world.route_count )
216 return;
217
218 for( int i=0; i<world.route_count; i++ )
219 {
220 float dist = v3_dist2( world.routes[i].scoreboard_transform[3],
221 camera[3] );
222
223 if( dist < min_dist )
224 {
225 min_dist = dist;
226 closest = i;
227 }
228 }
229
230 sfd_render( projection, camera[3],
231 world.routes[closest].scoreboard_transform );
232 }
233
234 VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera )
235 {
236 m4x3f identity_matrix;
237 m4x3_identity( identity_matrix );
238
239 shader_gpos_use();
240 shader_gpos_uCamera( camera[3] );
241 shader_gpos_uPv( projection );
242 shader_gpos_uMdl( identity_matrix );
243
244 mesh_bind( &world.mesh_geo );
245 mesh_draw( &world.mesh_geo );
246
247 #if 0
248 glDisable(GL_CULL_FACE);
249 scene_bind( &world.foliage );
250 scene_draw( &world.foliage );
251 glEnable(GL_CULL_FACE);
252 #endif
253 }
254
255 #endif /* WORLD_RENDER_H */