2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
12 VG_STATIC vg_tex2d tex_terrain_noise
= { .path
= "textures/garbage.qoi",
13 .flags
= VG_TEXTURE_NEAREST
};
15 VG_STATIC
void world_render_init(void)
17 vg_info( "Loading default world textures\n" );
19 vg_acquire_thread_sync();
21 vg_tex2d_init( (vg_tex2d
*[]){ &tex_terrain_noise
}, 1 );
24 vg_info( "Allocate uniform buffers\n" );
25 for( int i
=0; i
<4; i
++ )
27 world_instance
*world
= &world_global
.worlds
[i
];
28 world
->ubo_bind_point
= i
;
30 glGenBuffers( 1, &world
->ubo_lighting
);
31 glBindBuffer( GL_UNIFORM_BUFFER
, world
->ubo_lighting
);
32 glBufferData( GL_UNIFORM_BUFFER
, sizeof(struct ub_world_lighting
),
33 NULL
, GL_DYNAMIC_DRAW
);
35 glBindBufferBase( GL_UNIFORM_BUFFER
, i
, world
->ubo_lighting
);
39 vg_info( "Allocate frame buffers\n" );
40 for( int i
=0; i
<4; i
++ )
42 world_instance
*world
= &world_global
.worlds
[i
];
43 struct framebuffer
*fb
= &world
->heightmap
;
45 fb
->display_name
= NULL
;
49 fb
->resolution_div
= 0;
51 /* TODO: We could get away with this being R16u, and just have it be
52 * a normed value between min and max of the bounding box Y */
54 fb
->attachments
[0].display_name
= NULL
;
55 fb
->attachments
[0].purpose
= k_framebuffer_attachment_type_colour
;
56 fb
->attachments
[0].internalformat
= GL_RG16F
;
57 fb
->attachments
[0].format
= GL_RG
;
58 fb
->attachments
[0].type
= GL_FLOAT
;
59 fb
->attachments
[0].attachment
= GL_COLOR_ATTACHMENT0
;
61 fb
->attachments
[1].purpose
= k_framebuffer_attachment_type_none
;
62 fb
->attachments
[2].purpose
= k_framebuffer_attachment_type_none
;
63 fb
->attachments
[3].purpose
= k_framebuffer_attachment_type_none
;
64 fb
->attachments
[4].purpose
= k_framebuffer_attachment_type_none
;
66 render_fb_allocate( fb
);
69 vg_release_thread_sync();
72 VG_STATIC
void world_link_lighting_ub( world_instance
*world
, GLuint shader
)
74 GLuint idx
= glGetUniformBlockIndex( shader
, "ub_world_lighting" );
75 glUniformBlockBinding( shader
, idx
, world
->ubo_bind_point
);
78 VG_STATIC
void world_bind_position_texture( world_instance
*world
,
79 GLuint shader
, GLuint location
,
82 render_fb_bind_texture( &world
->heightmap
, 0, slot
);
83 glUniform1i( location
, slot
);
86 VG_STATIC
void world_bind_light_array( world_instance
*world
,
87 GLuint shader
, GLuint location
,
90 glActiveTexture( GL_TEXTURE0
+ slot
);
91 glBindTexture( GL_TEXTURE_BUFFER
, world
->tex_light_entities
);
92 glUniform1i( location
, slot
);
95 VG_STATIC
void world_bind_light_index( world_instance
*world
,
96 GLuint shader
, GLuint location
,
99 glActiveTexture( GL_TEXTURE0
+ slot
);
100 glBindTexture( GL_TEXTURE_3D
, world
->tex_light_cubes
);
101 glUniform1i( location
, slot
);
104 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
);
110 VG_STATIC
void bind_terrain_noise(void)
112 vg_tex2d_bind( &tex_terrain_noise
, 0 );
115 typedef void (*func_bind_point
)( world_instance
*world
,
116 struct world_surface
*mat
);
118 VG_STATIC
void world_render_if( world_instance
*world
,
119 enum mdl_shader shader
,
120 enum geo_type geo_type
,
121 func_bind_point bind_point
)
124 for( int i
=0; i
<world
->surface_count
; i
++ )
126 struct world_surface
*mat
= &world
->surfaces
[i
];
128 if( mat
->info
.shader
== shader
)
132 if( geo_type
== k_geo_type_solid
)
135 sm
= &mat
->sm_no_collide
;
137 if( !sm
->indice_count
)
140 bind_point( world
, mat
);
141 mdl_draw_submesh( sm
);
147 void world_render_both_stages( world_instance
*world
,
148 enum mdl_shader shader
,
149 func_bind_point bind_point
)
151 mesh_bind( &world
->mesh_geo
);
152 world_render_if( world
, shader
, k_geo_type_solid
, bind_point
);
154 glDisable( GL_CULL_FACE
);
155 mesh_bind( &world
->mesh_no_collide
);
156 world_render_if( world
, shader
, k_geo_type_nonsolid
, bind_point
);
157 glEnable( GL_CULL_FACE
);
160 VG_STATIC
void bindpoint_diffuse_texture1( world_instance
*world
,
161 struct world_surface
*mat
)
163 glActiveTexture( GL_TEXTURE1
);
164 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
167 VG_STATIC
void render_world_vb( world_instance
*world
, camera
*cam
)
169 m4x3f identity_matrix
;
170 m4x3_identity( identity_matrix
);
172 shader_scene_vertex_blend_use();
173 shader_scene_vertex_blend_uTexGarbage(0);
174 shader_scene_vertex_blend_uTexGradients(1);
175 world_link_lighting_ub( world
, _shader_scene_vertex_blend
.id
);
176 world_bind_position_texture( world
, _shader_scene_vertex_blend
.id
,
177 _uniform_scene_vertex_blend_g_world_depth
, 2 );
178 world_bind_light_array( world
, _shader_scene_vertex_blend
.id
,
179 _uniform_scene_vertex_blend_uLightsArray
, 3 );
180 world_bind_light_index( world
, _shader_scene_vertex_blend
.id
,
181 _uniform_scene_vertex_blend_uLightsIndex
, 4 );
183 vg_tex2d_bind( &tex_terrain_noise
, 0 );
185 shader_scene_vertex_blend_uPv( cam
->mtx
.pv
);
186 shader_scene_vertex_blend_uPvmPrev( cam
->mtx_prev
.pv
);
187 shader_scene_vertex_blend_uMdl( identity_matrix
);
188 shader_scene_vertex_blend_uCamera( cam
->transform
[3] );
189 shader_scene_vertex_blend_uBoard0( TEMP_BOARD_0
);
190 shader_scene_vertex_blend_uBoard1( TEMP_BOARD_1
);
192 world_render_both_stages( world
, k_shader_standard_vertex_blend
,
193 bindpoint_diffuse_texture1
);
196 VG_STATIC
void render_world_standard( world_instance
*world
, camera
*cam
)
198 m4x3f identity_matrix
;
199 m4x3_identity( identity_matrix
);
201 shader_scene_standard_use();
202 shader_scene_standard_uTexGarbage(0);
203 shader_scene_standard_uTexMain(1);
204 shader_scene_standard_uPv( cam
->mtx
.pv
);
205 shader_scene_standard_uPvmPrev( cam
->mtx_prev
.pv
);
207 world_link_lighting_ub( world
, _shader_scene_standard
.id
);
208 world_bind_position_texture( world
, _shader_scene_standard
.id
,
209 _uniform_scene_standard_g_world_depth
, 2 );
210 world_bind_light_array( world
, _shader_scene_standard
.id
,
211 _uniform_scene_standard_uLightsArray
, 3 );
212 world_bind_light_index( world
, _shader_scene_standard
.id
,
213 _uniform_scene_standard_uLightsIndex
, 4 );
215 bind_terrain_noise();
217 shader_scene_standard_uMdl( identity_matrix
);
218 shader_scene_standard_uCamera( cam
->transform
[3] );
219 shader_scene_standard_uBoard0( TEMP_BOARD_0
);
220 shader_scene_standard_uBoard1( TEMP_BOARD_1
);
222 world_render_both_stages( world
, k_shader_standard
,
223 bindpoint_diffuse_texture1
);
226 VG_STATIC
void render_world_alphatest( world_instance
*world
, camera
*cam
)
228 m4x3f identity_matrix
;
229 m4x3_identity( identity_matrix
);
231 shader_scene_standard_alphatest_use();
232 shader_scene_standard_alphatest_uTexGarbage(0);
233 shader_scene_standard_alphatest_uTexMain(1);
234 shader_scene_standard_alphatest_uPv( cam
->mtx
.pv
);
235 shader_scene_standard_alphatest_uPvmPrev( cam
->mtx_prev
.pv
);
237 world_link_lighting_ub( world
, _shader_scene_standard_alphatest
.id
);
238 world_bind_position_texture( world
, _shader_scene_standard_alphatest
.id
,
239 _uniform_scene_standard_alphatest_g_world_depth
, 2 );
240 world_bind_light_array( world
, _shader_scene_standard_alphatest
.id
,
241 _uniform_scene_standard_alphatest_uLightsArray
, 3 );
242 world_bind_light_index( world
, _shader_scene_standard_alphatest
.id
,
243 _uniform_scene_standard_alphatest_uLightsIndex
, 4 );
246 bind_terrain_noise();
248 shader_scene_standard_alphatest_uMdl( identity_matrix
);
249 shader_scene_standard_alphatest_uCamera( cam
->transform
[3] );
250 shader_scene_standard_alphatest_uBoard0( TEMP_BOARD_0
);
251 shader_scene_standard_alphatest_uBoard1( TEMP_BOARD_1
);
253 glDisable(GL_CULL_FACE
);
255 world_render_both_stages( world
, k_shader_standard_cutout
,
256 bindpoint_diffuse_texture1
);
258 glEnable(GL_CULL_FACE
);
261 VG_STATIC
void bindpoint_terrain( world_instance
*world
,
262 struct world_surface
*mat
)
264 glActiveTexture( GL_TEXTURE1
);
265 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
267 shader_scene_terrain_uSandColour( mat
->info
.colour
);
268 shader_scene_terrain_uBlendOffset( mat
->info
.colour1
);
271 VG_STATIC
void render_terrain( world_instance
*world
, camera
*cam
)
273 m4x3f identity_matrix
;
274 m4x3_identity( identity_matrix
);
276 shader_scene_terrain_use();
277 shader_scene_terrain_uTexGarbage(0);
278 shader_scene_terrain_uTexGradients(1);
280 world_link_lighting_ub( world
, _shader_scene_terrain
.id
);
281 world_bind_position_texture( world
, _shader_scene_terrain
.id
,
282 _uniform_scene_terrain_g_world_depth
, 2 );
283 world_bind_light_array( world
, _shader_scene_terrain
.id
,
284 _uniform_scene_terrain_uLightsArray
, 3 );
285 world_bind_light_index( world
, _shader_scene_terrain
.id
,
286 _uniform_scene_terrain_uLightsIndex
, 4 );
288 vg_tex2d_bind( &tex_terrain_noise
, 0 );
290 shader_scene_terrain_uPv( cam
->mtx
.pv
);
291 shader_scene_terrain_uPvmPrev( cam
->mtx_prev
.pv
);
293 shader_scene_terrain_uMdl( identity_matrix
);
294 shader_scene_terrain_uCamera( cam
->transform
[3] );
295 shader_scene_terrain_uBoard0( TEMP_BOARD_0
);
296 shader_scene_terrain_uBoard1( TEMP_BOARD_1
);
298 world_render_both_stages( world
, k_shader_terrain_blend
, bindpoint_terrain
);
301 VG_STATIC
void render_sky( world_instance
*world
, camera
*cam
)
304 * Modify matrix to remove clipping and view translation
311 m4x4_copy( cam
->mtx
.v
, v
);
312 m4x4_copy( cam
->mtx_prev
.v
, v_prev
);
314 v3_zero( v_prev
[3] );
316 m4x4_copy( cam
->mtx
.p
, pv
);
317 m4x4_copy( cam
->mtx_prev
.p
, pv_prev
);
318 m4x4_reset_clipping( pv
, cam
->farz
, cam
->nearz
);
319 m4x4_reset_clipping( pv_prev
, cam
->farz
, cam
->nearz
);
321 m4x4_mul( pv
, v
, pv
);
322 m4x4_mul( pv_prev
, v_prev
, pv_prev
);
324 m4x3f identity_matrix
;
325 m4x3_identity( identity_matrix
);
330 shader_model_sky_use();
331 shader_model_sky_uMdl( identity_matrix
);
332 shader_model_sky_uPv( pv
);
333 shader_model_sky_uPvmPrev( pv_prev
);
334 shader_model_sky_uTexGarbage(0);
335 world_link_lighting_ub( world
, _shader_model_sky
.id
);
337 vg_tex2d_bind( &tex_terrain_noise
, 0 );
339 glDepthMask( GL_FALSE
);
340 glDisable( GL_DEPTH_TEST
);
342 mesh_bind( &world_global
.skydome
);
343 mesh_draw( &world_global
.skydome
);
345 glEnable( GL_DEPTH_TEST
);
346 glDepthMask( GL_TRUE
);
349 VG_STATIC
void render_world_gates( world_instance
*world
, camera
*cam
,
352 float closest
= INFINITY
;
354 struct ent_gate
*gate
= NULL
;
356 for( u32 i
=0; i
<mdl_arrcount(&world
->ent_gate
); i
++ ){
357 ent_gate
*gi
= mdl_arritm( &world
->ent_gate
, i
);
359 if( gi
->type
== k_gate_type_unlinked
)
362 float dist
= v3_dist2( gi
->co
[0], cam
->transform
[3] );
364 vg_line_pt3( gi
->co
[0], 0.25f
, VG__BLUE
);
366 if( dist
< closest
){
374 world_instance
*dest_world
= &world_global
.worlds
[ gate
->world_index
];
375 render_gate( dest_world
, gate
, cam
, layer_depth
);
377 render_gate( world
, gate
, cam
, layer_depth
);
380 /* should really be set in fixed update since its used in the physics
381 * of most systems. too bad! */
382 world
->rendering_gate
= gate
;
386 VG_STATIC
void render_world( world_instance
*world
, camera
*cam
,
389 render_sky( world
, cam
);
391 render_world_routes( world
, cam
, layer_depth
);
392 render_world_standard( world
, cam
);
393 render_world_vb( world
, cam
);
394 render_world_alphatest( world
, cam
);
395 render_terrain( world
, cam
);
399 float min_dist
= INFINITY
;
401 if( !mdl_arrcount( &world
->ent_route
) )
404 for( u32 i
=0; i
<mdl_arrcount( &world
->ent_route
); i
++ ){
405 ent_route
*route
= mdl_arritm( &world
->ent_route
, i
);
406 float dist
= v3_dist2( route
->board_transform
[3], cam
->pos
);
408 if( dist
< min_dist
){
414 ent_route
*route
= mdl_arritm( &world
->ent_route
, closest
);
415 sfd_render( world
, cam
, route
->board_transform
);
418 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
)
420 m4x3f identity_matrix
;
421 m4x3_identity( identity_matrix
);
423 shader_scene_depth_use();
424 shader_scene_depth_uCamera( cam
->transform
[3] );
425 shader_scene_depth_uPv( cam
->mtx
.pv
);
426 shader_scene_depth_uPvmPrev( cam
->mtx_prev
.pv
);
427 shader_scene_depth_uMdl( identity_matrix
);
428 world_link_lighting_ub( world
, _shader_scene_depth
.id
);
430 mesh_bind( &world
->mesh_geo
);
431 mesh_draw( &world
->mesh_geo
);
434 VG_STATIC
void render_world_position( world_instance
*world
, camera
*cam
)
436 m4x3f identity_matrix
;
437 m4x3_identity( identity_matrix
);
439 shader_scene_position_use();
440 shader_scene_position_uCamera( cam
->transform
[3] );
441 shader_scene_position_uPv( cam
->mtx
.pv
);
442 shader_scene_position_uPvmPrev( cam
->mtx_prev
.pv
);
443 shader_scene_position_uMdl( identity_matrix
);
444 world_link_lighting_ub( world
, _shader_scene_position
.id
);
446 mesh_bind( &world
->mesh_geo
);
447 mesh_draw( &world
->mesh_geo
);
450 #endif /* WORLD_RENDER_H */