CHGICKEN
authorhgn <hgodden00@gmail.com>
Mon, 20 Jun 2022 22:39:20 +0000 (23:39 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 20 Jun 2022 22:39:20 +0000 (23:39 +0100)
19 files changed:
character.h
gate.h
main.c
render.h
rigidbody.h
scene.h
shaders/sky.fs [new file with mode: 0644]
shaders/sky.h [new file with mode: 0644]
shaders/terrain.fs
shaders/terrain.h
shaders/terrain.vs
shaders/water.fs
shaders/water.h
terrain.h
textures/garbage.png [new file with mode: 0644]
textures/gradients.png
vg.conf
water.h
world.h [new file with mode: 0644]

index f86830a7838964f79726733e03e29a2eefa64aed..6a3a26b0764ef4e06babb3e6ca0ca84ca280858e 100644 (file)
@@ -823,12 +823,10 @@ static void character_debug_ragdoll( struct character *ch )
    rb_debug( &ch->ragdoll[k_chpart_foot_r], 0xff00a5ff );
 }
 
-static void character_ragdoll_iter( struct character *ch, scene *sc )
+static void character_ragdoll_iter( struct character *ch )
 {
    for( int i=0; i<PART_COUNT; i++ )
-   {
-      rb_build_manifold( &ch->ragdoll[i], sc );
-   }
+      rb_build_manifold( &ch->ragdoll[i] );
 
    v3f rv;
 
diff --git a/gate.h b/gate.h
index 65dda90b275ced92e690c7e95654953d89dd2203..2f2b21ef096246537863ad80e2209b08cb9b1ac5 100644 (file)
--- a/gate.h
+++ b/gate.h
@@ -66,9 +66,9 @@ static void gate_init( void (*newfb)(GLuint*,GLuint*,GLuint*) )
    free( mgate );
 }
 
-static void gate_fb_resize( void (*resize)(GLuint*,GLuint*,GLuint*) )
+static void gate_fb_resize(void)
 {
-   resize( &grender.fb, &grender.rgb, &grender.rb );
+   resize_renderbuffer_std( &grender.fb, &grender.rgb, &grender.rb );
 }
 
 static void render_gate( teleport_gate *gate, m4x3f camera )
@@ -125,10 +125,7 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
    surface[3] = v3_dot( surface, gate->other->co );
 
    m4x4f projection;
-   m4x4_projection( projection,
-         gpipeline.fov,
-         (float)vg_window_x / (float)vg_window_y, 
-         0.1f, 900.0f );
+   pipeline_projection( projection, 0.1f, 900.0f );
 
 #if 0 /* For debugging frustum */
    {
@@ -198,7 +195,7 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
 
    m4x4_mul( projection, view, projection );
    
-   render_world( projection );
+   render_world( projection, cam_new );
    render_water_texture( cam_new );
    glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
    render_water_surface( projection );
diff --git a/main.c b/main.c
index 57728587415bb3237d8a9a668c5459fa6cdaff7a..aef6dabf24c49d8e46008c94410a79ed1a449f5e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -31,13 +31,14 @@ static int replay_buffer_frame = 0;
 #include "road.h"
 #include "scene.h"
 #include "ik.h"
-#include "character.h"
 #include "terrain.h"
+#include "character.h"
 #include "ragdoll.h"
 #include "rigidbody.h"
 #include "render.h"
 #include "gate.h"
 #include "water.h"
+#include "world.h"
 
 #include "shaders/blit.h"
 #include "shaders/standard.h"
@@ -110,15 +111,6 @@ static struct gplayer
 }
 player;
 
-static struct gworld
-{
-   scene geo;
-   submodel sm_road, sm_terrain;
-   glmesh skybox;
-
-   v3f tutorial;
-}
-world;
 
 static struct grender
 {
@@ -129,6 +121,7 @@ static struct grender
 }
 render;
 
+#if 0
 rigidbody mr_box = {
    .bbx = {{ -1.0f, -0.25f, -0.25f }, { 1.0f, 0.25f, 0.25f }}
 };
@@ -145,6 +138,7 @@ gate_b = {
    .co = { -8.0f, -3.0f, -17.0f },
    .q = { 0.0f, 0.0f, 0.0f, 1.0f }
 };
+#endif
 
 static void player_transform_update(void)
 {
@@ -192,42 +186,6 @@ static int playermodel( int argc, char const *argv[] )
    return 1;
 }
 
-static void create_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
-{
-   glGenFramebuffers( 1, fb );
-   glBindFramebuffer( GL_FRAMEBUFFER, *fb );
-
-   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);
-
-   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);
-
-   /* 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 );
-
-   glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-         GL_RENDERBUFFER, *rb );
-}
-
-static void resize_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
-{
-   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 );
-
-   glBindRenderbuffer( GL_RENDERBUFFER, *rb );
-   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 
-         vg_window_x, vg_window_y );
-}
 
 void vg_start(void)
 {
@@ -235,9 +193,11 @@ void vg_start(void)
 
    vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
 
+#if 0
    rb_init( &mr_box );
    rb_init( &mrs_box );
    mrs_box.co[2] += 2.0f;
+#endif
 
    vg_convar_push( (struct vg_convar){
       .name = "frame",
@@ -322,58 +282,7 @@ void vg_start(void)
    character_load( &player.mdl, "ch_default" );
    character_init_ragdoll( &player.mdl );
    
-   /* Setup scene */
-   scene_init( &world.geo );
-   model *mworld = vg_asset_read( "models/mp_dev.mdl" );
-
-   scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ),
-         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
-   scene_copy_slice( &world.geo, &world.sm_road );
-
-   scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ),
-         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
-   scene_copy_slice( &world.geo, &world.sm_terrain );
-
-   v3_copy( model_marker_get( mworld, "mp_dev_tutorial" )->co, world.tutorial );
-
-
-   /* GATE DEV */
-   {
-      model_marker *ga = model_marker_get(mworld,"gate_a"),
-                   *gb = model_marker_get(mworld,"gate_a_recv");
-
-      v3_copy( ga->co, gate_a.co );
-      v3_copy( gb->co, gate_b.co );
-      v4_copy( ga->q, gate_a.q );
-      v4_copy( gb->q, gate_b.q );
-      v2_copy( ga->s, gate_a.dims );
-      v2_copy( gb->s, gate_b.dims );
-
-      gate_a.other = &gate_b;
-      gate_b.other = &gate_a;
-
-      gate_transform_update( &gate_a );
-      gate_transform_update( &gate_b );
-   }
-
-   /* WATER DEV */
-   {
-      glmesh surf;
-      submodel *sm = submodel_get(mworld,"mp_dev_water");
-      model_unpack_submodel( mworld, &surf, sm );
-            
-      water_init( create_renderbuffer_std );
-      water_set_surface( &surf, sm->pivot[1] );
-   }
-   {
-      model *msky = vg_asset_read("models/rs_skydome.mdl");
-      model_unpack( msky, &world.skybox );
-      free(msky);
-   }
-
-   free( mworld );
-   scene_upload( &world.geo );
-   bvh_create( &world.geo );
+   world_init_default();
 
    reset_player( 1, (const char *[]){ "tutorial" } );
    player_transform_update();
@@ -394,6 +303,7 @@ void vg_start(void)
          render.rgb_background, 0);
 
    gate_init( create_renderbuffer_std );
+   terrain_init();
 
    {
       float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
@@ -427,7 +337,7 @@ static void player_freecam(void)
    m4x3_mulv( cam_rot, lookdir, lookdir );
    m4x3_mulv( cam_rot, sidedir, sidedir );
    
-   float movespeed = 5.0f;
+   float movespeed = 15.0f;
    static v2f mouse_last,
               view_vel = { 0.0f, 0.0f };
 
@@ -468,11 +378,6 @@ static void apply_gravity( v3f vel, float const timestep )
    v3_muladds( vel, gravity, timestep, vel );
 }
 
-static int ray_hit_is_ramp( ray_hit *hit )
-{
-   return hit->tri[0] < world.sm_road.vertex_count;
-}
-
 static void player_start_air(void)
 {
    player.in_air = 1;
@@ -526,7 +431,7 @@ static void player_start_air(void)
          contact.dist = v3_length( vdir );
          v3_divs( vdir, contact.dist, vdir);
 
-         if( bvh_raycast( &world.geo, pco1, vdir, &contact ))
+         if( ray_world( pco1, vdir, &contact ))
          {
             float land_delta = v3_dot( pv, contact.normal );
             u32 scolour = (u8)(vg_minf(-land_delta * 2.0f, 255.0f));
@@ -571,9 +476,12 @@ static int sample_if_resistant( v3f pos )
 {
    v3f ground;
    v3_copy( pos, ground );
+   ground[1] += 4.0f;
    
    ray_hit hit;
-   if( bvh_scene_sample( &world.geo, ground, &hit ) )
+   hit.dist = INFINITY;
+
+   if( ray_world( ground, (v3f){0.0f,-1.0f,0.0f}, &hit ))
    {
       v3f angle;
       v3_copy( player.v, angle );
@@ -582,7 +490,7 @@ static int sample_if_resistant( v3f pos )
 
       if( resistance < 0.25f )
       {
-         v3_copy( ground, pos );
+         v3_copy( hit.pos, pos );
          return 1;
       }
    }
@@ -748,11 +656,13 @@ static void player_physics_air(void)
 
    v3f ground_pos;
    v3_copy( player.co, ground_pos );
+   ground_pos[1] += 4.0f;
    
    ray_hit hit;
-   if( bvh_scene_sample( &world.geo, ground_pos, &hit ) )
+   hit.dist = INFINITY;
+   if( ray_world( ground_pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
    {
-      if( ground_pos[1] > player.co[1] )
+      if( hit.pos[1] > player.co[1] )
       {
          player.in_air = 0;
          
@@ -796,7 +706,7 @@ static void player_physics_air(void)
       v3_divs( vdir, contact.dist, vdir);
       
       float orig_dist = contact.dist;
-      if( bvh_raycast( &world.geo, pco1, vdir, &contact ))
+      if( ray_world( pco1, vdir, &contact ))
       {
          v3f localup;
          m3x3_mulv( player.to_world, (v3f){0.0f,1.0f,0.0f}, localup );
@@ -905,6 +815,7 @@ static void player_update(void)
 
    player.iY = 0.0f; /* temp */
 
+#if 0
    /* GATE COLLISION */
    if( gate_intersect( &gate_a, player.co, prevco ) )
    {
@@ -922,6 +833,7 @@ static void player_update(void)
       m3x3_q( transport, transport_rotation );
       q_mul( transport_rotation, player.rot, player.rot );
    }
+#endif
 
    /* Camera and character */
    player_transform_update();
@@ -956,8 +868,9 @@ void vg_update(void)
       character_debug_ragdoll( &player.mdl );
 
       if( player.is_dead )
-         character_ragdoll_iter( &player.mdl, &world.geo );
+         character_ragdoll_iter( &player.mdl );
 
+#if 0
       rb_build_manifold( &mr_box, &world.geo );
       rb_build_manifold( &mrs_box, &world.geo );
       rb_constraint_manifold( &mr_box );
@@ -971,6 +884,7 @@ void vg_update(void)
 
       rb_update_transform( &mr_box );
       rb_update_transform( &mrs_box );
+#endif
 
       clock = 0;
    }
@@ -1193,40 +1107,8 @@ static void vg_framebuffer_resize( int w, int h )
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, 
          GL_RGB, GL_UNSIGNED_BYTE, NULL );
 
-   gate_fb_resize( resize_renderbuffer_std );
-   water_fb_resize( resize_renderbuffer_std );
-}
-
-static void render_world( m4x4f projection )
-{
-   m4x3f identity_matrix;
-   m4x3_identity( identity_matrix );
-
-   shader_unlit_use();
-   shader_unlit_uPv( projection );
-   shader_unlit_uTexMain( 0 );
-   vg_tex2d_bind( &tex_sky, 0 );
-   
-   glDepthMask(GL_FALSE);
-   glDisable(GL_DEPTH_TEST);
-
-   mesh_bind( &world.skybox );
-   mesh_draw( &world.skybox );
-
-   glEnable(GL_DEPTH_TEST);
-   glDepthMask(GL_TRUE);
-
-   
-   shader_standard_use();
-   shader_standard_uPv( projection );
-   shader_standard_uMdl( identity_matrix );
-
-   vg_tex2d_bind( &tex_grid, 0 );
-   shader_standard_uTexMain( 0 );
-   shader_standard_uColour( (v4f){0.4f,0.4f,0.4f,1.0f} );
-
-   scene_bind( &world.geo );
-   scene_draw( &world.geo );
+   gate_fb_resize();
+   water_fb_resize();
 }
 
 void vg_render(void) 
@@ -1308,7 +1190,7 @@ void vg_render(void)
    gpipeline.fov = freecam? 60.0f: 120.0f;
    m4x4_projection( vg_pv, gpipeline.fov, 
          (float)vg_window_x / (float)vg_window_y, 
-         0.1f, 1000.0f );
+         0.025f, 1000.0f );
 
    m4x4_mul( vg_pv, world_4x4, vg_pv );
 
@@ -1325,14 +1207,16 @@ void vg_render(void)
    m4x3f cam_transform;
    m4x3_invert_affine( world_matrix, cam_transform );
 
-   render_world( vg_pv );
+   render_world( vg_pv, cam_transform );
    render_water_texture( cam_transform );
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    render_water_surface( vg_pv );
 
+#if 0
    vg_tex2d_bind( &tex_water, 1 );
    render_gate( &gate_a, cam_transform );
+#endif
 
    
    /* Copy the RGB of what we have into the background buffer */
index 0abbdae0ce9f07a78b3b8c964fd38abf67117f53..493ed3b6d4520c8954bc7860e4702c28fb9b9893 100644 (file)
--- a/render.h
+++ b/render.h
@@ -11,7 +11,7 @@ gpipeline;
 
 static void render_water_texture( m4x3f camera );
 static void render_water_surface( m4x4f pv );
-static void render_world( m4x4f pv );
+static void render_world( m4x4f projection, m4x3f camera );
 
 /* 
  * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf 
@@ -34,4 +34,49 @@ static void plane_clip_projection( m4x4f mat, v4f plane )
    mat[3][2] = c[3];
 }
 
+static void pipeline_projection( m4x4f mat, float nearz, float farz )
+{
+   m4x4_projection( mat,
+         gpipeline.fov,
+         (float)vg_window_x / (float)vg_window_y, 
+         nearz, farz );
+}
+
+static void create_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
+{
+   glGenFramebuffers( 1, fb );
+   glBindFramebuffer( GL_FRAMEBUFFER, *fb );
+
+   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);
+
+   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);
+
+   /* 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 );
+
+   glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+         GL_RENDERBUFFER, *rb );
+}
+
+static void resize_renderbuffer_std( GLuint *fb, GLuint *rgb, GLuint *rb )
+{
+   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 );
+
+   glBindRenderbuffer( GL_RENDERBUFFER, *rb );
+   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 
+         vg_window_x, vg_window_y );
+}
+
 #endif /* RENDER_H */
index 4318d8c1f294d117622c5421b840b239b2b74134..01734e8f2d74760ab32659165a1a51c633a4785c 100644 (file)
@@ -3,13 +3,15 @@
  *            qu3e  - Randy Gaul
  */
 
+#include "vg/vg.h"
+static void rb_tangent_basis( v3f n, v3f tx, v3f ty );
+
 #ifndef RIGIDBODY_H
 #define RIGIDBODY_H
 
 #define RB_DEPR 
 
-#include "vg/vg.h"
-#include "scene.h"
+#include "world.h"
 
 #define k_rb_delta (1.0f/60.0f)
 
@@ -106,7 +108,7 @@ static void rb_tangent_basis( v3f n, v3f tx, v3f ty )
    v3_cross( n, tx, ty );
 }
 
-static void rb_build_manifold( rigidbody *rb, scene *sc )
+static void rb_build_manifold( rigidbody *rb )
 {
    v3f *box = rb->bbx;
    v3f pts[8]; 
@@ -140,12 +142,16 @@ static void rb_build_manifold( rigidbody *rb, scene *sc )
       struct contact *ct = &rb->manifold[rb->manifold_count];
       
       v3f surface;
-
       v3_copy( point, surface );
+      surface[1] += 4.0f;
 
       ray_hit hit;
-      bvh_scene_sample( sc, surface, &hit );
+      hit.dist = INFINITY;
+      if( !ray_world( surface, (v3f){0.0f,-1.0f,0.0f}, &hit ))
+         continue;
+
       v3_copy( hit.normal, ct->n );
+      v3_copy( hit.pos, surface );
 
       float p = vg_minf( surface[1] - point[1], 1.0f );
 
diff --git a/scene.h b/scene.h
index af24b6cee41cb4c2739407d13af486a9737e4a9b..ff970007dfb5fce17dbfc9c03f2a3be2b27c9bbb 100644 (file)
--- a/scene.h
+++ b/scene.h
@@ -181,6 +181,50 @@ static void scene_add_model( scene *pscene, model *mdl, submodel *submodel,
    pscene->indice_count += submodel->indice_count;
 }
 
+static void scene_add_foliage( scene *pscene, model *mdl, submodel *submodel,
+      m4x3f transform )
+{
+   pscene->verts = buffer_reserve( pscene->verts, pscene->vertex_count, 
+         &pscene->vertex_cap, submodel->vertex_count, sizeof(model_vert) );
+   pscene->indices = buffer_reserve( pscene->indices, pscene->indice_count,
+         &pscene->indice_cap, submodel->indice_count, sizeof(u32) );
+   
+   /* Transform and place vertices */
+   model_vert *src_verts = submodel_vert_data( mdl, submodel );
+   u32 *src_indices = submodel_indice_data( mdl, submodel );
+   
+   boxf bbxnew;
+   box_copy( submodel->bbx, bbxnew );
+   m4x3_transform_aabb( transform, bbxnew );
+   box_concat( pscene->bbx, bbxnew );
+   
+   float rand_hue = vg_randf();
+   for( u32 i=0; i<submodel->vertex_count; i++ )
+   {
+      model_vert *pvert = &pscene->verts[ pscene->vertex_count+i ],
+                 *src = &src_verts[ i ];
+
+      m4x3_mulv( transform, src->co, pvert->co );
+      m3x3_mulv( transform, src->norm, pvert->norm );
+
+      v4_copy( src->colour, pvert->colour );
+      v2_copy( src->uv, pvert->uv );
+      
+      float rel_y = src->co[1] / submodel->bbx[1][1];
+      pvert->colour[0] = rel_y;
+      pvert->colour[2] = rand_hue;
+   }
+
+   for( u32 i=0; i<submodel->indice_count; i++ )
+   {
+      u32 *pidx = &pscene->indices[ pscene->indice_count+i ];
+      *pidx = src_indices[i] + pscene->vertex_count;
+   }
+
+   pscene->vertex_count += submodel->vertex_count;
+   pscene->indice_count += submodel->indice_count;
+}
+
 static void scene_copy_slice( scene *pscene, submodel *sm )
 {
    sm->indice_start = pscene->submesh.indice_start;
diff --git a/shaders/sky.fs b/shaders/sky.fs
new file mode 100644 (file)
index 0000000..b8d4fc7
--- /dev/null
@@ -0,0 +1,20 @@
+out vec4 FragColor;
+
+uniform vec4 uColour;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+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);
+   vec3 diffuse = mix( skycolour, horizon, fblend );
+
+   FragColor = vec4(diffuse,1.0);
+}
diff --git a/shaders/sky.h b/shaders/sky.h
new file mode 100644 (file)
index 0000000..55a2046
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef SHADER_sky_H
+#define SHADER_sky_H
+static void shader_sky_link(void);
+static void shader_sky_register(void);
+static struct vg_shader _shader_sky = {
+   .name = "sky",
+   .link = shader_sky_link,
+   .vs = 
+{
+.orig_file = "../shaders/standard.vs",
+.static_src = 
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line      2        0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );\n"
+"   aColour = a_colour;\n"
+"   aUv = a_uv;\n"
+"   aNorm = mat3(uMdl) * a_norm;\n"
+"   aCo = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "../shaders/sky.fs",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"\n"
+"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"
+"   vec3 diffuse = mix( skycolour, horizon, fblend );\n"
+"\n"
+"   FragColor = vec4(diffuse,1.0);\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_sky_uPv;
+static GLuint _uniform_sky_uMdl;
+static GLuint _uniform_sky_uColour;
+static void shader_sky_uPv(m4x4f m){
+   glUniformMatrix4fv( _uniform_sky_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_sky_uMdl(m4x3f m){
+   glUniformMatrix4x3fv( _uniform_sky_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_sky_uColour(v4f v){
+   glUniform4fv( _uniform_sky_uColour, 1, v );
+}
+static void shader_sky_register(void){
+   vg_shader_register( &_shader_sky );
+}
+static void shader_sky_use(void){ glUseProgram(_shader_sky.id); }
+static void shader_sky_link(void){
+   _uniform_sky_uPv = glGetUniformLocation( _shader_sky.id, "uPv" );
+   _uniform_sky_uMdl = glGetUniformLocation( _shader_sky.id, "uMdl" );
+   _uniform_sky_uColour = glGetUniformLocation( _shader_sky.id, "uColour" );
+}
+#endif /* SHADER_sky_H */
index 04751e9ec45ae40c4e3f1c76573d22f5f5ba514d..10e5d9d524a9cb40e23ddb9d050b04f7180e3281 100644 (file)
@@ -1,6 +1,30 @@
-#include "common.glsl"
+out vec4 FragColor;
+
+uniform sampler2D uTexGarbage;
+uniform sampler2D uTexGradients;
+
+in vec4 aColour;
+in vec2 aUv;
+in vec3 aNorm;
+in vec3 aCo;
 
 void main()
 {
+   vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );
+   vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;
+   vec3 qnorm = 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;
+
+   vec4 rgarbage = texture( uTexGarbage, uvdiffuse );
+   float amtgrass = step(qnorm.y,0.6);
+   vec2 uvgradients = vec2( rgarbage.a, -amtgrass*0.125 ) + aUv;
+   vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;
+   
+   vec3 shadow = pow(vec3(0.014,0.034,0.084),vec3(1.0/3.2));
+   float light1 = 1.0-(dot( vec3(0.95,0.0,-0.3), qnorm )*0.5+0.5);
 
+   FragColor = vec4(diffuse*(1.0-light1)+diffuse*shadow*light1, 1.0);
 }
index e10d371293468abb2aac8c0a1f86729803cb5803..42e87aa62a98397ac40339c4c8503fa48b2943bf 100644 (file)
@@ -9,37 +9,91 @@ static struct vg_shader _shader_terrain = {
 {
 .orig_file = "../shaders/terrain.vs",
 .static_src = 
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line      2        0 \n"
+"\n"
+"uniform mat4 uPv;\n"
 "uniform mat4x3 uMdl;\n"
 "\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"\n"
 "void main()\n"
 "{\n"
-"\n"
+"   gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );\n"
+"   aColour = a_colour;\n"
+"   aUv = a_uv;\n"
+"   aNorm = mat3(uMdl) * a_norm;\n"
+"   aCo = a_co;\n"
 "}\n"
 ""},
    .fs = 
 {
 .orig_file = "../shaders/terrain.fs",
 .static_src = 
-"// Nothing\n"
+"out vec4 FragColor;\n"
 "\n"
-"#line      2        0 \n"
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexGradients;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
 "\n"
 "void main()\n"
 "{\n"
+"   vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
+"   vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
+"   vec3 qnorm = floor(aNorm*4.0+modnorm) * 0.25;\n"
+"\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"
+"   vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
+"   float amtgrass = step(qnorm.y,0.6);\n"
+"   vec2 uvgradients = vec2( rgarbage.a, -amtgrass*0.125 ) + aUv;\n"
+"   vec3 diffuse = texture( uTexGradients, uvgradients ).rgb;\n"
+"   \n"
+"   vec3 shadow = pow(vec3(0.014,0.034,0.084),vec3(1.0/3.2));\n"
+"   float light1 = 1.0-(dot( vec3(0.95,0.0,-0.3), qnorm )*0.5+0.5);\n"
 "\n"
+"   FragColor = vec4(diffuse*(1.0-light1)+diffuse*shadow*light1, 1.0);\n"
 "}\n"
 ""},
 };
 
+static GLuint _uniform_terrain_uPv;
 static GLuint _uniform_terrain_uMdl;
+static GLuint _uniform_terrain_uTexGarbage;
+static GLuint _uniform_terrain_uTexGradients;
+static void shader_terrain_uPv(m4x4f m){
+   glUniformMatrix4fv( _uniform_terrain_uPv, 1, GL_FALSE, (float *)m );
+}
 static void shader_terrain_uMdl(m4x3f m){
    glUniformMatrix4x3fv( _uniform_terrain_uMdl, 1, GL_FALSE, (float *)m );
 }
+static void shader_terrain_uTexGarbage(int i){
+   glUniform1i( _uniform_terrain_uTexGarbage, i );
+}
+static void shader_terrain_uTexGradients(int i){
+   glUniform1i( _uniform_terrain_uTexGradients, i );
+}
 static void shader_terrain_register(void){
    vg_shader_register( &_shader_terrain );
 }
 static void shader_terrain_use(void){ glUseProgram(_shader_terrain.id); }
 static void shader_terrain_link(void){
+   _uniform_terrain_uPv = glGetUniformLocation( _shader_terrain.id, "uPv" );
    _uniform_terrain_uMdl = glGetUniformLocation( _shader_terrain.id, "uMdl" );
+   _uniform_terrain_uTexGarbage = glGetUniformLocation( _shader_terrain.id, "uTexGarbage" );
+   _uniform_terrain_uTexGradients = glGetUniformLocation( _shader_terrain.id, "uTexGradients" );
 }
 #endif /* SHADER_terrain_H */
index 5bb262bc0ba07a032b20b9a7c6a446759bb144c0..db7f98033ae326ee291becfb969556d2746c0fb1 100644 (file)
@@ -1,6 +1,18 @@
+#include "vertex_standard.glsl"
+
+uniform mat4 uPv;
 uniform mat4x3 uMdl;
 
+out vec4 aColour;
+out vec2 aUv;
+out vec3 aNorm;
+out vec3 aCo;
+
 void main()
 {
-
+   gl_Position = uPv * vec4( uMdl * vec4(a_co,1.0), 1.0 );
+   aColour = a_colour;
+   aUv = a_uv;
+   aNorm = mat3(uMdl) * a_norm;
+   aCo = a_co;
 }
index a8220a4446716f7e804878935be5dd0d4efefe80..b352e39922ed6edb04894f9f285cba99dad9130c 100644 (file)
@@ -16,5 +16,5 @@ void main()
    vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;
 
    vec4 reflected = texture( uTexMain, ssuv+distortamt );
-   FragColor = vec4(reflected.rgb*0.9,reflected.a);
+   FragColor = vec4(reflected.rgb*1.0,reflected.a);
 }
index 749067ed1e1d622ba8b08a4fbc3fae7308de149b..e50253c9854de1bf6d232e375385c186c646d426 100644 (file)
@@ -50,7 +50,7 @@ static struct vg_shader _shader_water = {
 "   vec2 distortamt = (dudva.rg-0.5) * (dudvb.ba-0.5) * 2.0;\n"
 "\n"
 "   vec4 reflected = texture( uTexMain, ssuv+distortamt );\n"
-"   FragColor = vec4(reflected.rgb*0.1,reflected.a);\n"
+"   FragColor = vec4(reflected.rgb*1.0,reflected.a);\n"
 "}\n"
 ""},
 };
index 22b27231815447db6d6f41ec9b7e2a8fd174434b..739fb75633fbaac3e5cc95e186578eb4c36675f0 100644 (file)
--- a/terrain.h
+++ b/terrain.h
@@ -7,15 +7,78 @@
 #include "render.h"
 
 #include "shaders/terrain.h"
+#include "shaders/sky.h"
+
+vg_tex2d tex_terrain_colours = { .path = "textures/gradients.qoi",
+                                 .flags = VG_TEXTURE_CLAMP | VG_TEXTURE_NEAREST
+};
+vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
+                                 .flags = VG_TEXTURE_NEAREST };
+
+static struct
+{
+   glmesh skydome;
+}
+trender;
 
 static void terrain_register(void)
 {
    shader_terrain_register();
+   shader_sky_register();
+}
+
+static void terrain_init(void)
+{
+   vg_tex2d_init( (vg_tex2d *[]){ &tex_terrain_colours, 
+                                  &tex_terrain_noise }, 2 );
+
+
+   model *msky = vg_asset_read("models/rs_skydome.mdl");
+   model_unpack( msky, &trender.skydome );
+   free(msky);
 }
 
-void test(void)
+static void render_terrain(m4x4f projection)
 {
+   shader_terrain_use();
+   shader_terrain_uTexGarbage(0);
+   shader_terrain_uTexGradients(1);
+
+   vg_tex2d_bind( &tex_terrain_noise, 0 );
+   vg_tex2d_bind( &tex_terrain_colours, 1 );
+
+   m4x3f identity_matrix;
+   m4x3_identity( identity_matrix );
+   shader_terrain_uPv( projection );
+   shader_terrain_uMdl( identity_matrix );
+}
+
+static void render_sky(m4x3f camera)
+{
+   m4x4f projection, full;
+   pipeline_projection( projection, 0.4f, 1000.0f );
+
+   m4x3f inverse;
+   m3x3_transpose( camera, inverse );
+   v3_copy((v3f){0.0f,0.0f,0.0f}, inverse[3]);
+   m4x3_expand( inverse, full );
+   m4x4_mul( projection, full, full );
+
+   m4x3f identity_matrix;
+   m4x3_identity( identity_matrix );
    
+   shader_sky_use();
+   shader_sky_uMdl(identity_matrix);
+   shader_sky_uPv(full);
+
+   glDepthMask(GL_FALSE);
+   glDisable(GL_DEPTH_TEST);
+
+   mesh_bind( &trender.skydome );
+   mesh_draw( &trender.skydome );
+
+   glEnable(GL_DEPTH_TEST);
+   glDepthMask(GL_TRUE);
 }
 
 #endif
diff --git a/textures/garbage.png b/textures/garbage.png
new file mode 100644 (file)
index 0000000..705b8da
Binary files /dev/null and b/textures/garbage.png differ
index f596bf6e48eecde007d93e621843624b892c6556..660ec90811cf4811319e43651de7ddf73fa00584 100644 (file)
Binary files a/textures/gradients.png and b/textures/gradients.png differ
diff --git a/vg.conf b/vg.conf
index 5453b236c4cdc3cf01d5c4979653f57edb920db4..e383b597abdcd4cb43551e051acbe16b0ed10184 100644 (file)
--- a/vg.conf
+++ b/vg.conf
@@ -8,3 +8,4 @@ shader unlit standard.vs unlit.fs
 shader character character.vs character.fs
 shader gate gate.vs gate.fs
 shader water water.vs water.fs
+shader sky standard.vs sky.fs
diff --git a/water.h b/water.h
index 94c7b34d0a332c782e58b581f46bca735367e9a7..957f2021c3cfedc7b34513dd8b503ad027b31f96 100644 (file)
--- a/water.h
+++ b/water.h
@@ -24,9 +24,9 @@ static void water_register(void)
    shader_water_register();
 }
 
-static void water_init( void (*newfb)(GLuint*,GLuint*,GLuint*))
+static void water_init(void)
 {
-   newfb( &wrender.fb, &wrender.rgb, &wrender.rb );
+   create_renderbuffer_std( &wrender.fb, &wrender.rgb, &wrender.rb );
 }
 
 static void water_set_surface( glmesh *surf, float height )
@@ -35,9 +35,9 @@ static void water_set_surface( glmesh *surf, float height )
    wrender.height = height;
 }
 
-static void water_fb_resize( void (*resize)(GLuint*,GLuint*,GLuint*) )
+static void water_fb_resize(void)
 {
-   resize( &wrender.fb, &wrender.rgb, &wrender.fb );
+   resize_renderbuffer_std( &wrender.fb, &wrender.rgb, &wrender.rb );
 }
 
 static void render_water_texture( m4x3f camera )
@@ -81,7 +81,7 @@ static void render_water_texture( m4x3f camera )
    m4x4_mul( projection, view, projection );
 
    glCullFace( GL_FRONT );
-   render_world( projection );
+   render_world( projection, new_cam );
    glCullFace( GL_BACK );
 }
 
diff --git a/world.h b/world.h
new file mode 100644 (file)
index 0000000..cdf2f16
--- /dev/null
+++ b/world.h
@@ -0,0 +1,150 @@
+#ifndef WORLD_H
+#define WORLD_H
+
+#define VG_3D
+#include "vg/vg.h"
+
+#include "scene.h"
+#include "terrain.h"
+#include "render.h"
+#include "water.h"
+
+#include "shaders/standard.h"
+
+static struct gworld
+{
+   scene geo, foliage;
+   submodel sm_road, sm_terrain;
+   glmesh skybox;
+
+   v3f tutorial;
+}
+world;
+
+static void render_world( m4x4f projection, m4x3f camera )
+{
+   render_sky( camera );
+
+   m4x3f identity_matrix;
+   m4x3_identity( identity_matrix );
+
+   render_terrain( projection );
+   scene_bind( &world.geo );
+   scene_draw( &world.geo );
+
+   glDisable(GL_CULL_FACE);
+   scene_bind( &world.foliage );
+   scene_draw( &world.foliage );
+   glEnable(GL_CULL_FACE);
+}
+
+static int ray_world( v3f pos, v3f dir, ray_hit *hit )
+{
+   return bvh_raycast( &world.geo, pos, dir, hit );
+}
+
+static int ray_hit_is_ramp( ray_hit *hit )
+{
+   return hit->tri[0] < world.sm_road.vertex_count;
+}
+
+static void world_init_default(void)
+{
+   /* Setup scene */
+   scene_init( &world.geo );
+   model *mworld = vg_asset_read( "models/mp_dev.mdl" );
+
+   scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ),
+         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
+   scene_copy_slice( &world.geo, &world.sm_road );
+
+   scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ),
+         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
+   scene_copy_slice( &world.geo, &world.sm_terrain );
+
+   v3_copy( model_marker_get( mworld, "mp_dev_tutorial" )->co, world.tutorial );
+
+
+   /* GATE DEV */
+#if 0
+   {
+      model_marker *ga = model_marker_get(mworld,"gate_a"),
+                   *gb = model_marker_get(mworld,"gate_a_recv");
+
+      v3_copy( ga->co, gate_a.co );
+      v3_copy( gb->co, gate_b.co );
+      v4_copy( ga->q, gate_a.q );
+      v4_copy( gb->q, gate_b.q );
+      v2_copy( ga->s, gate_a.dims );
+      v2_copy( gb->s, gate_b.dims );
+
+      gate_a.other = &gate_b;
+      gate_b.other = &gate_a;
+
+      gate_transform_update( &gate_a );
+      gate_transform_update( &gate_b );
+   }
+#endif
+
+   /* WATER DEV */
+   {
+      glmesh surf;
+      submodel *sm = submodel_get(mworld,"mp_dev_water");
+      model_unpack_submodel( mworld, &surf, sm );
+            
+      water_init();
+      water_set_surface( &surf, sm->pivot[1] );
+   }
+
+   free( mworld );
+   scene_upload( &world.geo );
+   bvh_create( &world.geo );
+
+
+
+   scene_init( &world.foliage );
+   model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
+
+   v3f volume;
+   v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
+   volume[1] = 1.0f;
+
+   m4x3f transform;
+
+   for( int i=0;i<100000;i++ )
+   {
+      v3f pos;
+      v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
+      v3_add( pos, world.geo.bbx[0], pos );
+      
+      ray_hit hit;
+      hit.dist = INFINITY;
+
+      if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
+      {
+         if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) )
+         {
+            v4f qsurface, qrandom;
+            v3f axis;
+
+            v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
+
+            float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
+            q_axis_angle( qsurface, axis, angle );
+            q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
+            q_mul( qsurface, qrandom, qsurface );
+            q_m3x3( qsurface, transform );
+
+            v3_copy( hit.pos, transform[3] );
+
+            scene_add_foliage( &world.foliage, mfoliage,
+                  model_get_submodel( mfoliage, 0 ), transform );
+         }
+      }
+   }
+
+   free( mfoliage );
+   scene_upload( &world.foliage );
+}
+
+#endif /* WORLD_H */