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