stuff
authorhgn <hgodden00@gmail.com>
Fri, 1 Jul 2022 22:40:26 +0000 (23:40 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 1 Jul 2022 22:40:26 +0000 (23:40 +0100)
19 files changed:
gate.h
main.c
player.h
render.h
rigidbody.h
scene.h
shaders/sky.fs
shaders/sky.h
shaders/terrain.fs
shaders/terrain.h
shaders/water.fs
shaders/water.h
shaders/water.vs
terrain.h
textures/gradients.png
textures/water_surf.png
vg_config.h
water.h
world.h

diff --git a/gate.h b/gate.h
index 6e9b95f9b8d27fcebe255fe496d1a52b78cda74b..7088c7dc5c236dc03223e5b3948904a6011278d0 100644 (file)
--- a/gate.h
+++ b/gate.h
@@ -13,16 +13,20 @@ typedef struct teleport_gate teleport_gate;
 
 static struct
 {
-   GLuint fb, rgb, rb;
+   struct framebuffer fb;
    glmesh mdl;
 
    int high_qual; /* If in high performance mode, we don't use RT's, and
-                            instead use stencil buffers.
-                            There is therefore no heat warp effect. */
+                      instead use stencil buffers.
+                      There is therefore no heat warp effect. */
 }
 grender =
 {
-   .high_qual = 0
+   .high_qual = 0,
+   .fb = {
+      .format = GL_RGB,
+      .div = 1
+   }
 };
 
 struct teleport_gate
@@ -56,7 +60,7 @@ static void gate_register(void)
 
 static void gate_init(void)
 {
-   create_renderbuffer_std( &grender.fb, &grender.rgb, &grender.rb );
+   fb_init( &grender.fb );
 
    model *mgate = vg_asset_read( "models/rs_gate.mdl" );
    model_unpack( mgate, &grender.mdl );
@@ -65,7 +69,7 @@ static void gate_init(void)
 
 static void gate_fb_resize(void)
 {
-   resize_renderbuffer_std( &grender.fb, &grender.rgb, &grender.rb );
+   fb_resize( &grender.fb );
 }
 
 static void render_gate( teleport_gate *gate, m4x3f camera )
@@ -129,7 +133,7 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
 
    if( grender.high_qual )
    {
-      glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
+      fb_use( &grender.fb );
       glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
       glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
    }
@@ -167,17 +171,18 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
        */
 
       render_water_texture( cam_new );
-      glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
-      render_water_surface( projection );
-      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+      fb_use( &grender.fb );
+
+      render_water_surface( projection, cam_new );
+      fb_use( NULL );
 
       shader_gate_use();
 
       shader_gate_uPv( vg_pv );
       shader_gate_uMdl( gate_xform );
 
-      glActiveTexture( GL_TEXTURE0 );
-      glBindTexture( GL_TEXTURE_2D, grender.rgb );
+      fb_bindtex( &grender.fb, 0 );
+
       shader_gate_uCam( viewpos );
       shader_gate_uTexMain( 0 );
       shader_gate_uTexWater( 1 );
diff --git a/main.c b/main.c
index 6b38fc5401b69366bb36a1872d3b81c7c4451b06..def609d6c915b063db19fba3a135ea68c810261f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -59,17 +59,6 @@ int main( int argc, char *argv[] )
    vg_init( argc, argv, "Voyager Game Engine" ); 
 }
 
-#if 0
-rigidbody mr_box = {
-   .bbx = {{ -1.0f, -0.25f, -0.25f }, { 1.0f, 0.25f, 0.25f }}
-};
-
-rigidbody mrs_box = {
-   .bbx = {{ -0.5f, -0.25f, -0.25f }, { 0.5f, 0.25f, 0.25f }}
-};
-
-#endif
-
 static int playermodel( int argc, char const *argv[] )
 {
    if( argc < 1 ) return 0;
@@ -145,6 +134,11 @@ void vg_start(void)
    player_transform_update();
 }
 
+void vg_free(void)
+{
+   vg_tex2d_free( texture_list, vg_list_size(texture_list) );
+}
+
 void vg_update(void)
 {
    player_update();
@@ -170,30 +164,6 @@ void vg_render(void)
    v3f shake = { vg_randf()-0.5f, vg_randf()-0.5f, vg_randf()-0.5f };
    v3_muls( shake, speed*0.01f, shake );
 
-   if( player.is_dead )
-   {
-#if 0
-      v3f delta;
-      v3_sub( player.mdl.ragdoll[k_chpart_head].co, player.follow, delta );
-      v3_normalize(delta);
-
-      v3f follow_pos;
-      v3_muladds( player.mdl.ragdoll[k_chpart_head].co, delta, 
-            -1.5f, follow_pos );
-      v3_lerp( player.follow, follow_pos, 0.1f, player.follow );
-      v3_negate( player.follow, final );
-
-
-      float yaw = atan2f( delta[0], -delta[2] );
-      float pitch = asinf( delta[1] );
-      m4x3_rotate_x( world_matrix, -pitch );
-      m4x3_rotate_y( world_matrix, yaw );
-#endif
-   }
-   else
-   {
-   }
-
    m4x4f world_4x4;
    m4x3_expand( player.camera_inverse, world_4x4 );
 
@@ -218,7 +188,7 @@ void vg_render(void)
    render_water_texture( player.camera );
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   render_water_surface( vg_pv );
+   render_water_surface( vg_pv, player.camera );
 
    vg_tex2d_bind( &tex_water, 1 );
 
@@ -247,7 +217,11 @@ void vg_render(void)
 
    draw_player();
 
-   /* Draw back in the background */
+   /* Draw back in the background
+    *
+    * TODO: need to disable alpha write in the terrain shader so this works 
+    *       again.
+    */
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
@@ -264,39 +238,6 @@ void vg_render(void)
    /* Other shite */
    glDisable( GL_DEPTH_TEST );
    vg_lines_drawall( (float *)vg_pv );
-
-   /* Debugger camera */
-#if 0
-   glViewport( 0,0, 800, 800 );
-   glClearColor( 0.1f, 0.0f, 0.2f, 1.0f );
-   glClear( GL_DEPTH_BUFFER_BIT );
-
-   m4x3_identity( world_matrix );
-
-   v3f debugcam;
-   v3_negate( player.co, debugcam );
-   debugcam[2] -= 2.0f;
-   debugcam[1] -= 0.7f;
-
-   m4x3_translate( world_matrix, debugcam );
-   m4x3_expand( world_matrix, world_4x4 );
-
-   m4x4_projection( vg_pv, 
-         100.0f,
-         (float)128.0f / (float)128.0f,
-         0.1f, 1000.0f );
-   m4x4_mul( vg_pv, world_4x4, vg_pv );
-
-   if(sv_debugcam)
-   {
-      glEnable( GL_DEPTH_TEST );
-      draw_player();
-   }
-#endif
-
-   glDisable( GL_DEPTH_TEST );
-   vg_lines_drawall( (float *)vg_pv );
-
    glViewport( 0,0, vg_window_x, vg_window_y );
 }
 
@@ -329,5 +270,3 @@ void vg_ui(void)
             "Gamepad not ready", 1, k_text_align_left );
    }
 }
-
-void vg_free(void){}
index 7ab0e63d57fabbae67d0b4815ab5537579593f56..6c819801b01f664310d73f91144bc1be1911ab92 100644 (file)
--- a/player.h
+++ b/player.h
@@ -31,7 +31,7 @@ static struct gplayer
    v3f land_target_log[22];
    u32 land_target_colours[22];
    int land_log_count;
-   m3x3f vr;
+   m3x3f vr,vr_pstep;
 
    m4x3f to_world, to_local;
    
@@ -93,6 +93,7 @@ static void player_mouseview(void)
 
    if( vg_get_button_down( "primary" ) )
       v2_copy( vg_mouse, mouse_last );
+
    else if( vg_get_button( "primary" ) )
    {
       v2f delta;
@@ -102,10 +103,12 @@ static void player_mouseview(void)
       v2_muladds( view_vel, delta, 0.005f, view_vel );
    }
    
+   v2_muladds( view_vel, 
+         (v2f){ vg_get_axis("h1"), vg_get_axis("v1") }, 
+         0.05f, view_vel );
    v2_muls( view_vel, 0.7f, view_vel );
    v2_add( view_vel, player.angles, player.angles );
    player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f );
-
 }
 
 static void player_freecam(void)
@@ -219,7 +222,8 @@ static void player_start_air(void)
                best_velocity_mod = vmod;
 
                v3_copy( contact.pos, player.land_target );
-
+               
+               m3x3_copy( vr, player.vr_pstep );
                q_axis_angle( vr_q, axis, vmod*0.1f );
                q_m3x3( vr_q, player.vr );
             }
@@ -364,7 +368,9 @@ static void player_physics_ground(void)
    for( int i=0; i<5; i++ )
    {
       vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * fwd_resistance );
-      vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -7.0f *substep );
+
+      /* This used to be -7.0 */
+      vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -10.0f *substep );
    }
    
    static double start_push = 0.0;
@@ -454,6 +460,7 @@ static void player_physics_air(void)
    for( int i=0; i<50; i++ )
    {
       v3_copy( pco, pco1 );
+      m3x3_mulv( player.vr_pstep, pv, pv );
       apply_gravity( pv, pstep );
       v3_muladds( pco, pv, pstep, pco );
 
@@ -498,7 +505,8 @@ static void player_physics_air(void)
    player.iY -= vg_get_axis( "horizontal" ) * 3.6f * ktimestep;
    {
 
-      float iX = vg_get_axis( "vertical" ) * 3.6f * limiter * ktimestep;
+      float iX = vg_get_axis( "vertical" ) * 
+         player.reverse * 3.6f * limiter * ktimestep;
       static float siX = 0.0f;
       siX = vg_lerpf( siX, iX, 0.3f );
       
@@ -617,10 +625,6 @@ struct walkgrid
    }
    samples[WALKGRID_SIZE][WALKGRID_SIZE];
 
-#if 0
-   u32 geo[256];
-#endif
-
    boxf region;
 
    float move; /* Current amount of movement we have left to apply */
@@ -639,10 +643,6 @@ static void player_walkgrid_samplepole( struct grid_sample *s )
    boxf region = {{ s->pos[0] -0.01f, s->pos[1] - 4.0f, s->pos[2] -0.01f},
                   { s->pos[0] +0.01f, s->pos[1] + 4.0f, s->pos[2] +0.01f}};
 
-#if 0
-   vg_line( region[0],region[1], 0x20ffffff );
-#endif
-
    u32 geo[256];
    v3f tri[3];
    int len = bh_select( &world.geo.bhtris, region, geo, 256 );
@@ -678,18 +678,11 @@ static void player_walkgrid_samplepole( struct grid_sample *s )
             {
                walk_height = p0[1];
             }
-
-#if 0
-            draw_cross( p0, 0xffffffff, 0.05f );
-#endif
          }
          else
          {
             if( p0[1] > block_height )
                block_height = p0[1];
-#if 0
-            draw_cross( p0, 0xff0000ff, 0.05f );
-#endif
          }
       }
    }
@@ -703,39 +696,6 @@ static void player_walkgrid_samplepole( struct grid_sample *s )
          s->type = k_sample_type_valid;
    else
       s->type = k_sample_type_air;
-   
-#if 0
-   if( s->type == k_sample_type_valid )
-   {
-      vg_line_pt3( s->pos, 0.01f, 0xff00ff00 );
-   }
-#endif
-
-#if 0
-   int count = 0;
-
-   ray_hit hit;
-   hit.dist = 10.0f;
-   count = bvh_raycast( &world.geo, sample_pos, vdir, &hit );
-
-   if( count )
-   {
-      v3_copy( hit.pos, s->pos );
-
-      if( !player_walkgrid_tri_walkable( hit.tri ) )
-      {
-         draw_cross( pos, 0xff0000ff, 0.05f );
-         return 0;
-      }
-      else
-      {
-         draw_cross( pos, 0xff00ff00, 0.05f );
-         return count;
-      }
-   }
-   else
-      return 0;
-#endif
 }
 
 float const k_gridscale = 0.5f;
@@ -876,29 +836,6 @@ static void player_walkgrid_clip_edge( struct grid_sample *sa,
    }
 }
 
-static void player_walkgrid_clip( struct grid_sample *sa,
-                                  struct grid_sample *sb,
-                                  enum eclipdir dir )
-{
-   int mintype = VG_MIN( sa->type, sb->type ),
-       maxtype = VG_MAX( sa->type, sb->type );
-
-   if( maxtype == k_sample_type_valid )
-   {
-      if( mintype == k_sample_type_air || mintype == k_sample_type_invalid )
-      {
-         player_walkgrid_clip_edge( sa, sb, sa, dir );
-      }
-
-#if 0
-      else if( mintype == k_sample_type_invalid )
-      {
-         player_walkgrid_clip_blocker( sa, sb, dir );
-      }
-#endif
-   }
-}
-
 static const struct conf
 {
    struct confedge
@@ -1032,19 +969,6 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter)
     * the intersections with the grid, and any edges that are present
     */
 
-#if 0
-   if( wg->cell_id[0] < 0 || wg->cell_id[0] >= WALKGRID_SIZE-1 ||
-       wg->cell_id[1] < 0 || wg->cell_id[1] >= WALKGRID_SIZE-1 )
-   {
-      /*
-       * This condition should never be reached if the grid size is big 
-       * enough
-       */
-      wg->move = -1.0f;
-      return;
-   }
-#endif
-
    u32 icolours[] = { 0xffff00ff, 0xff00ffff, 0xffffff00 };
    
    v3f pa, pb, pc, pd, pl0, pl1;
@@ -1061,6 +985,7 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter)
    pd[1] = pa[1];
    pd[2] = pa[2];
 #if 0
+   /* if you want to draw the current cell */
    vg_line( pa, pb, 0xff00ffff );
    vg_line( pb, pc, 0xff00ffff );
    vg_line( pc, pd, 0xff00ffff );
@@ -1419,6 +1344,11 @@ static void player_walkgrid_getsurface(void)
          v3_muladds( delta, side, -ktimestep*k_walkspeed, delta );
       if( glfwGetKey( vg_window, GLFW_KEY_D ) )
          v3_muladds( delta, side,  ktimestep*k_walkspeed, delta );
+
+      v3_muladds( delta, fwd, 
+            vg_get_axis("vertical")*-ktimestep*k_walkspeed, delta );
+      v3_muladds( delta, side, 
+            vg_get_axis("horizontal")*ktimestep*k_walkspeed, delta );
    }
 
    /* 
@@ -1440,73 +1370,6 @@ static void player_walkgrid_getsurface(void)
    wg.cell_id[0] = region_cell_pos[0];
    wg.cell_id[1] = region_cell_pos[1];
 
-
-#if 0
-   /* Get surface samples
-    *
-    * TODO: Replace this with a spiral starting from the player position
-    */
-   for( int y=0; y<WALKGRID_SIZE; y++ )
-   {
-      for( int x=0; x<WALKGRID_SIZE; x++ )
-      {
-         struct grid_sample *s = &wg.samples[y][x];
-         v3_muladds( wg.region[0], (v3f){ x, 0, y }, k_gridscale, s->pos );
-         s->pos[1] = cell[1];
-         player_walkgrid_samplepole( s );
-      }
-   }
-   
-   /* 
-    * Calculate h+v clipping distances.
-    * Distances are stored in A always, so you know that if the sample is
-    * invalid, this signifies the start of the manifold as opposed to the
-    * extent or bounds of it.
-    */
-   for( int i=0; i<2; i++ )
-   {
-      for( int x=0; x<WALKGRID_SIZE; x++ )
-      {
-         for( int z=0; z<WALKGRID_SIZE-1; z++ )
-         {
-            struct grid_sample *sa, *sb;
-            if( i == 1 )
-            {
-               sa = &wg.samples[z][x];
-               sb = &wg.samples[z+1][x];
-            }
-            else
-            {
-               sa = &wg.samples[x][z];
-               sb = &wg.samples[x][z+1];
-            }
-            
-            player_walkgrid_clip( sa, sb, i );
-
-            if( sa->type == k_sample_type_valid && 
-                sb->type == k_sample_type_valid )
-               vg_line( sa->pos, sb->pos, 0xffffffff );
-#if 0
-            if( sa->valid != sb->valid )
-            {
-               clipdir[i*2] = (float)(sa->valid - sb->valid) * k_gridscale;
-
-               player_walkgrid_clip( sa->valid? sa->pos: sb->pos,
-                                     clipdir, sa->clip[i] );
-            }
-            else
-            {
-               if( sa->valid )
-               {
-                  vg_line( sa->pos, sb->pos, 0xffffffff );
-               }
-            }
-#endif
-         }
-      }
-   }
-#endif
-   
    for(int y=0; y<WALKGRID_SIZE; y++ )
    {
       for(int x=0; x<WALKGRID_SIZE; x++ )
@@ -1634,13 +1497,6 @@ static void player_walkgrid_getsurface(void)
          break;
    }
 
-#if 0
-   player.co[0] += wg.dir[0];
-   player.co[2] += wg.dir[1];
-#endif
-
-
-
    /* Draw connections */
    struct grid_sample *corners[4];
    for( int x=0; x<WALKGRID_SIZE-1; x++ )
@@ -1727,15 +1583,6 @@ static void player_animate(void)
    v3_muladds( head, offset, 0.7f, head );
    head[1] = vg_clampf( head[1], 0.3f, kheight );
 
-#if 0
-   if( !freecam )
-   {
-      v3_copy( head, player.view );
-      v3f camoffs = {-0.2f,-0.6f,0.00f};
-      v3_add( player.view, camoffs, player.view );
-   }
-#endif
-
    /* 
     * Animation blending
     * ===========================================
@@ -2169,6 +2016,11 @@ static void player_update(void)
    if( vg_get_axis("grabl")>0.0f)
       reset_player(0,NULL);
 
+   if( vg_get_button_down( "switchmode" ) )
+   {
+      player.on_board ^= 0x1;
+   }
+
    if( freecam )
    {
       player_freecam();
@@ -2177,8 +2029,41 @@ static void player_update(void)
    {
       if( player.is_dead )
       {
+         /* 
+          * Follow camera
+          */
          character_ragdoll_iter( &player.mdl );
          character_debug_ragdoll( &player.mdl );
+
+         v3f delta;
+         v3f head_pos;
+         v3_copy( player.mdl.ragdoll[k_chpart_head].co, head_pos );
+
+         v3_sub( head_pos, player.camera_pos, delta );
+         v3_normalize( delta );
+
+         v3f follow_pos;
+         v3_muladds( head_pos, delta, -2.5f, follow_pos );
+         v3_lerp( player.camera_pos, follow_pos, 0.1f, player.camera_pos );
+
+         /* 
+          * Make sure the camera stays above the ground
+          */
+         v3f min_height = {0.0f,1.0f,0.0f};
+
+         v3f sample;
+         v3_add( player.camera_pos, min_height, sample );
+         ray_hit hit;
+         hit.dist = min_height[1]*2.0f;
+
+         if( ray_world( sample, (v3f){0.0f,-1.0f,0.0f}, &hit ))
+            v3_add( hit.pos, min_height, player.camera_pos );
+
+         player.camera_pos[1] = 
+            vg_maxf( wrender.height + 2.0f, player.camera_pos[1] );
+
+         player.angles[0] = atan2f( delta[0], -delta[2] ); 
+         player.angles[1] = -asinf( delta[1] );
       }
       else
       {
index ef7a82fb73f9986b5568c72cee08f7caf2b70294..d8bdc95ea21503662a93fc85d06690d5b49299ae 100644 (file)
--- a/render.h
+++ b/render.h
@@ -14,8 +14,15 @@ static struct pipeline
 }
 gpipeline;
 
+struct framebuffer
+{
+   GLuint fb, colour, rb;
+   int div;
+   GLuint format;
+};
+
 static void render_water_texture( m4x3f camera );
-static void render_water_surface( m4x4f pv );
+static void render_water_surface( m4x4f pv, m4x3f camera );
 static void render_world( m4x4f projection, m4x3f camera );
 
 /* 
@@ -47,41 +54,63 @@ static void pipeline_projection( m4x4f mat, float nearz, float farz )
          nearz, farz );
 }
 
-static void create_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
+static void fb_use( struct framebuffer *fb )
 {
-   glGenFramebuffers( 1, fb );
-   glBindFramebuffer( GL_FRAMEBUFFER, *fb );
+   if( !fb )
+   {
+      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+      glViewport( 0, 0, vg_window_x, vg_window_y );
+   }
+   else
+   {
+      glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
+      glViewport( 0, 0, vg_window_x / fb->div, vg_window_y / fb->div );
+   }
+}
 
-   glGenTextures( 1, rgb );
-   glBindTexture( GL_TEXTURE_2D, *rgb );
-   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 
-         0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+static void fb_init( struct framebuffer *fb )
+{
+   i32 ix = vg_window_x / fb->div,
+       iy = vg_window_y / fb->div;
+
+   glGenFramebuffers( 1, &fb->fb );
+   glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
+
+   glGenTextures( 1, &fb->colour );
+   glBindTexture( GL_TEXTURE_2D, fb->colour );
+   glTexImage2D( GL_TEXTURE_2D, 0, fb->format, ix, iy,
+         0, fb->format, GL_UNSIGNED_BYTE, NULL);
 
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
-         GL_TEXTURE_2D, *rgb, 0);
+         GL_TEXTURE_2D, fb->colour, 0);
 
-   /* TODO: Check for DEPTH32f availiblity and use if possible */
-
-   glGenRenderbuffers( 1, rb );
-   glBindRenderbuffer( GL_RENDERBUFFER, *rb );
-   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 
-         vg_window_x, vg_window_y );
+   glGenRenderbuffers( 1, &fb->rb );
+   glBindRenderbuffer( GL_RENDERBUFFER, fb->rb );
+   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, ix, iy );
 
    glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-         GL_RENDERBUFFER, *rb );
+         GL_RENDERBUFFER, fb->rb );
 }
 
-static void resize_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
+static void fb_bindtex( struct framebuffer *fb, int texture )
 {
-   glBindTexture( GL_TEXTURE_2D, *rgb );
-   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 0,
-         GL_RGB, GL_UNSIGNED_BYTE, NULL );
+   glActiveTexture( GL_TEXTURE0 + texture );
+   glBindTexture( GL_TEXTURE_2D, fb->colour );
+}
+
+static void fb_resize( struct framebuffer *fb )
+{
+   i32 ix = vg_window_x / fb->div,
+       iy = vg_window_y / fb->div;
+
+   glBindTexture( GL_TEXTURE_2D, fb->colour );
+   glTexImage2D( GL_TEXTURE_2D, 0, fb->format, ix, iy, 0,
+         fb->format, GL_UNSIGNED_BYTE, NULL );
 
-   glBindRenderbuffer( GL_RENDERBUFFER, *rb );
-   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 
-         vg_window_x, vg_window_y );
+   glBindRenderbuffer( GL_RENDERBUFFER, fb->rb );
+   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, ix, iy );
 }
 
 static void render_fb_resize(void)
index aa74a8477436296d4932a02ae91691cb2096cdfc..845237f2e5e7b3f15ca7b15576da890d5e4557a8 100644 (file)
@@ -4,15 +4,15 @@
  */
 
 #include "common.h"
+#include "bvh.h"
+
 static void rb_tangent_basis( v3f n, v3f tx, v3f ty );
+static bh_system bh_system_rigidbodies;
 
 #ifndef RIGIDBODY_H
 #define RIGIDBODY_H
 
-#include "bvh.h"
-
 #define RB_DEPR 
-
 #define k_rb_delta (1.0f/60.0f)
 
 typedef struct rigidbody rigidbody;
@@ -289,7 +289,6 @@ static void rb_constraint_angle_limit( struct rb_angle_limit *limit )
 
 }
 
-
 RB_DEPR
 static void rb_constraint_angle( rigidbody *rba, v3f va,
                                  rigidbody *rbb, v3f vb, 
@@ -384,6 +383,10 @@ static void rb_constraint_position( rigidbody *ra, v3f lca,
    v3_add( impulse, ra->I, ra->I );
 
 #if 0
+   /*
+    * this could be used for spring joints
+    * its not good for position constraint
+    */
    v3f impulse;
    v3_muls( delta, 0.5f*spring, impulse );
 
diff --git a/scene.h b/scene.h
index b76aaee475320ab24a63a3130161de02319539fe..6f7c28cbe63b3ac4a0bfd1e6feed6eab22a45f40 100644 (file)
--- a/scene.h
+++ b/scene.h
@@ -6,9 +6,6 @@
 #include "bvh.h"
 
 typedef struct scene scene;
-#if 0
-typedef struct bvh_node bvh_node;
-#endif
 
 struct scene
 {
@@ -17,17 +14,7 @@ struct scene
    model_vert *verts;
    u32 *indices;
    
-#if 0
-   struct 
-   {
-      bvh_node *nodes;
-      u32 node_count;
-   }
-   bvh;
-#else
    bh_tree bhtris;
-#endif
-
    u32 vertex_count,
        indice_count,
        vertex_cap,
index 9e08967b1a741cdfaa6fdd14e909667737423600..653f4b9c41546eb1c28c4415f1a98888e4438397 100644 (file)
@@ -12,25 +12,24 @@ in vec3 aCo;
 void main()
 {
    float fintensity = 1.0-(abs(aNorm.y)*0.7);
-   float angle = -dot(vec3(0.95,0.0,-0.3),aNorm)*0.5+0.5;
-   float fblend = pow(fintensity,6.0) * angle;
-   vec3 horizon = vec3(0.9,0.9,0.8);
-   vec3 skycolour = vec3(0.4,0.5,0.8);
+   float fblend = pow(fintensity,6.0);
+   vec3 horizon = vec3( 0.61, 0.71, 0.86 )*1.5;
+   vec3 skycolour = vec3( 0.31, 0.56, 0.91 );
    vec3 diffuse = mix( skycolour, horizon, fblend );
 
-   float fmove = uTime * 0.001;
+   float fmove = uTime * 0.004;
    vec2 cloudplane = (aCo.xz / (aCo.y*sign(aNorm.y))) * 0.03;
    vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );
    vec4 clouds2 = texture( uTexGarbage, cloudplane + vec2(0.3,0.1)*fmove );
 
    float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);
-   float cloud_e = pow(cloud_d,1.8)*pow(abs(aNorm.y),0.3)*2.0;
+   float cloud_e = pow(cloud_d,1.5)*pow(abs(aNorm.y),0.3)*2.0;
 
    vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );
    float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );
 
-   vec3 skycomp = mix(diffuse, vec3(1.0), cloud_e);
+   vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);
    skycomp = mix(mix(pow(colour_ocean,vec3(6.0))*0.6,skycomp, 0.7),skycomp,fhorizon);
 
-   FragColor = vec4(skycomp, 1.0);
+   FragColor = vec4(skycomp, 0.0);
 }
index 920036a0110f0ecb9be9dd11b4e78e23a5a7a967..653173ec8d4d617d59b549527daa8a78ea64c9c3 100644 (file)
@@ -51,27 +51,26 @@ static struct vg_shader _shader_sky = {
 "void main()\n"
 "{\n"
 "   float fintensity = 1.0-(abs(aNorm.y)*0.7);\n"
-"   float angle = -dot(vec3(0.95,0.0,-0.3),aNorm)*0.5+0.5;\n"
-"   float fblend = pow(fintensity,6.0) * angle;\n"
-"   vec3 horizon = vec3(0.9,0.9,0.8);\n"
-"   vec3 skycolour = vec3(0.4,0.5,0.8);\n"
+"   float fblend = pow(fintensity,6.0);\n"
+"   vec3 horizon = vec3( 0.61, 0.71, 0.86 )*1.5;\n"
+"   vec3 skycolour = vec3( 0.31, 0.56, 0.91 );\n"
 "   vec3 diffuse = mix( skycolour, horizon, fblend );\n"
 "\n"
-"   float fmove = uTime * 0.001;\n"
+"   float fmove = uTime * 0.004;\n"
 "   vec2 cloudplane = (aCo.xz / (aCo.y*sign(aNorm.y))) * 0.03;\n"
 "   vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );\n"
 "   vec4 clouds2 = texture( uTexGarbage, cloudplane + vec2(0.3,0.1)*fmove );\n"
 "\n"
 "   float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);\n"
-"   float cloud_e = pow(cloud_d,1.8)*pow(abs(aNorm.y),0.3)*2.0;\n"
+"   float cloud_e = pow(cloud_d,1.5)*pow(abs(aNorm.y),0.3)*2.0;\n"
 "\n"
 "   vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );\n"
 "   float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );\n"
 "\n"
-"   vec3 skycomp = mix(diffuse, vec3(1.0), cloud_e);\n"
+"   vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);\n"
 "   skycomp = mix(mix(pow(colour_ocean,vec3(6.0))*0.6,skycomp, 0.7),skycomp,fhorizon);\n"
 "\n"
-"   FragColor = vec4(skycomp, 1.0);\n"
+"   FragColor = vec4(skycomp, 0.0);\n"
 "}\n"
 ""},
 };
index fbfa276767f2f7a4f9e6de2dfe9584e27376edf9..98895a0d1ddd1c00df5eb3fb403d3911b9767940 100644 (file)
@@ -3,36 +3,52 @@ out vec4 FragColor;
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexGradients;
 uniform vec3 uCamera;
+uniform vec4 uPlane;
 
 in vec4 aColour;
 in vec2 aUv;
 in vec3 aNorm;
 in vec3 aCo;
 
+float water_depth( vec3 pos, vec3 dir, vec4 plane )
+{
+   float d = dot( plane.xyz, dir );
+   float t = dot((plane.xyz*plane.w - pos),plane.xyz) / d;
+   return t*0.05;
+}
+
 void main()
 {
    vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );
+   
+   // Creating normal patches
    vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;
-   vec3 qnorm = floor(aNorm*4.0+modnorm) * 0.25;
-
+   vec3 qnorm = normalize(floor(aNorm*4.0+modnorm) * 0.25);
    vec2 dir = normalize(qnorm.xz);
    vec2 uvdiffuse = aCo.xz * 0.02;
    uvdiffuse = mat2(dir.y, dir.x, -dir.x, dir.y) * uvdiffuse;
-
+   
+   // Patch local noise
    vec4 rgarbage = texture( uTexGarbage, uvdiffuse );
+
+   // Colour blending
    float amtgrass = step(qnorm.y,0.6);
+   float amtsand = min(max((aCo.y + 90.0) * -0.08,0.0)*qnorm.y,1.0);
    vec2 uvgradients = vec2( rgarbage.a, -amtgrass*0.125 ) + aUv;
    vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;
-   
+   diffuse = mix( diffuse, vec3(1.0,0.9,0.7), amtsand );
+
+   // Lighting
    vec3 lightdir = vec3(0.95,0.0,-0.3);
    vec3 shadow = pow(vec3(0.014,0.034,0.084),vec3(1.0/3.2));
-   float light1 = 1.0-(dot( lightdir, qnorm )*0.5+0.5);
+   float light1 = dot( lightdir, mix(qnorm,aNorm,amtsand) )*0.5+0.5;
+   diffuse = diffuse * (light1*vec3(1.0,0.96,0.9)*1.2 + shadow*(1.0-light1));
    
-   qnorm = floor(aNorm*8.0)*0.125;
-   vec3 viewdelta = normalize( uCamera - aCo );
+   // Specular lighting
+   vec3 halfview = normalize( uCamera - aCo );
    vec3 specdir = reflect( -lightdir, qnorm );
-   float spec = pow(max(dot(viewdelta,specdir),0.0),10.0) * 0.2*rgarbage.r;
-   
-   diffuse = diffuse*(1.0-light1)+diffuse*shadow*light1;
-   FragColor = vec4(diffuse+spec, 1.0);
+   float spec = pow(max(dot(halfview,specdir),0.0),10.0) * 0.2*rgarbage.r;
+   diffuse += spec * vec3(1.0,0.8,0.8);
+
+   FragColor = vec4(diffuse, water_depth(aCo,halfview,uPlane));
 }
index 0e22487735ffd46a0fa56fe2246f479faabb1653..983e0ba350b100f4b82ebdd68268547639a6d213 100644 (file)
@@ -42,38 +42,54 @@ static struct vg_shader _shader_terrain = {
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexGradients;\n"
 "uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
 "\n"
 "in vec4 aColour;\n"
 "in vec2 aUv;\n"
 "in vec3 aNorm;\n"
 "in vec3 aCo;\n"
 "\n"
+"float water_depth( vec3 pos, vec3 dir, vec4 plane )\n"
+"{\n"
+"   float d = dot( plane.xyz, dir );\n"
+"   float t = dot((plane.xyz*plane.w - pos),plane.xyz) / d;\n"
+"   return t*0.05;\n"
+"}\n"
+"\n"
 "void main()\n"
 "{\n"
 "   vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
+"   \n"
+"   // Creating normal patches\n"
 "   vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
-"   vec3 qnorm = floor(aNorm*4.0+modnorm) * 0.25;\n"
-"\n"
+"   vec3 qnorm = normalize(floor(aNorm*4.0+modnorm) * 0.25);\n"
 "   vec2 dir = normalize(qnorm.xz);\n"
 "   vec2 uvdiffuse = aCo.xz * 0.02;\n"
 "   uvdiffuse = mat2(dir.y, dir.x, -dir.x, dir.y) * uvdiffuse;\n"
-"\n"
+"   \n"
+"   // Patch local noise\n"
 "   vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
+"\n"
+"   // Colour blending\n"
 "   float amtgrass = step(qnorm.y,0.6);\n"
+"   float amtsand = min(max((aCo.y + 90.0) * -0.08,0.0)*qnorm.y,1.0);\n"
 "   vec2 uvgradients = vec2( rgarbage.a, -amtgrass*0.125 ) + aUv;\n"
 "   vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;\n"
-"   \n"
+"   diffuse = mix( diffuse, vec3(1.0,0.9,0.7), amtsand );\n"
+"\n"
+"   // Lighting\n"
 "   vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
 "   vec3 shadow = pow(vec3(0.014,0.034,0.084),vec3(1.0/3.2));\n"
-"   float light1 = 1.0-(dot( lightdir, qnorm )*0.5+0.5);\n"
+"   float light1 = dot( lightdir, mix(qnorm,aNorm,amtsand) )*0.5+0.5;\n"
+"   diffuse = diffuse * (light1*vec3(1.0,0.96,0.9)*1.2 + shadow*(1.0-light1));\n"
 "   \n"
-"   qnorm = floor(aNorm*8.0)*0.125;\n"
-"   vec3 viewdelta = normalize( uCamera - aCo );\n"
+"   // Specular lighting\n"
+"   vec3 halfview = normalize( uCamera - aCo );\n"
 "   vec3 specdir = reflect( -lightdir, qnorm );\n"
-"   float spec = pow(max(dot(viewdelta,specdir),0.0),10.0) * 0.2*rgarbage.r;\n"
-"   \n"
-"   diffuse = diffuse*(1.0-light1)+diffuse*shadow*light1;\n"
-"   FragColor = vec4(diffuse+spec, 1.0);\n"
+"   float spec = pow(max(dot(halfview,specdir),0.0),10.0) * 0.2*rgarbage.r;\n"
+"   diffuse += spec * vec3(1.0,0.8,0.8);\n"
+"\n"
+"   FragColor = vec4(diffuse, water_depth(aCo,halfview,uPlane));\n"
 "}\n"
 ""},
 };
@@ -83,6 +99,7 @@ static GLuint _uniform_terrain_uMdl;
 static GLuint _uniform_terrain_uTexGarbage;
 static GLuint _uniform_terrain_uTexGradients;
 static GLuint _uniform_terrain_uCamera;
+static GLuint _uniform_terrain_uPlane;
 static void shader_terrain_uPv(m4x4f m){
    glUniformMatrix4fv( _uniform_terrain_uPv, 1, GL_FALSE, (float *)m );
 }
@@ -98,6 +115,9 @@ static void shader_terrain_uTexGradients(int i){
 static void shader_terrain_uCamera(v3f v){
    glUniform3fv( _uniform_terrain_uCamera, 1, v );
 }
+static void shader_terrain_uPlane(v4f v){
+   glUniform4fv( _uniform_terrain_uPlane, 1, v );
+}
 static void shader_terrain_register(void){
    vg_shader_register( &_shader_terrain );
 }
@@ -108,5 +128,6 @@ static void shader_terrain_link(void){
    _uniform_terrain_uTexGarbage = glGetUniformLocation( _shader_terrain.id, "uTexGarbage" );
    _uniform_terrain_uTexGradients = glGetUniformLocation( _shader_terrain.id, "uTexGradients" );
    _uniform_terrain_uCamera = glGetUniformLocation( _shader_terrain.id, "uCamera" );
+   _uniform_terrain_uPlane = glGetUniformLocation( _shader_terrain.id, "uPlane" );
 }
 #endif /* SHADER_terrain_H */
index da92d134e8e3bda2c3098b32a88bf3c154190f6e..077a8e68848e0916fa31ca7a8dcb26dba2dfcba6 100644 (file)
@@ -3,32 +3,57 @@ out vec4 FragColor;
 uniform sampler2D uTexMain;
 uniform sampler2D uTexDudv;
 uniform sampler2D uTexDepth;
+uniform sampler2D uTexBack;
+
 uniform vec2 uInvRes;
 uniform float uTime;
 
+uniform vec3 uCamera;
+uniform float uSurfaceY;
+
 in vec4 aUv;
 in vec3 aCo;
+in float aDepth;
 
 void main()
 {
+   // Reflected and warped texture
    vec2 ssuv = gl_FragCoord.xy*uInvRes;
-   vec4 dudva = texture( uTexDudv, aUv.xy + vec2(uTime*0.04f,uTime*0.03f) );
-   vec4 dudvb = texture( uTexDudv, aUv.xy - vec2(uTime*0.1,uTime*0.054) );
 
-   vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;
+   vec4 dudva = texture( uTexDudv, aUv.xy - vec2(uTime*0.004f,uTime*0.003f) );
+   vec4 dudvb = texture( uTexDudv, aUv.xy*0.7 - vec2(uTime*0.01,uTime*0.0054) );
+   vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 0.6;
 
    vec4 reflected = texture( uTexMain, ssuv+distortamt );
+   
+   // Surface colour composite
    float depthvalue = texture( uTexDepth, aUv.zw ).r;
-   float opacity = smoothstep( 0.0, 0.1, depthvalue );
 
-   vec3 colour_shore = vec3( 0.96, 0.98, 0.9 );
-   vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );
-   vec3 surface_tint = mix( colour_shore, colour_ocean, depthvalue );
+   vec3 colour_shore = vec3( 0.21, 0.6, 0.8 );
+   vec3 colour_ocean = vec3( 0.01, 0.1, 0.2 );
+   vec3 surface_tint = mix(colour_shore, colour_ocean, pow(depthvalue,1.8))*1.5;
+   
+   // Foam
+   float fband = fract( aCo.z*0.1+uTime*0.1-depthvalue*10.0 );
+   fband = step( fband+dudvb.g*0.8, 0.5 ) * max((1.0-depthvalue*4.0),0.0);
 
-   vec3 comp_surf = mix(pow(surface_tint,vec3(6.0))*0.6,reflected.rgb, 0.7);
+   // Lighting
+   vec3 surfnorm = vec3(distortamt.x,1.0,distortamt.y);
    
-   float band = fract( aCo.z*0.1+uTime*0.1-depthvalue*10.0 );
-   band = step( band + dudvb.g*0.8, 0.5 ) * max((1.0-depthvalue*4.0),0.0);
+   vec3 halfview = -normalize( aCo-uCamera );
+   float ffresnel = pow(1.0-dot( surfnorm, halfview ),5.0);
 
-   FragColor = vec4(comp_surf + band*0.2,opacity+band*0.2);
+   vec3 lightdir = vec3(0.95,0.0,-0.3);
+   vec3 specdir = reflect( -lightdir, surfnorm );
+   float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;
+   
+   // Depth 
+   vec4 backsample = texture( uTexBack, ssuv+distortamt*0.1 );
+   float depthblend = pow(backsample.a,0.8);
+
+   // Composite
+   vec3 vsurface = mix(surface_tint*backsample.rgb, reflected.rgb, ffresnel );
+   vsurface += spec;
+   
+   FragColor = mix( vec4(vsurface,depthblend), vec4(1.0,1.0,1.0,0.8), fband );
 }
index 85726132fa6472e1d25a4a91fd4e18093f64b3f1..67b07454cbb3eb7a22117bc0d51a49feba8c56de 100644 (file)
@@ -22,6 +22,7 @@ static struct vg_shader _shader_water = {
 "\n"
 "out vec4 aUv;\n"
 "out vec3 aCo;\n"
+"out float aDepth;\n"
 "\n"
 "void main()\n"
 "{\n"
@@ -29,8 +30,10 @@ static struct vg_shader _shader_water = {
 "   gl_Position = uPv * vec4(world_pos,1.0);\n"
 "\n"
 "   vec2 depth_coords = (world_pos.xz-uDepthBounds.xy)*uDepthBounds.zw;\n"
-"   aUv = vec4(world_pos.xz*0.1,depth_coords);\n"
+"   aUv = vec4(world_pos.xz*0.01,depth_coords);\n"
 "   aCo = world_pos;\n"
+"\n"
+"   aDepth = gl_Position.z;\n"
 "}\n"
 ""},
    .fs = 
@@ -42,34 +45,59 @@ static struct vg_shader _shader_water = {
 "uniform sampler2D uTexMain;\n"
 "uniform sampler2D uTexDudv;\n"
 "uniform sampler2D uTexDepth;\n"
+"uniform sampler2D uTexBack;\n"
+"\n"
 "uniform vec2 uInvRes;\n"
 "uniform float uTime;\n"
 "\n"
+"uniform vec3 uCamera;\n"
+"uniform float uSurfaceY;\n"
+"\n"
 "in vec4 aUv;\n"
 "in vec3 aCo;\n"
+"in float aDepth;\n"
 "\n"
 "void main()\n"
 "{\n"
+"   // Reflected and warped texture\n"
 "   vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
-"   vec4 dudva = texture( uTexDudv, aUv.xy + vec2(uTime*0.04f,uTime*0.03f) );\n"
-"   vec4 dudvb = texture( uTexDudv, aUv.xy - vec2(uTime*0.1,uTime*0.054) );\n"
 "\n"
-"   vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;\n"
+"   vec4 dudva = texture( uTexDudv, aUv.xy - vec2(uTime*0.004f,uTime*0.003f) );\n"
+"   vec4 dudvb = texture( uTexDudv, aUv.xy*0.7 - vec2(uTime*0.01,uTime*0.0054) );\n"
+"   vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 0.6;\n"
 "\n"
 "   vec4 reflected = texture( uTexMain, ssuv+distortamt );\n"
+"   \n"
+"   // Surface colour composite\n"
 "   float depthvalue = texture( uTexDepth, aUv.zw ).r;\n"
-"   float opacity = smoothstep( 0.0, 0.1, depthvalue );\n"
 "\n"
-"   vec3 colour_shore = vec3( 0.96, 0.98, 0.9 );\n"
-"   vec3 colour_ocean = vec3( 0.61, 0.84, 0.9 );\n"
-"   vec3 surface_tint = mix( colour_shore, colour_ocean, depthvalue );\n"
+"   vec3 colour_shore = vec3( 0.21, 0.6, 0.8 );\n"
+"   vec3 colour_ocean = vec3( 0.01, 0.1, 0.2 );\n"
+"   vec3 surface_tint = mix(colour_shore, colour_ocean, pow(depthvalue,1.8))*1.5;\n"
+"   \n"
+"   // Foam\n"
+"   float fband = fract( aCo.z*0.1+uTime*0.1-depthvalue*10.0 );\n"
+"   fband = step( fband+dudvb.g*0.8, 0.5 ) * max((1.0-depthvalue*4.0),0.0);\n"
 "\n"
-"   vec3 comp_surf = mix(pow(surface_tint,vec3(6.0))*0.6,reflected.rgb, 0.7);\n"
+"   // Lighting\n"
+"   vec3 surfnorm = vec3(distortamt.x,1.0,distortamt.y);\n"
 "   \n"
-"   float band = fract( aCo.z*0.1+uTime*0.1-depthvalue*10.0 );\n"
-"   band = step( band + dudvb.g*0.8, 0.5 ) * max((1.0-depthvalue*4.0),0.0);\n"
+"   vec3 halfview = -normalize( aCo-uCamera );\n"
+"   float ffresnel = pow(1.0-dot( surfnorm, halfview ),5.0);\n"
 "\n"
-"   FragColor = vec4(comp_surf + band*0.2,opacity+band*0.2);\n"
+"   vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
+"   vec3 specdir = reflect( -lightdir, surfnorm );\n"
+"   float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;\n"
+"   \n"
+"   // Depth \n"
+"   vec4 backsample = texture( uTexBack, ssuv+distortamt*0.1 );\n"
+"   float depthblend = pow(backsample.a,0.8);\n"
+"\n"
+"   // Composite\n"
+"   vec3 vsurface = mix(surface_tint*backsample.rgb, reflected.rgb, ffresnel );\n"
+"   vsurface += spec;\n"
+"   \n"
+"   FragColor = mix( vec4(vsurface,depthblend), vec4(1.0,1.0,1.0,0.8), fband );\n"
 "}\n"
 ""},
 };
@@ -80,8 +108,11 @@ static GLuint _uniform_water_uDepthBounds;
 static GLuint _uniform_water_uTexMain;
 static GLuint _uniform_water_uTexDudv;
 static GLuint _uniform_water_uTexDepth;
+static GLuint _uniform_water_uTexBack;
 static GLuint _uniform_water_uInvRes;
 static GLuint _uniform_water_uTime;
+static GLuint _uniform_water_uCamera;
+static GLuint _uniform_water_uSurfaceY;
 static void shader_water_uPv(m4x4f m){
    glUniformMatrix4fv( _uniform_water_uPv, 1, GL_FALSE, (float *)m );
 }
@@ -100,12 +131,21 @@ static void shader_water_uTexDudv(int i){
 static void shader_water_uTexDepth(int i){
    glUniform1i( _uniform_water_uTexDepth, i );
 }
+static void shader_water_uTexBack(int i){
+   glUniform1i( _uniform_water_uTexBack, i );
+}
 static void shader_water_uInvRes(v2f v){
    glUniform2fv( _uniform_water_uInvRes, 1, v );
 }
 static void shader_water_uTime(float f){
    glUniform1f( _uniform_water_uTime, f );
 }
+static void shader_water_uCamera(v3f v){
+   glUniform3fv( _uniform_water_uCamera, 1, v );
+}
+static void shader_water_uSurfaceY(float f){
+   glUniform1f( _uniform_water_uSurfaceY, f );
+}
 static void shader_water_register(void){
    vg_shader_register( &_shader_water );
 }
@@ -117,7 +157,10 @@ static void shader_water_link(void){
    _uniform_water_uTexMain = glGetUniformLocation( _shader_water.id, "uTexMain" );
    _uniform_water_uTexDudv = glGetUniformLocation( _shader_water.id, "uTexDudv" );
    _uniform_water_uTexDepth = glGetUniformLocation( _shader_water.id, "uTexDepth" );
+   _uniform_water_uTexBack = glGetUniformLocation( _shader_water.id, "uTexBack" );
    _uniform_water_uInvRes = glGetUniformLocation( _shader_water.id, "uInvRes" );
    _uniform_water_uTime = glGetUniformLocation( _shader_water.id, "uTime" );
+   _uniform_water_uCamera = glGetUniformLocation( _shader_water.id, "uCamera" );
+   _uniform_water_uSurfaceY = glGetUniformLocation( _shader_water.id, "uSurfaceY" );
 }
 #endif /* SHADER_water_H */
index 3d6372c57f76f4000bf8fc8811e68160f06d71a4..c8ac51bcefa266db568a8c12b23ad7895c2bdf1a 100644 (file)
@@ -6,6 +6,7 @@ uniform vec4 uDepthBounds;
 
 out vec4 aUv;
 out vec3 aCo;
+out float aDepth;
 
 void main()
 {
@@ -13,6 +14,8 @@ void main()
    gl_Position = uPv * vec4(world_pos,1.0);
 
    vec2 depth_coords = (world_pos.xz-uDepthBounds.xy)*uDepthBounds.zw;
-   aUv = vec4(world_pos.xz*0.1,depth_coords);
+   aUv = vec4(world_pos.xz*0.01,depth_coords);
    aCo = world_pos;
+
+   aDepth = gl_Position.z;
 }
index 3005c93e4ee9620ade79792299e323f7e8e81049..d35dc0ab0f39ffdaa3c57b53bb891d86b48ee124 100644 (file)
--- a/terrain.h
+++ b/terrain.h
@@ -1,10 +1,14 @@
+#include "common.h"
+
+static void render_terrain(m4x4f projection, v3f camera);
+static void render_sky(m4x3f camera);
+
 #ifndef TERRAIN_H
 #define TERRAIN_H
 
-#define VG_3D
-#include "vg/vg.h"
 #include "model.h"
 #include "render.h"
+#include "water.h"
 
 #include "shaders/terrain.h"
 #include "shaders/sky.h"
@@ -52,6 +56,7 @@ static void render_terrain(m4x4f projection, v3f camera)
    shader_terrain_uPv( projection );
    shader_terrain_uMdl( identity_matrix );
    shader_terrain_uCamera( camera );
+   shader_terrain_uPlane( (v4f){ 0.0f,1.0f,0.0f, wrender.height } );
 }
 
 static void render_sky(m4x3f camera)
index 660ec90811cf4811319e43651de7ddf73fa00584..201e051be348de5d38248dcb411fd30b101cb852 100644 (file)
Binary files a/textures/gradients.png and b/textures/gradients.png differ
index 90417f79935f7dc722f12b8fc9c3c00644adfc2f..493f823606544abe08d78a4183c49ee7596f335a 100644 (file)
Binary files a/textures/water_surf.png and b/textures/water_surf.png differ
index 4b305e94e2b91eeb5059db20b0b4cf389de9f428..92fd2e855c88dc9357acef1552859c0d79d138a1 100644 (file)
@@ -20,7 +20,8 @@ static struct button_binding vg_button_binds[] =
 static struct button_binding vg_controller_binds[] = 
 {
    { "push", GLFW_GAMEPAD_BUTTON_A },
-   { "break", GLFW_GAMEPAD_BUTTON_B }
+   { "break", GLFW_GAMEPAD_BUTTON_B },
+   { "switchmode", GLFW_GAMEPAD_BUTTON_Y } 
 };
 
 static struct axis_binding vg_axis_binds[] = 
diff --git a/water.h b/water.h
index 83a6cf82cded97e1fbd334ea525f791b24d705ac..bcd0c6847d44ca840d66b8694840bbe6fbad2351 100644 (file)
--- a/water.h
+++ b/water.h
@@ -1,10 +1,17 @@
+#include "common.h"
+#include "model.h"
+
+static void water_register(void);
+static void water_init(void);
+static void water_fb_resize(void);
+static void water_compute_depth( boxf bounds );
+static void water_set_surface( glmesh *surf, float height );
+static float water_height(void);
+
 #ifndef WATER_H
 #define WATER_H
 
-#define VG_3D
-#include "vg/vg.h"
-
-#include "model.h"
+#include "world.h"
 #include "render.h"
 #include "shaders/water.h"
 #include "scene.h"
@@ -13,7 +20,7 @@ vg_tex2d tex_water_surf = { .path = "textures/water_surf.qoi" };
 
 static struct
 {
-   GLuint fb, rgb, rb;
+   struct framebuffer fbreflect, fbdepth;
    glmesh mdl;
 
    GLuint depthmap;
@@ -23,7 +30,16 @@ static struct
    float height;
    int enabled;
 }
-wrender;
+wrender =
+{
+   .fbreflect = { .format = GL_RGB,  .div = 2 },
+   .fbdepth   = { .format = GL_RGBA, .div = 2 }
+};
+
+static float water_height(void)
+{
+   return wrender.height;
+}
 
 static void water_register(void)
 {
@@ -33,11 +49,21 @@ static void water_register(void)
 static void water_init(void)
 {
    /* TODO: probably dont do this every time */
-   create_renderbuffer_std( &wrender.fb, &wrender.rgb, &wrender.rb );
    wrender.enabled = 1;
+   
+   fb_init( &wrender.fbreflect );
+   fb_init( &wrender.fbdepth );
+}
+
+static void water_fb_resize(void)
+{
+   if( !wrender.enabled )
+      return;
+   
+   fb_resize( &wrender.fbreflect );
+   fb_resize( &wrender.fbdepth );
 }
 
-static int ray_world( v3f pos, v3f dir, ray_hit *hit );
 static void water_compute_depth( boxf bounds )
 {
    if( !wrender.enabled )
@@ -104,22 +130,13 @@ static void water_set_surface( glmesh *surf, float height )
    wrender.height = height;
 }
 
-static void water_fb_resize(void)
-{
-   if( !wrender.enabled )
-      return;
-
-   resize_renderbuffer_std( &wrender.fb, &wrender.rgb, &wrender.rb );
-}
-
 static void render_water_texture( m4x3f camera )
 {
    if( !wrender.enabled )
       return;
 
    /* Draw reflection buffa */
-   glBindFramebuffer( GL_FRAMEBUFFER, wrender.fb );
-   glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
+   fb_use( &wrender.fbreflect );
    glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
 
    m4x3f new_cam, inverse;
@@ -158,9 +175,34 @@ static void render_water_texture( m4x3f camera )
    glCullFace( GL_FRONT );
    render_world( projection, new_cam );
    glCullFace( GL_BACK );
+
+
+   /* Draw beneath texture */
+   fb_use( &wrender.fbdepth );
+   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+
+   m4x3_invert_affine( camera, inverse );
+   m4x3_expand( inverse, view );
+
+   v4f clippb = { 0.0f, -1.0f, 0.0f, -(wrender.height) };
+   m4x3_mulp( inverse, clippb, clippb );
+   clippb[3] *= -1.0f;
+   
+   float depth_loss = camera[3][1]-wrender.height;
+
+   m4x4_projection( projection,
+         gpipeline.fov,
+         (float)vg_window_x / (float)vg_window_y, 
+         0.1f, 900.0f );
+
+   plane_clip_projection( projection, clippb );
+   m4x4_mul( projection, view, projection );
+   render_world( projection, camera );
+   
+   glViewport( 0, 0, vg_window_x, vg_window_y );
 }
 
-static void render_water_surface( m4x4f pv )
+static void render_water_surface( m4x4f pv, m4x3f camera )
 {
    if( !wrender.enabled )
       return;
@@ -168,8 +210,7 @@ static void render_water_surface( m4x4f pv )
    /* Draw surface */
    shader_water_use();
    
-   glActiveTexture( GL_TEXTURE0 );
-   glBindTexture( GL_TEXTURE_2D, wrender.rgb );
+   fb_bindtex( &wrender.fbreflect, 0 );
    shader_water_uTexMain( 0 );
 
    vg_tex2d_bind( &tex_water_surf, 1 );
@@ -187,7 +228,13 @@ static void render_water_surface( m4x4f pv )
          1.0f/ (wrender.depthbounds[1][0]-wrender.depthbounds[0][0]),
          1.0f/ (wrender.depthbounds[1][2]-wrender.depthbounds[0][2])} );
 
+   fb_bindtex( &wrender.fbdepth, 3 );
+   shader_water_uTexBack( 3 );
+
    shader_water_uTime( vg_time );
+   shader_water_uCamera( camera[3] );
+   shader_water_uSurfaceY( wrender.height );
+
    shader_water_uPv( pv );
 
    m4x3f full;
diff --git a/world.h b/world.h
index ea5a5c4b7ec71408b6cd92da2fc545eaa302e8bc..73b42a4c2bbaf45de4a41f5295bf7789f4e5e028 100644 (file)
--- a/world.h
+++ b/world.h
@@ -1,9 +1,10 @@
+#include "common.h"
+
+static int ray_world( v3f pos, v3f dir, ray_hit *hit );
+
 #ifndef WORLD_H
 #define WORLD_H
 
-#define VG_3D
-#include "vg/vg.h"
-
 #include "scene.h"
 #include "terrain.h"
 #include "render.h"
@@ -22,10 +23,6 @@ static struct gworld
 
    v3f tutorial;
 
-#if 0
-   rigidbody box;
-#endif
-
    teleport_gate gates[16];
    u32 gate_count;
    
@@ -69,7 +66,6 @@ static int ray_hit_is_ramp( ray_hit *hit )
    return hit->tri[0] < world.sm_road.vertex_count;
 }
 
-static bh_system bh_system_rigidbodies;
 static void world_load(void)
 {
    /* Setup scene */
@@ -207,7 +203,7 @@ static void world_load(void)
       if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
       {
          if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
-             hit.pos[1] > wrender.height )
+             hit.pos[1] > water_height()+10.0f )
          {
             v4f qsurface, qrandom;
             v3f axis;
@@ -222,7 +218,7 @@ static void world_load(void)
 
             v3_copy( hit.pos, transform[3] );
             
-            if( vg_randf() < 0.00000006f )
+            if( vg_randf() < 0.0006f )
             {
                m3x3_identity( transform );
                scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform);