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 fb
->attachments
[0].display_name
= NULL
;
52 fb
->attachments
[0].purpose
= k_framebuffer_attachment_type_colour
;
53 fb
->attachments
[0].internalformat
= GL_RG16F
;
54 fb
->attachments
[0].format
= GL_RG
;
55 fb
->attachments
[0].type
= GL_FLOAT
;
56 fb
->attachments
[0].attachment
= GL_COLOR_ATTACHMENT0
;
58 fb
->attachments
[1].purpose
= k_framebuffer_attachment_type_none
;
59 fb
->attachments
[2].purpose
= k_framebuffer_attachment_type_none
;
60 fb
->attachments
[3].purpose
= k_framebuffer_attachment_type_none
;
61 fb
->attachments
[4].purpose
= k_framebuffer_attachment_type_none
;
63 render_fb_allocate( fb
);
66 vg_release_thread_sync();
69 VG_STATIC
void world_link_lighting_ub( world_instance
*world
, GLuint shader
)
71 GLuint idx
= glGetUniformBlockIndex( shader
, "ub_world_lighting" );
72 glUniformBlockBinding( shader
, idx
, world
->ubo_bind_point
);
75 VG_STATIC
void world_bind_position_texture( world_instance
*world
,
76 GLuint shader
, GLuint location
,
79 render_fb_bind_texture( &world
->heightmap
, 0, slot
);
80 glUniform1i( location
, slot
);
83 VG_STATIC
void world_bind_light_array( world_instance
*world
,
84 GLuint shader
, GLuint location
,
87 glActiveTexture( GL_TEXTURE0
+ slot
);
88 glBindTexture( GL_TEXTURE_BUFFER
, world
->tex_light_entities
);
89 glUniform1i( location
, slot
);
92 VG_STATIC
void world_bind_light_index( world_instance
*world
,
93 GLuint shader
, GLuint location
,
96 glActiveTexture( GL_TEXTURE0
+ slot
);
97 glBindTexture( GL_TEXTURE_3D
, world
->tex_light_cubes
);
98 glUniform1i( location
, slot
);
101 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
);
107 VG_STATIC
void bind_terrain_noise(void)
109 vg_tex2d_bind( &tex_terrain_noise
, 0 );
112 typedef void (*func_bind_point
)( world_instance
*world
,
113 struct world_surface
*mat
);
115 VG_STATIC
void world_render_if( world_instance
*world
,
116 enum mdl_shader shader
,
117 enum geo_type geo_type
,
118 func_bind_point bind_point
)
121 for( int i
=0; i
<world
->surface_count
; i
++ )
123 struct world_surface
*mat
= &world
->surfaces
[i
];
125 if( mat
->info
.shader
== shader
)
129 if( geo_type
== k_geo_type_solid
)
132 sm
= &mat
->sm_no_collide
;
134 if( !sm
->indice_count
)
137 bind_point( world
, mat
);
138 mdl_draw_submesh( sm
);
144 void world_render_both_stages( world_instance
*world
,
145 enum mdl_shader shader
,
146 func_bind_point bind_point
)
148 mesh_bind( &world
->mesh_geo
);
149 world_render_if( world
, shader
, k_geo_type_solid
, bind_point
);
151 glDisable( GL_CULL_FACE
);
152 mesh_bind( &world
->mesh_no_collide
);
153 world_render_if( world
, shader
, k_geo_type_nonsolid
, bind_point
);
154 glEnable( GL_CULL_FACE
);
157 VG_STATIC
void bindpoint_diffuse_texture1( world_instance
*world
,
158 struct world_surface
*mat
)
160 glActiveTexture( GL_TEXTURE1
);
161 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
164 VG_STATIC
void render_world_vb( world_instance
*world
, camera
*cam
)
166 m4x3f identity_matrix
;
167 m4x3_identity( identity_matrix
);
169 shader_scene_vertex_blend_use();
170 shader_scene_vertex_blend_uTexGarbage(0);
171 shader_scene_vertex_blend_uTexGradients(1);
172 world_link_lighting_ub( world
, _shader_scene_vertex_blend
.id
);
173 world_bind_position_texture( world
, _shader_scene_vertex_blend
.id
,
174 _uniform_scene_vertex_blend_g_world_depth
, 2 );
175 world_bind_light_array( world
, _shader_scene_vertex_blend
.id
,
176 _uniform_scene_vertex_blend_uLightsArray
, 3 );
177 world_bind_light_index( world
, _shader_scene_vertex_blend
.id
,
178 _uniform_scene_vertex_blend_uLightsIndex
, 4 );
180 vg_tex2d_bind( &tex_terrain_noise
, 0 );
182 shader_scene_vertex_blend_uPv( cam
->mtx
.pv
);
183 shader_scene_vertex_blend_uPvmPrev( cam
->mtx_prev
.pv
);
184 shader_scene_vertex_blend_uMdl( identity_matrix
);
185 shader_scene_vertex_blend_uCamera( cam
->transform
[3] );
187 world_render_both_stages( world
, k_shader_standard_vertex_blend
,
188 bindpoint_diffuse_texture1
);
191 VG_STATIC
void render_world_standard( world_instance
*world
, camera
*cam
)
193 m4x3f identity_matrix
;
194 m4x3_identity( identity_matrix
);
196 shader_scene_standard_use();
197 shader_scene_standard_uTexGarbage(0);
198 shader_scene_standard_uTexMain(1);
199 shader_scene_standard_uPv( cam
->mtx
.pv
);
200 shader_scene_standard_uPvmPrev( cam
->mtx_prev
.pv
);
202 world_link_lighting_ub( world
, _shader_scene_standard
.id
);
203 world_bind_position_texture( world
, _shader_scene_standard
.id
,
204 _uniform_scene_standard_g_world_depth
, 2 );
205 world_bind_light_array( world
, _shader_scene_standard
.id
,
206 _uniform_scene_standard_uLightsArray
, 3 );
207 world_bind_light_index( world
, _shader_scene_standard
.id
,
208 _uniform_scene_standard_uLightsIndex
, 4 );
210 bind_terrain_noise();
212 shader_scene_standard_uMdl( identity_matrix
);
213 shader_scene_standard_uCamera( cam
->transform
[3] );
215 world_render_both_stages( world
, k_shader_standard
,
216 bindpoint_diffuse_texture1
);
219 VG_STATIC
void render_world_alphatest( world_instance
*world
, camera
*cam
)
221 m4x3f identity_matrix
;
222 m4x3_identity( identity_matrix
);
224 shader_scene_standard_alphatest_use();
225 shader_scene_standard_alphatest_uTexGarbage(0);
226 shader_scene_standard_alphatest_uTexMain(1);
227 shader_scene_standard_alphatest_uPv( cam
->mtx
.pv
);
228 shader_scene_standard_alphatest_uPvmPrev( cam
->mtx_prev
.pv
);
230 world_link_lighting_ub( world
, _shader_scene_standard_alphatest
.id
);
231 world_bind_position_texture( world
, _shader_scene_standard_alphatest
.id
,
232 _uniform_scene_standard_alphatest_g_world_depth
, 2 );
233 world_bind_light_array( world
, _shader_scene_standard_alphatest
.id
,
234 _uniform_scene_standard_alphatest_uLightsArray
, 3 );
235 world_bind_light_index( world
, _shader_scene_standard_alphatest
.id
,
236 _uniform_scene_standard_alphatest_uLightsIndex
, 4 );
239 bind_terrain_noise();
241 shader_scene_standard_alphatest_uMdl( identity_matrix
);
242 shader_scene_standard_alphatest_uCamera( cam
->transform
[3] );
244 glDisable(GL_CULL_FACE
);
246 world_render_both_stages( world
, k_shader_standard_cutout
,
247 bindpoint_diffuse_texture1
);
249 glEnable(GL_CULL_FACE
);
252 VG_STATIC
void bindpoint_terrain( world_instance
*world
,
253 struct world_surface
*mat
)
255 glActiveTexture( GL_TEXTURE1
);
256 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
258 shader_scene_terrain_uSandColour( mat
->info
.colour
);
259 shader_scene_terrain_uBlendOffset( mat
->info
.colour1
);
262 VG_STATIC
void render_terrain( world_instance
*world
, camera
*cam
)
264 m4x3f identity_matrix
;
265 m4x3_identity( identity_matrix
);
267 shader_scene_terrain_use();
268 shader_scene_terrain_uTexGarbage(0);
269 shader_scene_terrain_uTexGradients(1);
271 world_link_lighting_ub( world
, _shader_scene_terrain
.id
);
272 world_bind_position_texture( world
, _shader_scene_terrain
.id
,
273 _uniform_scene_terrain_g_world_depth
, 2 );
274 world_bind_light_array( world
, _shader_scene_terrain
.id
,
275 _uniform_scene_terrain_uLightsArray
, 3 );
276 world_bind_light_index( world
, _shader_scene_terrain
.id
,
277 _uniform_scene_terrain_uLightsIndex
, 4 );
279 vg_tex2d_bind( &tex_terrain_noise
, 0 );
281 shader_scene_terrain_uPv( cam
->mtx
.pv
);
282 shader_scene_terrain_uPvmPrev( cam
->mtx_prev
.pv
);
284 shader_scene_terrain_uMdl( identity_matrix
);
285 shader_scene_terrain_uCamera( cam
->transform
[3] );
287 world_render_both_stages( world
, k_shader_terrain_blend
, bindpoint_terrain
);
290 VG_STATIC
void render_sky( world_instance
*world
, camera
*cam
)
293 * Modify matrix to remove clipping and view translation
300 m4x4_copy( cam
->mtx
.v
, v
);
301 m4x4_copy( cam
->mtx_prev
.v
, v_prev
);
303 v3_zero( v_prev
[3] );
305 m4x4_copy( cam
->mtx
.p
, pv
);
306 m4x4_copy( cam
->mtx_prev
.p
, pv_prev
);
307 m4x4_reset_clipping( pv
, cam
->farz
, cam
->nearz
);
308 m4x4_reset_clipping( pv_prev
, cam
->farz
, cam
->nearz
);
310 m4x4_mul( pv
, v
, pv
);
311 m4x4_mul( pv_prev
, v_prev
, pv_prev
);
313 m4x3f identity_matrix
;
314 m4x3_identity( identity_matrix
);
319 shader_model_sky_use();
320 shader_model_sky_uMdl( identity_matrix
);
321 shader_model_sky_uPv( pv
);
322 shader_model_sky_uPvmPrev( pv_prev
);
323 shader_model_sky_uTexGarbage(0);
324 world_link_lighting_ub( world
, _shader_model_sky
.id
);
326 vg_tex2d_bind( &tex_terrain_noise
, 0 );
328 glDepthMask( GL_FALSE
);
329 glDisable( GL_DEPTH_TEST
);
331 mesh_bind( &world_global
.skydome
);
332 mesh_draw( &world_global
.skydome
);
334 glEnable( GL_DEPTH_TEST
);
335 glDepthMask( GL_TRUE
);
338 VG_STATIC
void render_world_gates( world_instance
*world
, camera
*cam
,
341 float closest
= INFINITY
;
343 struct ent_gate
*gate
= NULL
;
345 for( u32 i
=0; i
<mdl_arrcount(&world
->ent_gate
); i
++ ){
346 ent_gate
*gi
= mdl_arritm( &world
->ent_gate
, i
);
348 if( gi
->type
== k_gate_type_unlinked
)
351 float dist
= v3_dist2( gi
->co
[0], cam
->transform
[3] );
353 vg_line_pt3( gi
->co
[0], 0.25f
, VG__BLUE
);
355 if( dist
< closest
){
363 world_instance
*dest_world
= &world_global
.worlds
[ gate
->world_index
];
364 render_gate( dest_world
, gate
, cam
, layer_depth
);
366 render_gate( world
, gate
, cam
, layer_depth
);
369 /* should really be set in fixed update since its used in the physics
370 * of most systems. too bad! */
371 world
->rendering_gate
= gate
;
375 VG_STATIC
void world_prerender( world_instance
*world
)
377 static double g_time
= 0.0;
378 g_time
+= vg
.time_delta
* (1.0/(k_day_length
*60.0));
381 struct ub_world_lighting
*state
= &world
->ub_lighting
;
383 state
->g_time
= g_time
;
384 state
->g_realtime
= vg
.time
;
385 state
->g_debug_indices
= k_debug_light_indices
;
386 state
->g_light_preview
= k_light_preview
;
387 state
->g_debug_complexity
= k_debug_light_complexity
;
389 state
->g_time_of_day
= vg_fractf( g_time
);
390 state
->g_day_phase
= cosf( state
->g_time_of_day
* VG_PIf
* 2.0f
);
391 state
->g_sunset_phase
= cosf( state
->g_time_of_day
* VG_PIf
* 4.0f
+ VG_PIf
);
393 state
->g_day_phase
= state
->g_day_phase
* 0.5f
+ 0.5f
;
394 state
->g_sunset_phase
= powf( state
->g_sunset_phase
* 0.5f
+ 0.5f
, 6.0f
);
396 float a
= state
->g_time_of_day
* VG_PIf
* 2.0f
;
397 state
->g_sun_dir
[0] = sinf( a
);
398 state
->g_sun_dir
[1] = cosf( a
);
399 state
->g_sun_dir
[2] = 0.2f
;
400 v3_normalize( state
->g_sun_dir
);
403 world
->probabilities
[ k_probability_curve_constant
] = 1.0f
;
405 float dp
= state
->g_day_phase
;
407 world
->probabilities
[ k_probability_curve_wildlife_day
] =
408 (dp
*dp
*0.8f
+state
->g_sunset_phase
)*0.8f
;
409 world
->probabilities
[ k_probability_curve_wildlife_night
] =
410 1.0f
-powf(fabsf((state
->g_time_of_day
-0.5f
)*5.0f
),5.0f
);
413 glBindBuffer( GL_UNIFORM_BUFFER
, world
->ubo_lighting
);
414 glBufferSubData( GL_UNIFORM_BUFFER
, 0,
415 sizeof(struct ub_world_lighting
), &world
->ub_lighting
);
418 VG_STATIC
void render_world( world_instance
*world
, camera
*cam
,
421 render_sky( world
, cam
);
423 render_world_routes( world
, cam
, layer_depth
);
424 render_world_standard( world
, cam
);
425 render_world_vb( world
, cam
);
426 render_world_alphatest( world
, cam
);
427 render_terrain( world
, cam
);
431 float min_dist
= INFINITY
;
433 if( !mdl_arrcount( &world
->ent_route
) )
436 for( u32 i
=0; i
<mdl_arrcount( &world
->ent_route
); i
++ ){
437 ent_route
*route
= mdl_arritm( &world
->ent_route
, i
);
438 float dist
= v3_dist2( route
->board_transform
[3], cam
->pos
);
440 if( dist
< min_dist
){
446 ent_route
*route
= mdl_arritm( &world
->ent_route
, closest
);
447 sfd_render( world
, cam
, route
->board_transform
);
450 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
)
452 m4x3f identity_matrix
;
453 m4x3_identity( identity_matrix
);
455 shader_scene_depth_use();
456 shader_scene_depth_uCamera( cam
->transform
[3] );
457 shader_scene_depth_uPv( cam
->mtx
.pv
);
458 shader_scene_depth_uPvmPrev( cam
->mtx_prev
.pv
);
459 shader_scene_depth_uMdl( identity_matrix
);
460 world_link_lighting_ub( world
, _shader_scene_depth
.id
);
462 mesh_bind( &world
->mesh_geo
);
463 mesh_draw( &world
->mesh_geo
);
466 VG_STATIC
void render_world_position( world_instance
*world
, camera
*cam
)
468 m4x3f identity_matrix
;
469 m4x3_identity( identity_matrix
);
471 shader_scene_position_use();
472 shader_scene_position_uCamera( cam
->transform
[3] );
473 shader_scene_position_uPv( cam
->mtx
.pv
);
474 shader_scene_position_uPvmPrev( cam
->mtx_prev
.pv
);
475 shader_scene_position_uMdl( identity_matrix
);
476 world_link_lighting_ub( world
, _shader_scene_position
.id
);
478 mesh_bind( &world
->mesh_geo
);
479 mesh_draw( &world
->mesh_geo
);
482 #endif /* WORLD_RENDER_H */