3 static int ray_world( v3f pos
, v3f dir
, ray_hit
*hit
);
12 #include "rigidbody.h"
18 #include "shaders/terrain.h"
19 #include "shaders/sky.h"
20 #include "shaders/planeinf.h"
21 #include "shaders/standard.h"
22 #include "shaders/vblend.h"
23 #include "shaders/gpos.h"
24 #include "shaders/fscolour.h"
38 teleport_gate gates
[64];
42 rigidbody temp_rbs
[128];
46 /* Rendering & geometry */
47 scene geo
, foliage
, props
;
48 mdl_submesh sm_surface
;
50 glmesh skybox
, skydome
;
51 mdl_submesh dome_upper
, dome_lower
;
55 vg_tex2d tex_terrain_colours
= { .path
= "textures/gradients.qoi",
56 .flags
= VG_TEXTURE_CLAMP
|VG_TEXTURE_NEAREST
};
58 vg_tex2d tex_terrain_noise
= { .path
= "textures/garbage.qoi",
59 .flags
= VG_TEXTURE_NEAREST
};
61 static void ray_world_get_tri( ray_hit
*hit
, v3f tri
[3] )
63 for( int i
=0; i
<3; i
++ )
64 v3_copy( world
.geo
.verts
[ hit
->tri
[i
] ].co
, tri
[i
] );
67 static int ray_world( v3f pos
, v3f dir
, ray_hit
*hit
)
69 return scene_raycast( &world
.geo
, pos
, dir
, hit
);
72 static int ray_hit_is_ramp( ray_hit
*hit
)
74 return hit
->tri
[0] < world
.sm_surface
.vertex_count
;
77 static void world_register(void)
79 shader_terrain_register();
80 shader_sky_register();
81 shader_planeinf_register();
82 shader_gpos_register();
83 shader_fscolour_register();
86 static void world_free(void)
91 static void render_world_depth( m4x4f projection
, m4x3f camera
);
93 static void add_all_if_material( scene
*pscene
, mdl_header
*mdl
, u32 id
)
95 for( int i
=0; i
<mdl
->node_count
; i
++ )
97 mdl_node
*pnode
= mdl_node_from_id( mdl
, i
);
99 for( int j
=0; j
<pnode
->submesh_count
; j
++ )
101 mdl_submesh
*sm
= mdl_node_submesh( mdl
, pnode
, j
);
103 if( sm
->material_id
== id
)
106 mdl_node_transform( pnode
, transform
);
107 scene_add_submesh( pscene
, mdl
, sm
, transform
);
113 static void world_apply_foliage(void)
115 scene_init( &world
.foliage
);
116 mdl_header
*mfoliage
= mdl_load("models/rs_foliage.mdl");
119 v3_sub( world
.geo
.bbx
[1], world
.geo
.bbx
[0], volume
);
123 mdl_node
*mblob
= mdl_node_from_name( mfoliage
, "blob" );
124 mdl_submesh
*sm_blob
= mdl_node_submesh( mfoliage
, mblob
, 0 );
126 for( int i
=0;i
<100000;i
++ )
129 v3_mul( volume
, (v3f
){ vg_randf(), 1000.0f
, vg_randf() }, pos
);
131 v3_add( pos
, world
.geo
.bbx
[0], pos
);
136 if( ray_world( pos
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
138 if( hit
.normal
[1] > 0.8f
&& !ray_hit_is_ramp(&hit
) &&
139 hit
.pos
[1] > water_height()+10.0f
)
141 v4f qsurface
, qrandom
;
144 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, hit
.normal
, axis
);
146 float angle
= v3_dot(hit
.normal
,(v3f
){0.0f
,1.0f
,0.0f
});
147 q_axis_angle( qsurface
, axis
, angle
);
148 q_axis_angle( qrandom
, (v3f
){0.0f
,1.0f
,0.0f
}, vg_randf()*VG_TAUf
);
149 q_mul( qsurface
, qrandom
, qsurface
);
150 q_m3x3( qsurface
, transform
);
152 v3_copy( hit
.pos
, transform
[3] );
153 scene_add_submesh( &world
.foliage
, mfoliage
, sm_blob
, transform
);
158 scene_upload( &world
.foliage
);
162 static void world_load(void)
164 mdl_header
*mworld
= mdl_load( "models/mp_dev.mdl" );
166 world
.spawn_count
= 0;
167 world
.gate_count
= 0;
170 scene_init( &world
.geo
);
171 scene_init( &world
.props
);
174 * Compile meshes into the world scenes
178 mat_vertex_blend
= 0;
180 for( int i
=1; i
<mworld
->material_count
; i
++ )
182 mdl_material
*mat
= mdl_material_from_id( mworld
, i
);
183 const char *mat_name
= mdl_pstr( mworld
, mat
->pstr_name
);
185 vg_info( "%d %s\n", mat
->pstr_name
, mat_name
);
187 if( !strcmp( "surf", mat_name
))
189 else if( !strcmp( "surf_oob", mat_name
))
191 else if( !strcmp( "vertex_blend", mat_name
))
192 mat_vertex_blend
= i
;
196 add_all_if_material( &world
.geo
, mworld
, mat_surf
);
198 scene_copy_slice( &world
.geo
, &world
.sm_surface
);
201 add_all_if_material( &world
.geo
, mworld
, mat_surf_oob
);
203 vg_warn( "No OOB surface\n" );
205 scene_bh_create( &world
.geo
);
206 scene_upload( &world
.geo
);
208 if( mat_vertex_blend
)
209 add_all_if_material( &world
.props
, mworld
, mat_vertex_blend
);
216 for( int i
=0; i
<mworld
->node_count
; i
++ )
218 mdl_node
*pnode
= mdl_node_from_id( mworld
, i
);
220 if( pnode
->classtype
== k_classtype_none
)
222 else if( pnode
->classtype
== k_classtype_gate
)
224 struct classtype_gate
*entgate
= mdl_get_entdata( mworld
, pnode
);
225 mdl_node
*pother
= mdl_node_from_id( mworld
, entgate
->target
);
227 teleport_gate
*gate
= &world
.gates
[ world
.gate_count
++ ];
229 v3_copy( pnode
->co
, gate
->co
[0] );
230 v3_copy( pother
->co
, gate
->co
[1] );
231 v4_copy( pnode
->q
, gate
->q
[0] );
232 v4_copy( pother
->q
, gate
->q
[1] );
233 v2_copy( pnode
->s
, gate
->dims
);
235 gate_transform_update( gate
);
237 else if( pnode
->classtype
== k_classtype_block
)
239 struct classtype_block
*block
= mdl_get_entdata( mworld
, pnode
);
242 mdl_node_transform( pnode
, transform
);
244 rigidbody
*rb
= &world
.temp_rbs
[ world
.rb_count
++ ];
246 box_copy( block
->bbx
, rb
->bbx
); /* TODO: apply scale */
247 v3_copy( pnode
->co
, rb
->co
);
249 v4_copy( pnode
->q
, rb
->q
);
250 rb_update_transform( rb
);
252 else if( pnode
->classtype
== k_classtype_spawn
)
254 struct respawn_point
*rp
= &world
.spawns
[ world
.spawn_count
++ ];
256 v3_copy( pnode
->co
, rp
->co
);
257 v4_copy( pnode
->q
, rp
->q
);
258 strcpy( rp
->name
, mdl_pstr( mworld
, pnode
->pstr_name
) );
260 else if( pnode
->classtype
== k_classtype_water
)
262 if( wrender
.enabled
)
264 vg_warn( "Multiple water surfaces in level! ('%s')\n",
265 mdl_pstr( mworld
, pnode
->pstr_name
));
269 mdl_submesh
*sm
= mdl_node_submesh( mworld
, pnode
, 0 );
274 mdl_unpack_submesh( mworld
, &surf
, sm
);
276 water_set_surface( &surf
, pnode
->co
[1] );
281 scene_upload( &world
.props
);
283 bh_create( &world
.bhcubes
,
284 &bh_system_rigidbodies
, world
.temp_rbs
, world
.rb_count
);
286 world_apply_foliage();
290 * Rendering the depth map
296 v3_sub( world
.geo
.bbx
[1], world
.geo
.bbx
[0], extent
);
298 float fl
= world
.geo
.bbx
[0][0],
299 fr
= world
.geo
.bbx
[1][0],
300 fb
= world
.geo
.bbx
[0][2],
301 ft
= world
.geo
.bbx
[1][2],
306 ortho
[0][0] = 2.0f
* rl
;
307 ortho
[2][1] = 2.0f
* tb
;
308 ortho
[3][0] = (fr
+ fl
) * -rl
;
309 ortho
[3][1] = (ft
+ fb
) * -tb
;
311 m4x3_identity( camera
);
313 glViewport( 0, 0, 1024, 1024 );
314 glDisable(GL_DEPTH_TEST
);
315 glBindFramebuffer( GL_FRAMEBUFFER
, gpipeline
.fb_depthmap
);
316 shader_fscolour_use();
317 shader_fscolour_uColour( (v4f
){-9999.0f
,-9999.0f
,-9999.0f
,-9999.0f
} );
321 glBlendFunc(GL_ONE
, GL_ONE
);
322 glBlendEquation(GL_MAX
);
323 render_world_depth( ortho
, camera
);
325 glEnable(GL_DEPTH_TEST
);
328 * TODO: World settings entity
330 struct ub_world_lighting
*winfo
= &gpipeline
.ub_world_lighting
;
331 v4_copy( wrender
.plane
, winfo
->g_water_plane
);
334 bounds
[0] = world
.geo
.bbx
[0][0];
335 bounds
[1] = world
.geo
.bbx
[0][2];
336 bounds
[2] = 1.0f
/ (world
.geo
.bbx
[1][0]-world
.geo
.bbx
[0][0]);
337 bounds
[3] = 1.0f
/ (world
.geo
.bbx
[1][2]-world
.geo
.bbx
[0][2]);
338 v4_copy( bounds
, winfo
->g_depth_bounds
);
340 winfo
->g_water_fog
= 0.04f
;
341 render_update_lighting_ub();
344 static void world_init(void)
346 vg_tex2d_init( (vg_tex2d
*[]){ &tex_terrain_colours
,
347 &tex_terrain_noise
}, 2 );
350 mdl_header
*msky
= mdl_load("models/rs_skydome.mdl");
351 mdl_unpack_glmesh( msky
, &world
.skydome
);
353 mdl_node
*nlower
= mdl_node_from_name( msky
, "dome_lower" ),
354 *nupper
= mdl_node_from_name( msky
, "dome_upper" );
356 world
.dome_lower
= *mdl_node_submesh( msky
, nlower
, 0 );
357 world
.dome_upper
= *mdl_node_submesh( msky
, nupper
, 0 );
365 static void bind_terrain_textures(void)
367 vg_tex2d_bind( &tex_terrain_noise
, 0 );
368 vg_tex2d_bind( &tex_terrain_colours
, 1 );
371 static void render_props( m4x4f projection
, v3f camera
)
373 m4x3f identity_matrix
;
374 m4x3_identity( identity_matrix
);
377 shader_vblend_uTexGarbage(0);
378 shader_vblend_uTexGradients(1);
379 shader_link_standard_ub( _shader_vblend
.id
, 2 );
380 bind_terrain_textures();
382 shader_vblend_uPv( projection
);
383 shader_vblend_uMdl( identity_matrix
);
384 shader_vblend_uCamera( camera
);
386 scene_bind( &world
.props
);
387 scene_draw( &world
.props
);
390 static void render_terrain( m4x4f projection
, v3f camera
)
392 m4x3f identity_matrix
;
393 m4x3_identity( identity_matrix
);
395 shader_terrain_use();
396 shader_terrain_uTexGarbage(0);
397 shader_terrain_uTexGradients(1);
398 shader_link_standard_ub( _shader_terrain
.id
, 2 );
399 bind_terrain_textures();
401 shader_terrain_uPv( projection
);
402 shader_terrain_uMdl( identity_matrix
);
403 shader_terrain_uCamera( camera
);
405 scene_bind( &world
.geo
);
406 scene_draw( &world
.geo
);
408 glDisable(GL_CULL_FACE
);
409 scene_bind( &world
.foliage
);
410 scene_draw( &world
.foliage
);
411 glEnable(GL_CULL_FACE
);
414 static void render_lowerdome( m4x3f camera
)
416 m4x4f projection
, full
;
417 pipeline_projection( projection
, 0.4f
, 1000.0f
);
420 m3x3_transpose( camera
, inverse
);
421 v3_copy((v3f
){0.0f
,0.0f
,0.0f
}, inverse
[3]);
422 m4x3_expand( inverse
, full
);
423 m4x4_mul( projection
, full
, full
);
425 m4x3f identity_matrix
;
426 m4x3_identity( identity_matrix
);
428 shader_planeinf_use();
429 shader_planeinf_uMdl(identity_matrix
);
430 shader_planeinf_uPv(full
);
431 shader_planeinf_uCamera(camera
[3]);
432 shader_planeinf_uPlane( (v4f
){0.0f
,1.0f
,0.0f
, water_height()} );
434 mdl_draw_submesh( &world
.dome_lower
);
437 static void render_sky(m4x3f camera
)
439 m4x4f projection
, full
;
440 pipeline_projection( projection
, 0.4f
, 1000.0f
);
443 m3x3_transpose( camera
, inverse
);
444 v3_copy((v3f
){0.0f
,0.0f
,0.0f
}, inverse
[3]);
445 m4x3_expand( inverse
, full
);
446 m4x4_mul( projection
, full
, full
);
448 m4x3f identity_matrix
;
449 m4x3_identity( identity_matrix
);
452 shader_sky_uMdl(identity_matrix
);
453 shader_sky_uPv(full
);
454 shader_sky_uTexGarbage(0);
455 shader_sky_uTime( vg_time
);
457 vg_tex2d_bind( &tex_terrain_noise
, 0 );
459 glDepthMask( GL_FALSE
);
460 glDisable( GL_DEPTH_TEST
);
462 mesh_bind( &world
.skydome
);
463 mdl_draw_submesh( &world
.dome_upper
);
465 glEnable( GL_DEPTH_TEST
);
466 glDepthMask( GL_TRUE
);
469 static void render_world( m4x4f projection
, m4x3f camera
)
471 render_sky( camera
);
472 render_props( projection
, camera
[3] );
473 render_terrain( projection
, camera
[3] );
476 static void render_world_depth( m4x4f projection
, m4x3f camera
)
478 m4x3f identity_matrix
;
479 m4x3_identity( identity_matrix
);
482 shader_gpos_uCamera( camera
[3] );
483 shader_gpos_uPv( projection
);
484 shader_gpos_uMdl( identity_matrix
);
486 scene_bind( &world
.geo
);
487 scene_draw( &world
.geo
);
490 glDisable(GL_CULL_FACE
);
491 scene_bind( &world
.foliage
);
492 scene_draw( &world
.foliage
);
493 glEnable(GL_CULL_FACE
);
496 scene_bind( &world
.props
);
497 scene_draw( &world
.props
);