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"
30 teleport_gate gates
[64];
34 rigidbody temp_rbs
[128];
38 /* Rendering & geometry */
39 scene geo
, foliage
, props
;
40 submodel sm_road
, sm_terrain
;
42 glmesh skybox
, skydome
;
48 vg_tex2d tex_terrain_colours
= { .path
= "textures/gradients.qoi",
49 .flags
= VG_TEXTURE_CLAMP
|VG_TEXTURE_NEAREST
};
51 vg_tex2d tex_terrain_noise
= { .path
= "textures/garbage.qoi",
52 .flags
= VG_TEXTURE_NEAREST
};
54 static void ray_world_get_tri( ray_hit
*hit
, v3f tri
[3] )
56 for( int i
=0; i
<3; i
++ )
57 v3_copy( world
.geo
.verts
[ hit
->tri
[i
] ].co
, tri
[i
] );
60 static int ray_world( v3f pos
, v3f dir
, ray_hit
*hit
)
62 return scene_raycast( &world
.geo
, pos
, dir
, hit
);
65 static int ray_hit_is_ramp( ray_hit
*hit
)
67 return hit
->tri
[0] < world
.sm_road
.vertex_count
;
70 static void world_register(void)
72 shader_terrain_register();
73 shader_sky_register();
74 shader_planeinf_register();
75 shader_gpos_register();
76 shader_fscolour_register();
79 static void world_free(void)
84 static void render_world_depth( m4x4f projection
, m4x3f camera
);
85 static void world_load(void)
90 * TODO: Call world_free when its ready here
93 scene_init( &world
.geo
);
94 model
*mworld
= vg_asset_read( "models/mp_dev.mdl" );
96 for( int i
=0; i
<mworld
->layer_count
; i
++ )
98 submodel
*sm
= model_get_submodel( mworld
, i
);
99 if( !strcmp( sm
->material
, "surf" ) )
100 scene_add_model( &world
.geo
, mworld
, sm
, sm
->pivot
, 0.0f
, 1.0f
);
103 for( int i
=0; i
<mworld
->layer_count
; i
++ )
105 submodel
*sm
= model_get_submodel( mworld
, i
);
106 if( !strcmp( sm
->material
, "vertex_blend" ) )
109 q_m3x3( sm
->q
, transform
);
110 v3_copy( sm
->pivot
, transform
[3] );
111 scene_add_foliage( &world
.geo
, mworld
, sm
, transform
);
114 scene_copy_slice( &world
.geo
, &world
.sm_road
);
116 for( int i
=0; i
<mworld
->layer_count
; i
++ )
118 submodel
*sm
= model_get_submodel( mworld
, i
);
119 if( !strcmp( sm
->material
, "terrain" ) )
120 scene_add_model( &world
.geo
, mworld
, sm
, sm
->pivot
, 0.0f
, 1.0f
);
124 scene_copy_slice( &world
.geo
, &world
.sm_terrain
);
127 * TODO: Parametric marker import
129 v3_copy( model_marker_get( mworld
, "start" )->co
, world
.tutorial
);
135 world
.gate_count
= 0;
136 for( int i
=0; i
<mworld
->marker_count
; i
++ )
138 model_marker
*ga
= model_get_marker( mworld
, i
);
140 if( ga
->classtype
== k_classtype_gate
)
142 struct classtype_gate
*data
= get_entdata_raw( mworld
, ga
);
146 model_marker
*gb
= model_get_marker( mworld
, data
->target
);
148 teleport_gate
*gate
= &world
.gates
[ world
.gate_count
++ ];
150 v3_copy( ga
->co
, gate
->co
[0] );
151 v3_copy( gb
->co
, gate
->co
[1] );
152 v4_copy( ga
->q
, gate
->q
[0] );
153 v4_copy( gb
->q
, gate
->q
[1] );
154 v2_copy( ga
->s
, gate
->dims
);
156 gate_transform_update( gate
);
162 * Load water mesh (1 per world)
164 for( int i
=0; i
<mworld
->layer_count
; i
++ )
166 submodel
*sm
= model_get_submodel( mworld
, i
);
167 if( !strcmp( sm
->material
, "water" ) )
170 model_unpack_submodel( mworld
, &surf
, sm
);
173 water_set_surface( &surf
, sm
->pivot
[1] );
175 vg_info( "%.3f\n", sm
->pivot
[1] );
181 scene_bh_create( &world
.geo
);
182 scene_upload( &world
.geo
);
184 scene_init( &world
.foliage
);
185 model
*mfoliage
= vg_asset_read("models/rs_foliage.mdl");
188 * TODO: Load any other meshes into the foliage scene, and create rbs for
194 for( int i
=0; i
<mworld
->layer_count
; i
++ )
196 submodel
*sm
= model_get_submodel( mworld
, i
);
197 if( !strcmp( sm
->material
, "surf" ) ||
198 !strcmp( sm
->material
, "terrain" ) ||
199 !strcmp( sm
->material
, "water" ) ||
200 !strcmp( sm
->material
, "vertex_blend") )
204 q_m3x3( sm
->q
, transform
);
205 v3_copy( sm
->pivot
, transform
[3] );
206 scene_add_foliage( &world
.foliage
, mworld
, sm
, transform
);
208 rigidbody
*rb
= &world
.temp_rbs
[ world
.rb_count
++ ];
210 box_copy( sm
->bbx
, rb
->bbx
);
211 v3_copy( sm
->pivot
, rb
->co
);
213 v4_copy( sm
->q
, rb
->q
);
214 rb_update_transform( rb
);
218 v3_sub( world
.geo
.bbx
[1], world
.geo
.bbx
[0], volume
);
223 submodel
*sm_blob
= submodel_get( mfoliage
, "blob" ),
224 *sm_tree
= submodel_get( mfoliage
, "tree" );
226 for( int i
=0;i
<100000;i
++ )
229 v3_mul( volume
, (v3f
){ vg_randf(), 1000.0f
, vg_randf() }, pos
);
231 v3_add( pos
, world
.geo
.bbx
[0], pos
);
236 if( ray_world( pos
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
238 if( hit
.normal
[1] > 0.8f
&& !ray_hit_is_ramp(&hit
) &&
239 hit
.pos
[1] > water_height()+10.0f
)
241 v4f qsurface
, qrandom
;
244 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, hit
.normal
, axis
);
246 float angle
= v3_dot(hit
.normal
,(v3f
){0.0f
,1.0f
,0.0f
});
247 q_axis_angle( qsurface
, axis
, angle
);
248 q_axis_angle( qrandom
, (v3f
){0.0f
,1.0f
,0.0f
}, vg_randf()*VG_TAUf
);
249 q_mul( qsurface
, qrandom
, qsurface
);
250 q_m3x3( qsurface
, transform
);
252 v3_copy( hit
.pos
, transform
[3] );
254 if( vg_randf() < 0.0006f
)
256 m3x3_identity( transform
);
257 scene_add_foliage( &world
.foliage
, mfoliage
, sm_tree
, transform
);
260 scene_add_foliage( &world
.foliage
, mfoliage
, sm_blob
, transform
);
266 scene_upload( &world
.foliage
);
270 scene_init( &world
.props
);
271 for( int i
=0; i
<mworld
->layer_count
; i
++ )
273 submodel
*sm
= model_get_submodel( mworld
, i
);
274 if( !strcmp( sm
->material
, "vertex_blend" ) )
277 q_m3x3( sm
->q
, transform
);
278 v3_copy( sm
->pivot
, transform
[3] );
279 scene_add_foliage( &world
.props
, mworld
, sm
, transform
);
283 scene_upload( &world
.props
);
285 bh_create( &world
.bhcubes
,
286 &bh_system_rigidbodies
, world
.temp_rbs
, world
.rb_count
);
289 * Rendering the depth map
295 v3_sub( world
.geo
.bbx
[1], world
.geo
.bbx
[0], extent
);
297 float fl
= world
.geo
.bbx
[0][0],
298 fr
= world
.geo
.bbx
[1][0],
299 fb
= world
.geo
.bbx
[0][2],
300 ft
= world
.geo
.bbx
[1][2],
305 ortho
[0][0] = 2.0f
* rl
;
306 ortho
[2][1] = 2.0f
* tb
;
307 ortho
[3][0] = (fr
+ fl
) * -rl
;
308 ortho
[3][1] = (ft
+ fb
) * -tb
;
310 m4x3_identity( camera
);
312 glViewport( 0, 0, 1024, 1024 );
313 glDisable(GL_DEPTH_TEST
);
314 glBindFramebuffer( GL_FRAMEBUFFER
, gpipeline
.fb_depthmap
);
315 shader_fscolour_use();
316 shader_fscolour_uColour( (v4f
){-9999.0f
,-9999.0f
,-9999.0f
,-9999.0f
} );
320 glBlendFunc(GL_ONE
, GL_ONE
);
321 glBlendEquation(GL_MAX
);
322 render_world_depth( ortho
, camera
);
324 glEnable(GL_DEPTH_TEST
);
327 * TODO: World settings entity
329 struct ub_world_lighting
*winfo
= &gpipeline
.ub_world_lighting
;
330 v4_copy( wrender
.plane
, winfo
->g_water_plane
);
333 bounds
[0] = world
.geo
.bbx
[0][0];
334 bounds
[1] = world
.geo
.bbx
[0][2];
335 bounds
[2] = 1.0f
/ (world
.geo
.bbx
[1][0]-world
.geo
.bbx
[0][0]);
336 bounds
[3] = 1.0f
/ (world
.geo
.bbx
[1][2]-world
.geo
.bbx
[0][2]);
337 v4_copy( bounds
, winfo
->g_depth_bounds
);
339 winfo
->g_water_fog
= 0.04f
;
340 render_update_lighting_ub();
343 static void world_init(void)
345 vg_tex2d_init( (vg_tex2d
*[]){ &tex_terrain_colours
,
346 &tex_terrain_noise
}, 2 );
349 model
*msky
= vg_asset_read("models/rs_skydome.mdl");
350 model_unpack( msky
, &world
.skydome
);
352 world
.dome_lower
= *submodel_get( msky
, "dome_lower" );
353 world
.dome_upper
= *submodel_get( msky
, "dome_upper" );
362 static void bind_terrain_textures(void)
364 vg_tex2d_bind( &tex_terrain_noise
, 0 );
365 vg_tex2d_bind( &tex_terrain_colours
, 1 );
368 static void render_props( m4x4f projection
, v3f camera
)
370 m4x3f identity_matrix
;
371 m4x3_identity( identity_matrix
);
374 shader_vblend_uTexGarbage(0);
375 shader_vblend_uTexGradients(1);
376 shader_link_standard_ub( _shader_vblend
.id
, 2 );
377 bind_terrain_textures();
379 shader_vblend_uPv( projection
);
380 shader_vblend_uMdl( identity_matrix
);
381 shader_vblend_uCamera( camera
);
383 scene_bind( &world
.props
);
384 scene_draw( &world
.props
);
387 static void render_terrain( m4x4f projection
, v3f camera
)
389 m4x3f identity_matrix
;
390 m4x3_identity( identity_matrix
);
392 shader_terrain_use();
393 shader_terrain_uTexGarbage(0);
394 shader_terrain_uTexGradients(1);
395 shader_link_standard_ub( _shader_terrain
.id
, 2 );
396 bind_terrain_textures();
398 shader_terrain_uPv( projection
);
399 shader_terrain_uMdl( identity_matrix
);
400 shader_terrain_uCamera( camera
);
402 scene_bind( &world
.geo
);
403 scene_draw( &world
.geo
);
405 glDisable(GL_CULL_FACE
);
406 scene_bind( &world
.foliage
);
407 scene_draw( &world
.foliage
);
408 glEnable(GL_CULL_FACE
);
411 static void render_lowerdome( m4x3f camera
)
413 m4x4f projection
, full
;
414 pipeline_projection( projection
, 0.4f
, 1000.0f
);
417 m3x3_transpose( camera
, inverse
);
418 v3_copy((v3f
){0.0f
,0.0f
,0.0f
}, inverse
[3]);
419 m4x3_expand( inverse
, full
);
420 m4x4_mul( projection
, full
, full
);
422 m4x3f identity_matrix
;
423 m4x3_identity( identity_matrix
);
425 shader_planeinf_use();
426 shader_planeinf_uMdl(identity_matrix
);
427 shader_planeinf_uPv(full
);
428 shader_planeinf_uCamera(camera
[3]);
429 shader_planeinf_uPlane( (v4f
){0.0f
,1.0f
,0.0f
, water_height()} );
431 submodel_draw( &world
.dome_lower
);
434 static void render_sky(m4x3f camera
)
436 m4x4f projection
, full
;
437 pipeline_projection( projection
, 0.4f
, 1000.0f
);
440 m3x3_transpose( camera
, inverse
);
441 v3_copy((v3f
){0.0f
,0.0f
,0.0f
}, inverse
[3]);
442 m4x3_expand( inverse
, full
);
443 m4x4_mul( projection
, full
, full
);
445 m4x3f identity_matrix
;
446 m4x3_identity( identity_matrix
);
449 shader_sky_uMdl(identity_matrix
);
450 shader_sky_uPv(full
);
451 shader_sky_uTexGarbage(0);
452 shader_sky_uTime( vg_time
);
454 vg_tex2d_bind( &tex_terrain_noise
, 0 );
456 glDepthMask( GL_FALSE
);
457 glDisable( GL_DEPTH_TEST
);
459 mesh_bind( &world
.skydome
);
460 submodel_draw( &world
.dome_upper
);
462 glEnable( GL_DEPTH_TEST
);
463 glDepthMask( GL_TRUE
);
466 static void render_world( m4x4f projection
, m4x3f camera
)
468 render_sky( camera
);
469 render_props( projection
, camera
[3] );
470 render_terrain( projection
, camera
[3] );
473 static void render_world_depth( m4x4f projection
, m4x3f camera
)
475 m4x3f identity_matrix
;
476 m4x3_identity( identity_matrix
);
479 shader_gpos_uCamera( camera
[3] );
480 shader_gpos_uPv( projection
);
481 shader_gpos_uMdl( identity_matrix
);
483 scene_bind( &world
.geo
);
484 scene_draw( &world
.geo
);
487 glDisable(GL_CULL_FACE
);
488 scene_bind( &world
.foliage
);
489 scene_draw( &world
.foliage
);
490 glEnable(GL_CULL_FACE
);
493 scene_bind( &world
.props
);
494 scene_draw( &world
.props
);