From: hgn Date: Mon, 20 Jun 2022 22:39:20 +0000 (+0100) Subject: CHGICKEN X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=7758c7efec3956c68294bc914e7524045a2b1bd7;p=carveJwlIkooP6JGAAIwe30JlM.git CHGICKEN --- diff --git a/character.h b/character.h index f86830a..6a3a26b 100644 --- a/character.h +++ b/character.h @@ -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; iragdoll[i], sc ); - } + rb_build_manifold( &ch->ragdoll[i] ); v3f rv; diff --git a/gate.h b/gate.h index 65dda90..2f2b21e 100644 --- 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 5772858..aef6dab 100644 --- 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 */ diff --git a/render.h b/render.h index 0abbdae..493ed3b 100644 --- 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 */ diff --git a/rigidbody.h b/rigidbody.h index 4318d8c..01734e8 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -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 af24b6c..ff97000 100644 --- 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; ivertex_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; iindice_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 index 0000000..b8d4fc7 --- /dev/null +++ b/shaders/sky.fs @@ -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 index 0000000..55a2046 --- /dev/null +++ b/shaders/sky.h @@ -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 */ diff --git a/shaders/terrain.fs b/shaders/terrain.fs index 04751e9..10e5d9d 100644 --- a/shaders/terrain.fs +++ b/shaders/terrain.fs @@ -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); } diff --git a/shaders/terrain.h b/shaders/terrain.h index e10d371..42e87aa 100644 --- a/shaders/terrain.h +++ b/shaders/terrain.h @@ -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 */ diff --git a/shaders/terrain.vs b/shaders/terrain.vs index 5bb262b..db7f980 100644 --- a/shaders/terrain.vs +++ b/shaders/terrain.vs @@ -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; } diff --git a/shaders/water.fs b/shaders/water.fs index a8220a4..b352e39 100644 --- a/shaders/water.fs +++ b/shaders/water.fs @@ -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); } diff --git a/shaders/water.h b/shaders/water.h index 749067e..e50253c 100644 --- a/shaders/water.h +++ b/shaders/water.h @@ -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" ""}, }; diff --git a/terrain.h b/terrain.h index 22b2723..739fb75 100644 --- 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 index 0000000..705b8da Binary files /dev/null and b/textures/garbage.png differ diff --git a/textures/gradients.png b/textures/gradients.png index f596bf6..660ec90 100644 Binary files a/textures/gradients.png and b/textures/gradients.png differ diff --git a/vg.conf b/vg.conf index 5453b23..e383b59 100644 --- 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 94c7b34..957f202 100644 --- 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 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 */