proxy models
[carveJwlIkooP6JGAAIwe30JlM.git] / world_render.c
index 1e99566e68ddd9f9e8169758473364b9722750ca..1d2256b4f6ddf88d7cefc696b68ece318e23e585 100644 (file)
@@ -84,6 +84,7 @@ static void world_render_init(void)
    shader_scene_depth_register();
    shader_scene_position_register();
    shader_model_sky_register();
+   shader_model_sky_space_register();
 
    vg_info( "Loading world resources\n" );
    vg_linear_clear( vg_mem.scratch );
@@ -153,6 +154,45 @@ struct world_pass{
    void (*fn_set_uNormalMtx)( m3x3f mnorm );
 };
 
+/* FIXME: we gotta do something about this crap, maybe batch lists. something..
+ * anything but this. */
+static
+void world_render_props( world_instance *world, u32 material_id,
+                         struct world_pass *pass ){
+   if( !mdl_arrcount( &world->ent_prop ) ) return;
+
+   /* HACK: use the first material for every prop entity */
+   ent_prop *first = mdl_arritm( &world->ent_prop, 0 );
+   if( !first->submesh_count ) return;
+
+   mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, first->submesh_start );
+   if( sm->material_id != material_id ) return;
+
+   struct world_surface *mat = &world->surfaces[ material_id ];
+   pass->fn_bind_textures( world, mat );
+
+   for( u32 j=0; j<mdl_arrcount( &world->ent_prop ); j++ ){
+      ent_prop *prop = mdl_arritm( &world->ent_prop, j );
+      if( prop->flags & 0x1 ) continue;
+      
+      for( u32 k=0; k<prop->submesh_count; k++ ){
+         sm = mdl_arritm( &world->meta.submeshs, prop->submesh_start+k );
+
+         m4x3f mmdl;
+         mdl_transform_m4x3( &prop->transform, mmdl );
+
+         m4x4f m4mdl;
+         m4x3_expand( mmdl, m4mdl );
+         m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl );
+
+         pass->fn_set_mdl( mmdl );
+         pass->fn_set_uPvmPrev( m4mdl );
+
+         mdl_draw_submesh( sm );
+      }
+   }
+}
+
 static
 void world_render_traffic( world_instance *world, u32 material_id,
                            struct world_pass *pass ){
@@ -204,6 +244,7 @@ void world_render_pass( world_instance *world, struct world_pass *pass ){
          }
          else{
             world_render_traffic( world, i, pass );
+            world_render_props( world, i, pass );
             sm = &mat->sm_no_collide;
          }
 
@@ -644,8 +685,7 @@ static void render_terrain( world_instance *world, camera *cam ){
    world_render_both_stages( world, &pass );
 }
 
-static void render_sky( world_instance *world, camera *cam )
-{
+static void render_sky( world_instance *world, camera *cam ){
    /* 
     * Modify matrix to remove clipping and view translation
     */
@@ -673,15 +713,32 @@ static void render_sky( world_instance *world, camera *cam )
    /*
     * Draw
     */
-   shader_model_sky_use();
-   shader_model_sky_uMdl( identity_matrix );
-   shader_model_sky_uPv( pv );
-   shader_model_sky_uPvmPrev( pv_prev );
-   shader_model_sky_uTexGarbage(0);
-   world_link_lighting_ub( world, _shader_model_sky.id );
+   if( world->skybox == k_skybox_default ){
+      shader_model_sky_use();
+      shader_model_sky_uMdl( identity_matrix );
+      shader_model_sky_uPv( pv );
+      shader_model_sky_uPvmPrev( pv_prev );
+      shader_model_sky_uTexGarbage(0);
+      world_link_lighting_ub( world, _shader_model_sky.id );
+
+      glActiveTexture( GL_TEXTURE0 );
+      glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
+   }
+   else if( world->skybox == k_skybox_space ){
+      shader_model_sky_space_use();
 
-   glActiveTexture( GL_TEXTURE0 );
-   glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
+      shader_model_sky_space_uMdl( identity_matrix );
+      shader_model_sky_space_uPv( pv );
+      shader_model_sky_space_uPvmPrev( pv_prev );
+      shader_model_sky_space_uTexGarbage(0);
+      world_link_lighting_ub( world, _shader_model_sky_space.id );
+
+      glActiveTexture( GL_TEXTURE0 );
+      glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
+   }
+   else {
+      assert(0);
+   }
 
    glDepthMask( GL_FALSE );
    glDisable( GL_DEPTH_TEST );
@@ -858,7 +915,9 @@ static void render_world_override_pass( world_instance *world,
    }
 }
 
-static void render_world_override( world_instance *world, m4x3f mmdl ){
+static void render_world_override( world_instance *world,
+                                   world_instance *lighting_source,
+                                   m4x3f mmdl ){
    struct world_pass pass = {
       .cam = &skaterift.cam,
       .fn_bind_textures = bindpoint_override,
@@ -869,32 +928,51 @@ static void render_world_override( world_instance *world, m4x3f mmdl ){
    };
 
    shader_scene_override_use();
+#if 0
    respawn_chooser_shader_uniforms();
+#endif
    shader_scene_override_uTexGarbage(0);
    shader_scene_override_uTexMain(1);
    shader_scene_override_uPv( pass.cam->mtx.pv );
 
-   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_override );
+   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( lighting_source, scene_override );
    bind_terrain_noise();
 
-   m4x3f mmdl_inv;
-   m4x3_invert_full( mmdl, mmdl_inv );
-
-   v3f cam_pos;
-   m4x3_mulv( mmdl_inv, pass.cam->transform[3], cam_pos );
-   shader_scene_override_uCamera( cam_pos );
+   shader_scene_override_uCamera( pass.cam->transform[3] );
 
    m4x4f mpvm_prev;
    m4x3_expand( mmdl, mpvm_prev );
    m4x4_mul( skaterift.cam.mtx_prev.pv, mpvm_prev, mpvm_prev );
 
    m3x3f mnormal;
-   m3x3_inv( mmdl_inv, mnormal );
+   m3x3_inv( mmdl, mnormal );
    m3x3_transpose( mnormal, mnormal );
    v3_normalize( mnormal[0] );
    v3_normalize( mnormal[1] );
    v3_normalize( mnormal[2] );
 
+   v4f uPlayerPos, uSpawnPos;
+   v4_zero( uPlayerPos );
+   v4_zero( uSpawnPos );
+
+   v3_copy( world->player_co, uPlayerPos );
+   
+   m4x3f mmdl_inv;
+   m4x3_invert_full( mmdl, mmdl_inv );
+   v3f localized;
+   m4x3_mulv( mmdl_inv, localplayer.rb.co, localized );
+   ent_spawn *spawn = world_find_closest_spawn( world, localized );
+   if( spawn )
+      v3_copy( spawn->transform.co, uSpawnPos );
+
+   uPlayerPos[3] = v3_dist(uPlayerPos,uSpawnPos);
+   uSpawnPos[3] = 1.0f/uPlayerPos[3];
+
+   shader_scene_override_uPlayerPos( uPlayerPos );
+   shader_scene_override_uSpawnPos( uSpawnPos );
+
+
+
    glDisable( GL_CULL_FACE );
    mesh_bind( &world->mesh_geo );
    pass.geo_type = k_world_geo_type_solid;