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_R16F
;
57 fb
->attachments
[0].format
= GL_RED
;
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
,
73 GLuint shader
, int texture_id
)
75 GLuint idx
= glGetUniformBlockIndex( shader
, "ub_world_lighting" );
76 glUniformBlockBinding( shader
, idx
, world
->ubo_bind_point
);
78 render_fb_bind_texture( &world
->heightmap
, 0, texture_id
);
79 glUniform1i( glGetUniformLocation( shader
, "g_world_depth" ), texture_id
);
82 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
);
88 VG_STATIC
void bind_terrain_noise(void)
90 vg_tex2d_bind( &tex_terrain_noise
, 0 );
93 typedef void (*func_bind_point
)( world_instance
*world
,
94 struct world_material
*mat
);
96 VG_STATIC
void world_render_if( world_instance
*world
,
97 enum mdl_shader shader
,
98 enum geo_type geo_type
,
99 func_bind_point bind_point
)
102 for( int i
=0; i
<world
->material_count
; i
++ )
104 struct world_material
*mat
= &world
->materials
[i
];
106 if( mat
->info
.shader
== shader
)
110 if( geo_type
== k_geo_type_solid
)
113 sm
= &mat
->sm_no_collide
;
115 if( !sm
->indice_count
)
118 bind_point( world
, mat
);
119 mdl_draw_submesh( sm
);
125 void world_render_both_stages( world_instance
*world
,
126 enum mdl_shader shader
,
127 func_bind_point bind_point
)
129 mesh_bind( &world
->mesh_geo
);
130 world_render_if( world
, shader
, k_geo_type_solid
, bind_point
);
132 glDisable( GL_CULL_FACE
);
133 mesh_bind( &world
->mesh_no_collide
);
134 world_render_if( world
, shader
, k_geo_type_nonsolid
, bind_point
);
135 glEnable( GL_CULL_FACE
);
138 VG_STATIC
void bindpoint_diffuse_texture1( world_instance
*world
,
139 struct world_material
*mat
)
141 glActiveTexture( GL_TEXTURE1
);
142 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
145 VG_STATIC
void render_world_vb( world_instance
*world
, camera
*cam
)
147 m4x3f identity_matrix
;
148 m4x3_identity( identity_matrix
);
150 shader_scene_vertex_blend_use();
151 shader_scene_vertex_blend_uTexGarbage(0);
152 shader_scene_vertex_blend_uTexGradients(1);
153 world_link_lighting_ub( world
, _shader_scene_vertex_blend
.id
, 2 );
154 vg_tex2d_bind( &tex_terrain_noise
, 0 );
156 shader_scene_vertex_blend_uPv( cam
->mtx
.pv
);
157 shader_scene_vertex_blend_uPvmPrev( cam
->mtx_prev
.pv
);
158 shader_scene_vertex_blend_uMdl( identity_matrix
);
159 shader_scene_vertex_blend_uCamera( cam
->transform
[3] );
160 shader_scene_vertex_blend_uBoard0( TEMP_BOARD_0
);
161 shader_scene_vertex_blend_uBoard1( TEMP_BOARD_1
);
163 world_render_both_stages( world
, k_shader_standard_vertex_blend
,
164 bindpoint_diffuse_texture1
);
167 VG_STATIC
void render_world_standard( world_instance
*world
, camera
*cam
)
169 m4x3f identity_matrix
;
170 m4x3_identity( identity_matrix
);
172 shader_scene_standard_use();
173 shader_scene_standard_uTexGarbage(0);
174 shader_scene_standard_uTexMain(1);
175 shader_scene_standard_uPv( cam
->mtx
.pv
);
176 shader_scene_standard_uPvmPrev( cam
->mtx_prev
.pv
);
177 world_link_lighting_ub( world
, _shader_scene_standard
.id
, 2 );
178 bind_terrain_noise();
180 shader_scene_standard_uMdl( identity_matrix
);
181 shader_scene_standard_uCamera( cam
->transform
[3] );
182 shader_scene_standard_uBoard0( TEMP_BOARD_0
);
183 shader_scene_standard_uBoard1( TEMP_BOARD_1
);
185 world_render_both_stages( world
, k_shader_standard
,
186 bindpoint_diffuse_texture1
);
189 VG_STATIC
void render_world_alphatest( world_instance
*world
, camera
*cam
)
191 m4x3f identity_matrix
;
192 m4x3_identity( identity_matrix
);
194 shader_scene_standard_alphatest_use();
195 shader_scene_standard_alphatest_uTexGarbage(0);
196 shader_scene_standard_alphatest_uTexMain(1);
197 shader_scene_standard_alphatest_uPv( cam
->mtx
.pv
);
198 shader_scene_standard_alphatest_uPvmPrev( cam
->mtx_prev
.pv
);
199 world_link_lighting_ub( world
, _shader_scene_standard_alphatest
.id
, 2 );
200 bind_terrain_noise();
202 shader_scene_standard_alphatest_uMdl( identity_matrix
);
203 shader_scene_standard_alphatest_uCamera( cam
->transform
[3] );
204 shader_scene_standard_alphatest_uBoard0( TEMP_BOARD_0
);
205 shader_scene_standard_alphatest_uBoard1( TEMP_BOARD_1
);
207 glDisable(GL_CULL_FACE
);
209 world_render_both_stages( world
, k_shader_standard_cutout
,
210 bindpoint_diffuse_texture1
);
212 glEnable(GL_CULL_FACE
);
215 VG_STATIC
void bindpoint_terrain( world_instance
*world
,
216 struct world_material
*mat
)
218 glActiveTexture( GL_TEXTURE1
);
219 glBindTexture( GL_TEXTURE_2D
, world
->textures
[ mat
->info
.tex_diffuse
] );
221 shader_scene_terrain_uSandColour( mat
->info
.colour
);
222 shader_scene_terrain_uBlendOffset( mat
->info
.colour1
);
225 VG_STATIC
void render_terrain( world_instance
*world
, camera
*cam
)
227 m4x3f identity_matrix
;
228 m4x3_identity( identity_matrix
);
230 shader_scene_terrain_use();
231 shader_scene_terrain_uTexGarbage(0);
232 shader_scene_terrain_uTexGradients(1);
233 world_link_lighting_ub( world
, _shader_scene_terrain
.id
, 2 );
235 vg_tex2d_bind( &tex_terrain_noise
, 0 );
237 shader_scene_terrain_uPv( cam
->mtx
.pv
);
238 shader_scene_terrain_uPvmPrev( cam
->mtx_prev
.pv
);
240 shader_scene_terrain_uMdl( identity_matrix
);
241 shader_scene_terrain_uCamera( cam
->transform
[3] );
242 shader_scene_terrain_uBoard0( TEMP_BOARD_0
);
243 shader_scene_terrain_uBoard1( TEMP_BOARD_1
);
245 world_render_both_stages( world
, k_shader_terrain_blend
, bindpoint_terrain
);
248 VG_STATIC
void render_sky( camera
*cam
)
251 * Modify matrix to remove clipping and view translation
258 m4x4_copy( cam
->mtx
.v
, v
);
259 m4x4_copy( cam
->mtx_prev
.v
, v_prev
);
261 v3_zero( v_prev
[3] );
263 m4x4_copy( cam
->mtx
.p
, pv
);
264 m4x4_copy( cam
->mtx_prev
.p
, pv_prev
);
265 m4x4_reset_clipping( pv
, cam
->farz
, cam
->nearz
);
266 m4x4_reset_clipping( pv_prev
, cam
->farz
, cam
->nearz
);
268 m4x4_mul( pv
, v
, pv
);
269 m4x4_mul( pv_prev
, v_prev
, pv_prev
);
271 m4x3f identity_matrix
;
272 m4x3_identity( identity_matrix
);
277 shader_model_sky_use();
278 shader_model_sky_uMdl( identity_matrix
);
279 shader_model_sky_uPv( pv
);
280 shader_model_sky_uPvmPrev( pv_prev
);
281 shader_model_sky_uTexGarbage(0);
282 shader_model_sky_uTime( world_global
.sky_time
);
284 vg_tex2d_bind( &tex_terrain_noise
, 0 );
286 glDepthMask( GL_FALSE
);
287 glDisable( GL_DEPTH_TEST
);
289 mesh_bind( &world_global
.skydome
);
290 mdl_draw_submesh( &world_global
.dome_upper
);
292 glEnable( GL_DEPTH_TEST
);
293 glDepthMask( GL_TRUE
);
296 VG_STATIC
void render_world_gates( world_instance
*world
, camera
*cam
)
298 if( !world
->gate_count
)
301 float closest
= INFINITY
;
304 for( int i
=0; i
<world
->gate_count
; i
++ )
306 struct route_gate
*rg
= &world
->gates
[i
];
307 float dist
= v3_dist2( rg
->gate
.co
[0], cam
->transform
[3] );
316 /* TODO: non-local portals! :D */
317 render_gate( world
, &world
->gates
[id
].gate
, cam
);
320 VG_STATIC
void render_world( world_instance
*world
, camera
*cam
)
324 render_world_routes( world
, cam
);
325 render_world_standard( world
, cam
);
326 render_world_vb( world
, cam
);
327 render_world_alphatest( world
, cam
);
328 render_terrain( world
, cam
);
332 float min_dist
= INFINITY
;
334 if( !world
->route_count
)
337 for( int i
=0; i
<world
->route_count
; i
++ )
339 float dist
= v3_dist2(world
->routes
[i
].scoreboard_transform
[3], cam
->pos
);
341 if( dist
< min_dist
)
348 sfd_render( cam
, world
->routes
[closest
].scoreboard_transform
);
351 VG_STATIC
void render_world_depth( world_instance
*world
, camera
*cam
)
353 m4x3f identity_matrix
;
354 m4x3_identity( identity_matrix
);
356 shader_scene_depth_use();
357 shader_scene_depth_uCamera( cam
->transform
[3] );
358 shader_scene_depth_uPv( cam
->mtx
.pv
);
359 shader_scene_depth_uPvmPrev( cam
->mtx_prev
.pv
);
360 shader_scene_depth_uMdl( identity_matrix
);
362 mesh_bind( &world
->mesh_geo
);
363 mesh_draw( &world
->mesh_geo
);
366 glDisable(GL_CULL_FACE
);
367 scene_bind( &world
.foliage
);
368 scene_draw( &world
.foliage
);
369 glEnable(GL_CULL_FACE
);
373 #endif /* WORLD_RENDER_H */