From: hgn Date: Mon, 30 May 2022 22:58:19 +0000 (+0100) Subject: latest X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=54ca09093b8d5f752b4a0897bd9703f3b2ad6ed1;p=carveJwlIkooP6JGAAIwe30JlM.git latest --- diff --git a/blender_export.py b/blender_export.py index 05059c2..9c01c19 100644 --- a/blender_export.py +++ b/blender_export.py @@ -92,9 +92,9 @@ def write_model(name): v.co[0] = vert.co[0] v.co[1] = vert.co[2] v.co[2] = -vert.co[1] - v.colour[0] = 0.0 - v.colour[1] = 0.0 - v.colour[2] = 0.0 + v.colour[0] = 1.0 + v.colour[1] = 1.0 + v.colour[2] = 1.0 v.colour[3] = 1.0 vertex_buffer += [v] @@ -139,3 +139,4 @@ def write_model(name): write_model( "test" ) write_model( "free_dev" ) write_model( "char_dev" ) +write_model( "skydome" ) diff --git a/ik.h b/ik.h new file mode 100644 index 0000000..0bbe3b2 --- /dev/null +++ b/ik.h @@ -0,0 +1,77 @@ +#include "vg/vg.h" + +/* + * Setup basic IK system (2d, 2 bones) + * + * + base (m1) + * \ + * \ l1 + * \ + * *(m2) + pole + * / + * / l2 + * + + * end + */ +struct ik_basic +{ + v3f base, + pole, + end; + + float l1, l2; +}; + +static void ik_basic( struct ik_basic *ik, m4x3f m1, m4x3f m2 ) +{ + /* Localize the system into 2d */ + v3f v0, v1, axis; + + vg_line( ik->base, ik->pole, 0xffffff00 ); + vg_line( ik->end, ik->pole, 0xffffff00 ); + + v3_sub( ik->base, ik->pole, v0 ); + v3_sub( ik->end, ik->pole, v1 ); + + v3_cross( v0, v1, axis ); + v3_normalize( v0 ); + v3_normalize( axis ); + v3_cross( axis, v0, v1 ); + + v3f p0, p1, p2; + v3_muladds( ik->base, axis, 0.2f, p0 ); + v3_muladds( ik->base, v0, 0.2f, p1 ); + v3_muladds( ik->base, v1, 0.2f, p2 ); + vg_line( ik->base, p0, 0xffff0000 ); + vg_line( ik->base, p1, 0xff00ff00 ); + vg_line( ik->base, p2, 0xff0000ff ); + + v2f base = { v3_dot( v0, ik->base ), v3_dot( v1, ik->base ) }, + end = { v3_dot( v0, ik->end ), v3_dot( v1, ik->end ) }, + knee; + + /* Compute angles */ + v2f delta; + v2_sub( end, base, delta ); + + float + d = vg_clampf( v2_length(delta), fabsf(ik->l1 - ik->l2), + ik->l1+ik->l2-0.00001f ), + c = acosf( (ik->l1*ik->l1 + d*d - ik->l2*ik->l2) / (2.0f*ik->l1*d) ), + rot = atan2f( delta[1], delta[0] ) + c - VG_PIf/2.0f; + + knee[0] = sinf(-rot) * ik->l1; + knee[1] = cosf(-rot) * ik->l1; + + /* Project back into world coords */ + v3f world_knee; + v3_muladds( ik->base, v0, knee[0], world_knee ); + v3_muladds( world_knee, v1, knee[1], world_knee ); + + /* Create matrices */ + m4x3_lookat( m1, ik->base, world_knee, axis ); + m4x3_lookat( m2, world_knee, ik->end, axis ); + + vg_line( ik->base, world_knee, 0xff0000ff ); + vg_line( world_knee, ik->end, 0xff00ff40 ); +} diff --git a/main.c b/main.c index e34ca5f..8a81228 100644 --- a/main.c +++ b/main.c @@ -4,7 +4,7 @@ /* Resources */ vg_tex2d tex_norwey = { .path = "textures/norway_foliage.qoi" }; vg_tex2d tex_grid = { .path = "textures/grid.qoi" }; -vg_tex2d tex_road = { .path = "textures/road.qoi" }; +vg_tex2d tex_sky = { .path = "textures/sky.qoi" }; vg_tex2d tex_gradients = { .path = "textures/gradients.qoi", .flags = VG_TEXTURE_CLAMP }; vg_tex2d *texture_list[] = @@ -12,18 +12,19 @@ vg_tex2d *texture_list[] = &tex_norwey, &tex_gradients, &tex_grid, - &tex_road + &tex_sky }; /* Convars */ static int freecam = 0; static int debugview = 0; static int debugsdf = 0; -static int debugroad = 0; +static int sv_debugcam = 0; /* Components */ #include "road.h" #include "scene.h" +#include "ik.h" int main( int argc, char *argv[] ) { @@ -32,33 +33,40 @@ int main( int argc, char *argv[] ) m4x3f world_matrix; -#if 0 -v3f player.co; -v3f player.view; /* Relative to pos */ -v3f player.v = { 0.0f, 0.0f, -0.2f }; -float player_yaw; -v2f player.look_dir; -v3f player.a; -#endif - static struct gplayer { v3f co, v, a; v4f rot; + float vswitch, slip_last; v3f view; v2f look_dir; /* TEMP */ m4x3f to_world, to_local; + + glmesh mesh; + + submodel legl, + legu, + board, + torso, + wheels; } player; -road_patch road_main; -scene test_scene; -scene world_scene; -scene player_scene; -u32 world_terrain_count, - world_road_count; +static struct gworld +{ + glmesh skydome; + + scene foliage, /* Tree shader */ + geo, /* Std shader, collisions */ + detail; /* Std shader, no collisions */ + + submodel terrain, + terrain_rocks, + terrain_road; +} +world; static void player_transform_update(void) { @@ -76,6 +84,8 @@ static int reset_player( int argc, char const *argv[] ) v3_zero( player.co ); v3_copy( (v3f){ 0.0f, 0.0f, -0.2f }, player.v ); q_identity( player.rot ); + player.vswitch = 1.0f; + player.slip_last = 0.0f; player_transform_update(); return 0; @@ -90,9 +100,6 @@ void vg_start(void) { vg_tex2d_init( texture_list, vg_list_size( texture_list ) ); - road_patch_init( &road_main ); - road_generate( &road_main ); - vg_convar_push( (struct vg_convar){ .name = "freecam", .data = &freecam, @@ -102,24 +109,24 @@ void vg_start(void) }); vg_convar_push( (struct vg_convar){ - .name = "debugview", - .data = &debugview, + .name = "debugcam", + .data = &sv_debugcam, .data_type = k_convar_dtype_i32, .opt_i32 = { .min=0, .max=1, .clamp=0 }, .persistent = 1 }); vg_convar_push( (struct vg_convar){ - .name = "debugsdf", - .data = &debugsdf, + .name = "debugview", + .data = &debugview, .data_type = k_convar_dtype_i32, - .opt_i32 = { .min=0, .max=1, .clamp=1 }, + .opt_i32 = { .min=0, .max=1, .clamp=0 }, .persistent = 1 }); vg_convar_push( (struct vg_convar){ - .name = "debugroad", - .data = &debugroad, + .name = "debugsdf", + .data = &debugsdf, .data_type = k_convar_dtype_i32, .opt_i32 = { .min=0, .max=1, .clamp=1 }, .persistent = 1 @@ -133,73 +140,106 @@ void vg_start(void) v3f lightDir = { 0.1f, 0.8f, 0.2f }; v3_normalize( lightDir ); - scene_init( &world_scene ); - scene_init( &test_scene ); - scene_init( &player_scene ); - model *world = vg_asset_read( "models/free_dev.mdl" ); - model *test = vg_asset_read( "models/test.mdl" ); + /* Unpack player */ model *char_dev = vg_asset_read( "models/char_dev.mdl" ); - scene_add_model( &player_scene, char_dev, - submodel_get( char_dev, "joint" ), - (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); + model_unpack( char_dev, &player.mesh ); + player.legl = *submodel_get( char_dev, "legl" ); + player.legu = *submodel_get( char_dev, "legu" ); + player.board = *submodel_get( char_dev, "skateboard" ); + player.torso = *submodel_get( char_dev, "torso" ); + player.wheels = *submodel_get( char_dev, "wheels" ); free(char_dev); + + /* Setup scene */ + scene_init( &world.geo ); + scene_init( &world.detail ); + scene_init( &world.foliage ); + + model *mworld = vg_asset_read( "models/free_dev.mdl" ); + model *mtest = vg_asset_read( "models/test.mdl" ); - scene_add_model( &world_scene, world, - submodel_get( world, "terrain" ), + model *msky = vg_asset_read( "models/skydome.mdl" ); + model_unpack( msky, &world.skydome ); + free( msky ); + + 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.terrain ); - int id_tree = submodel_get( test, "tree" ), - id_groundcover[] = + scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain_rocks" ), + (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); + scene_copy_slice( &world.geo, &world.terrain_rocks ); + + submodel *ptree = submodel_get( mtest, "tree" ), + *pt_groundcover[] = { - submodel_get( test, "bush" ), - submodel_get( test, "grass" ), - submodel_get( test, "blubber" ), - submodel_get( test, "blubber" ), - submodel_get( test, "blubber" ), - submodel_get( test, "grassthin" ) + submodel_get( mtest, "bush" ), + submodel_get( mtest, "bush" ), + submodel_get( mtest, "blubber" ), }; /* Sprinkle some trees in the terrain areas */ v3f range; - v3_sub( world_scene.bbx[1], world_scene.bbx[0], range ); + v3_sub( world.geo.bbx[1], world.geo.bbx[0], range ); + +#ifdef VG_RELEASE + int const ktree_count = 8000, + kfoliage_count = 200000; +#else + int const ktree_count = 200, + kfoliage_count = 0; +#endif - for( int i=0; i<8000; i++ ) + for( int i=0; i 0.9f ) + { + scene_add_model( &world.foliage, mtest, ptree, + pos, vg_randf() * VG_TAUf, vg_randf() * 0.5f + 0.5f ); + } + } + } - pos[0] = vg_randf(); - pos[1] = 0.0f; - pos[2] = vg_randf(); - v3_muladd( world_scene.bbx[0], pos, range, pos ); + for( int i=0; i 0.7f ) + { + scene_add_model( &world.foliage, mtest, + pt_groundcover[rand()%vg_list_size(pt_groundcover)], + pos, vg_randf() * VG_TAUf, vg_randf() * 0.5f + 0.5f ); + } } } - world_terrain_count = world_scene.indice_count; + scene_add_model( &world.geo, mworld, submodel_get( mworld, "road" ), + (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); + scene_copy_slice( &world.geo, &world.terrain_road ); - scene_add_model( &world_scene, world, - submodel_get( world, "road" ), + scene_add_model( &world.detail, mworld, submodel_get( mworld, "art" ), (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); - world_road_count = world_scene.indice_count-world_terrain_count; - free( test ); - free( world ); + free( mtest ); + free( mworld ); -#if 0 - scene_compute_occlusion( &test_scene ); - scene_shadow_gradient( &test_scene, 1, 0.0f, 1.0f ); - scene_shadow_sphere( &test_scene, (v3f){ 0.0f,4.0f,0.0f}, - (v4f){1.0f, 2.0f, 0.0f, 0.0f}, lightDir ); -#endif + scene_compute_occlusion( &world.foliage ); - scene_upload( &player_scene ); - scene_upload( &world_scene ); - scene_upload( &test_scene ); + scene_upload( &world.foliage ); + scene_upload( &world.geo ); + scene_upload( &world.detail ); reset_player( 0, NULL ); player_transform_update(); @@ -258,10 +298,88 @@ void vg_update(void) v3_muls( move_vel, 0.75f, move_vel ); v3_add( move_vel, player.view, player.view ); + } + - return; + static int in_air = 1; + + v3f ground_pos, ground_norm; + v3_copy( player.co, ground_pos ); + + if( sample_scene_height( &world.geo, ground_pos, ground_norm ) ) + { +#if 0 + v3f localup; + m3x3_mulv( player.to_world, (v3f){0.0f,1.0f,0.0f}, localup ); + v3_normalize(localup); + v3_normalize(ground_norm); + + float angle = v3_dot( localup, ground_norm ); + v3f axis; + v3_cross( localup, ground_norm, axis ); + + if( angle < 0.999f && !in_air ) + { + v4f correction; + q_axis_angle( correction, axis, acosf(angle) ); + q_mul( correction, player.rot, player.rot ); + } +#endif } + if( freecam ) + return; + + if( in_air ) + { + v3f pco, pco1, pv; + + float pstep = timestep*10.0f; + + v3f gravity = { 0.0f, -9.6f, 0.0f }; + v3_copy( player.co, pco ); + v3_copy( player.v, pv ); + + v3f targetn; + + for( int i=0; i<20; i++ ) + { + v3_copy( pco, pco1 ); + v3_muladds( pv, gravity, pstep, pv ); + v3_muladds( pco, pv, pstep, pco ); + + vg_line( pco, pco1, i&0x1?0xff000000:0xffffffff ); + + v3f sh; + v3_copy( pco, sh ); + sample_scene_height( &world.geo, sh, targetn ); + + if( sh[1] >= pco[1] ) + { + v3f localup; + m3x3_mulv( player.to_world, (v3f){0.0f,1.0f,0.0f}, localup ); + + float angle = v3_dot( localup, targetn ); + v3f axis; + v3_cross( localup, targetn, axis ); + + if( angle < 0.99f ) + { + v4f correction; + q_axis_angle( correction, axis, acosf(angle)*0.1f ); + q_mul( correction, player.rot, player.rot ); + } + + break; + } + } + + if( ground_pos[1] > player.co[1] ) + { + in_air = 0; + } + } + if( vg_get_button( "forward" ) ) { v3f dir = { 0.0f, 0.0f, -1.0f }; @@ -271,42 +389,47 @@ void vg_update(void) } /* Get front and back contact points */ - v3f contact_front, contact_back, fwd, fwd1, contact_norm, vup; + + v3f contact_front, contact_back, fwd, fwd1, contact_norm, vup, vside; + v3f axis; m3x3_mulv( player.to_world, (v3f){0.0f,0.0f,-1.0f}, fwd ); - m3x3_mulv( player.to_world, (v3f){0.03f,0.0f,-1.0f}, fwd1 ); + m4x3_mulv( player.to_world, (v3f){ 0.15f,0.0f,-1.0f}, contact_norm ); + m4x3_mulv( player.to_world, (v3f){-0.15f,0.0f,-1.0f}, contact_front ); + m4x3_mulv( player.to_world, (v3f){ 0.00f,0.0f, 1.0f}, contact_back ); m3x3_mulv( player.to_world, (v3f){0.0f,1.0f,0.0f}, vup ); - - v3_muladds( player.co, fwd, 1.0f, contact_front ); - v3_muladds( player.co, fwd,-1.0f, contact_back ); - v3_muladds( player.co, fwd1, 1.0f, contact_norm ); + m3x3_mulv( player.to_world, (v3f){1.0f,0.0f,0.0f}, vside ); - sample_scene_height( &world_scene, contact_front ); - sample_scene_height( &world_scene, contact_back ); - sample_scene_height( &world_scene, contact_norm ); + int all_contacting = + sample_scene_height( &world.geo, contact_front, NULL ) && + sample_scene_height( &world.geo, contact_back, NULL ) && + sample_scene_height( &world.geo, contact_norm, NULL ); v3f norm; v3f v0, v1; - v3_sub( contact_back, contact_norm, v0 ); - v3_sub( contact_front, contact_norm, v1 ); + v3_sub( contact_norm, contact_front, v0 ); + v3_sub( contact_back, contact_front, v1 ); v3_cross( v1, v0, norm ); v3_normalize( norm ); - v3f gravity = { 0.0f, -9.6f, 0.0f }; - v3_muladds( player.v, gravity, timestep, player.v ); + vg_line( contact_norm, contact_front, 0xff00ff00 ); + vg_line( contact_back, contact_front, 0xff0000ff ); - v3f ground_pos; - v3_copy( player.co, ground_pos ); - sample_scene_height( &world_scene, ground_pos ); + /* Surface alignment */ + float angle = v3_dot( vup, norm ); + v3_cross( vup, norm, axis ); - static int in_air = 1; - - if( in_air ) + if( angle < 0.999f && !in_air ) { - if( ground_pos[1] > player.co[1] ) - in_air = 0; + v4f correction; + q_axis_angle( correction, axis, acosf(angle) ); + q_mul( correction, player.rot, player.rot ); } + + v3f gravity = { 0.0f, -9.6f, 0.0f }; + v3_muladds( player.v, gravity, timestep, player.v ); + if( !in_air ) { float resistance = v3_dot( norm, player.v ); @@ -329,39 +452,26 @@ void vg_update(void) { player.co[1] = (contact_front[1]+contact_back[1])*0.5f; - vg_line( player.co, contact_front, 0xff00ffff ); - vg_line( player.co, contact_back, 0xff00ffa0 ); - - /* Create the 'travel' vector */ - v3f travel; - v3_sub( contact_front, contact_back, travel ); - v3_normalize( travel ); - - /* Apply gravity */ -#if 0 - float gravity_conversion = -v3_dot( travel, gravity ); - vel[2] += gravity_conversion * substep; -#endif - - /* Get localized (rotated) rigidbody forces - * -z - * ^ - * -|- - * | - * +z - */ - v3f vel; m3x3_mulv( player.to_local, player.v, vel ); /* Calculate local forces */ - slip = -vel[0] / vel[2]; - float substep = timestep * 0.2f; + slip = (-vel[0] / vel[2]) * player.vswitch; if( fabsf( slip ) > 1.2f ) - { slip = vg_signf( slip ) * 1.2f; + + + if( player.slip_last*slip < 0.0f && fabsf(slip) > 0.7f ) + { + vg_warn( "SWITCH\n" ); + player.vswitch = -player.vswitch; + slip = -slip; } + + player.slip_last = slip; + + float substep = timestep * 0.2f; for( int i=0; i<5; i++ ) { @@ -384,6 +494,10 @@ void vg_update(void) else { yawamt -= vg_get_axis( "horizontal" ) * 3.6f * timestep; + + v4f pitch; + q_axis_angle( pitch, vside, vg_get_axis( "vertical" ) * 3.6f *timestep ); + q_mul( pitch, player.rot, player.rot ); } v4f rotate; @@ -399,28 +513,42 @@ void vg_update(void) v2f ac; static v3f last_vel = { 0.0f, 0.0f, 0.0f }; - static v3f bob, bob1; + static v3f momentum, bob; v3_sub( player.v, last_vel, player.a ); v3_copy( player.v, last_vel ); - v3_add( bob, player.a, bob ); - bob[0] = vg_clampf( bob[0], -0.4f, 1.0f ); - bob[1] = vg_clampf( bob[1], -0.4f, 1.3f ); - bob[2] = vg_clampf( bob[2], -0.4f, 1.0f ); + v3_add( momentum, player.a, momentum ); + + v3_lerp( momentum, (v3f){0.0f,0.0f,0.0f}, 0.1f, momentum ); + v3f target; - v3_lerp( bob, (v3f){ 0.0f, 0.0f, 0.0f }, 0.1f, bob ); - v3_lerp( bob1, bob, 0.1f, bob1 ); + momentum[0] = vg_clampf( momentum[0], -2.0f, 2.0f ); + momentum[1] = vg_clampf( momentum[1], -0.2f, 5.0f ); + momentum[2] = vg_clampf( momentum[2], -2.0f, 2.0f ); + v3_copy( momentum, target ); + v3_lerp( bob, target, 0.2f, bob ); + /* Head */ - head[0] = (-sinf(slip)*0.9f * kheight + bob1[0]*0.6f) * 0.54f; - head[1] = cosf(slip)*0.9f * kheight +-bob1[1]*1.4f; + float lslip = fabsf(slip); //vg_minf( 0.4f, slip ); + head[0] = 0.0f;//(-sinf(lslip)*0.9f * kheight) * 0.44f; + head[1] = (0.3f + cosf(lslip)*0.5f) * kheight; head[2] = 0.0f; + v3f offset; + m3x3_mulv( player.to_local, bob, offset ); + offset[0] *= 0.25f; + offset[1] *= -0.25f; + offset[2] *= 0.7f; + v3_muladds( head, offset, 1.0f, head ); + + player_transform_update(); + m4x3_mulv( player.to_world, head, head ); v3_copy( head, player.view ); - player_transform_update(); + q_normalize(player.rot); } static void debug_grid( v3f at ) @@ -442,12 +570,106 @@ static void debug_grid( v3f at ) } } +static void draw_player(void) +{ + mesh_bind( &player.mesh ); + float const kleg_upper = 0.53f, + kleg_lower = 0.5f; + + /* Create IK targets */ + struct ik_basic ik_leg_l = { .l1 = kleg_upper, .l2 = kleg_lower }, + ik_leg_r = { .l1 = kleg_upper, .l2 = kleg_lower }; + + v3f butt, fwd; + + m4x3_mulv( player.to_world, (v3f){ 0.0f,0.16f,-0.4f }, ik_leg_r.end ); + m4x3_mulv( player.to_world, (v3f){ 0.0f,0.16f, 0.3f }, ik_leg_l.end ); + m4x3_mulv( player.to_world, (v3f){ -0.6f,0.5f,-0.4f }, ik_leg_r.pole ); + m4x3_mulv( player.to_world, (v3f){ -0.6f,0.5f,0.35f }, ik_leg_l.pole ); + + m3x3_mulv( player.to_world, (v3f){ 0.2f,-0.55f,0.0f}, butt ); + v3_add( butt, player.view, butt ); + + m3x3_mulv( player.to_world, (v3f){0.0f,0.0f,-1.0f}, fwd ); + v3_muladds( butt, fwd, 0.1f, ik_leg_r.base ); + v3_muladds( butt, fwd,-0.1f, ik_leg_l.base ); + + /* Compute IK */ + m4x3f mleg_l, mknee_l, mleg_r, mknee_r, mboard; + + ik_basic( &ik_leg_r, mleg_r, mknee_r ); + ik_basic( &ik_leg_l, mleg_l, mknee_l ); + + /* Draw */ + vg_tex2d_bind( &tex_grid, 0 ); + scene_tree_sway = 0.0f; + + mesh_bind( &player.mesh ); + m4x4f mat; + + SHADER_USE(shader_standard_lit); + + glUniformMatrix4fv( SHADER_UNIFORM( shader_standard_lit, "uPv" ), + 1, GL_FALSE, (float *)vg_pv ); + glUniform1i( SHADER_UNIFORM( shader_standard_lit, "uTexMain" ), 0 ); + vg_tex2d_bind( &tex_grid, 0 ); + + GLint kuMdl = SHADER_UNIFORM( shader_standard_lit, "uMdl" ); + + float kscale = 0.7f; + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.9f*kscale,0.6f*kscale,0.1f*kscale,1.0f ); + + m4x3_expand( player.to_world, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.board ); + + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.2f*kscale,0.3f*kscale,1.0f*kscale,1.0f ); + submodel_draw( &player.wheels ); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + glDisable( GL_DEPTH_TEST ); + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.2f*kscale,0.3f*kscale,1.0f*kscale,0.2f ); + + m4x3_expand( mleg_l, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.legu ); + + m4x3_expand( mknee_l, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.legl ); + + m4x3_expand( mleg_r, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.legu ); + + m4x3_expand( mknee_r, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.legl ); + + m4x3f mbutt; + m3x3_copy( player.to_world, mbutt ); + v3_copy( butt, mbutt[3] ); + + m4x3_expand( mbutt, mat ); + glUniformMatrix4fv( kuMdl, 1, GL_FALSE, (float *)mat ); + submodel_draw( &player.torso ); + + glDisable(GL_BLEND); + glEnable( GL_DEPTH_TEST ); +} + void vg_render(void) { glViewport( 0,0, vg_window_x, vg_window_y ); glDisable( GL_DEPTH_TEST ); glClearColor( 0.1f, 0.0f, 0.2f, 1.0f ); + glClearColor(141.0f/255.0f, 176.0f/255.0f, 215.0f/255.0f,1.0f); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); v3f pos_inv; @@ -459,7 +681,7 @@ void vg_render(void) m4x3_identity( world_matrix ); m4x3_rotate_x( world_matrix, - freecam? player.look_dir[1]: 0.3f+shake[1]*0.04f ); + freecam? player.look_dir[1]: 0.5f+shake[1]*0.04f ); m4x3_rotate_y( world_matrix, player.look_dir[0]+shake[0]*0.02f ); m4x3_translate( world_matrix, pos_inv ); @@ -472,65 +694,101 @@ void vg_render(void) 0.01f, 1000.0f ); m4x4_mul( vg_pv, world_4x4, vg_pv ); - if( debugroad ) - draw_road_patch_dev( &road_main ); - vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 ); vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 ); vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff ); - v3f board_fwd = { 0.0f, 0.0f, -1.0f }; - v3f board_side = { 1.0f, 0.0f, 0.0f }; + glEnable( GL_DEPTH_TEST ); + + scene_foliage_shader_use(); + m4x4f temp1; + m4x4_identity( temp1 ); + glUniformMatrix4fv( SHADER_UNIFORM( shader_debug_vcol, "uMdl" ), + 1, GL_FALSE, (float *)temp1 ); - m3x3_mulv( player.to_world, board_fwd, board_fwd ); - m3x3_mulv( player.to_world, board_side, board_side ); + vg_tex2d_bind( &tex_norwey, 0 ); + scene_tree_sway = 0.1f; - v3f bnw, bne, bse, bsw; + scene_bind( &world.foliage ); + scene_draw( &world.foliage ); + if( debugsdf ) + scene_debugsdf( &world.foliage ); - v3_muladds( player.co, board_fwd, 0.75f, bnw ); - v3_muladds( player.co, board_fwd, -0.75f, bsw ); - v3_muladds( bnw, board_side, 0.1f, bne ); - v3_muladds( bnw, board_side, -0.1f, bnw ); - v3_muladds( bsw, board_side, 0.1f, bse ); - v3_muladds( bsw, board_side, -0.1f, bsw ); - - vg_line( bnw, bne, 0xff00ff00 ); - vg_line( bne, bse, 0xff00ff00 ); - vg_line( bse, bsw, 0xff00ff00 ); - vg_line( bsw, bnw, 0xff00ff00 ); + SHADER_USE(shader_unlit); + m4x4f temp2; + m4x4_identity(temp2); + //m4x4_translate( temp2, player.co ); + glUniformMatrix4fv( SHADER_UNIFORM( shader_unlit, "uMdl" ), + 1, GL_FALSE, (float *)temp2 ); + glUniformMatrix4fv( SHADER_UNIFORM( shader_unlit, "uPv" ), + 1, GL_FALSE, (float *)vg_pv ); - glEnable( GL_DEPTH_TEST ); + glUniform1i( SHADER_UNIFORM( shader_unlit, "uTexMain" ), 0 ); + vg_tex2d_bind( &tex_sky, 0 ); - SHADER_USE( shader_debug_vcol ); - m4x3f temp; - m4x4f temp1; + SHADER_USE(shader_standard_lit); - vg_tex2d_bind( &tex_grid, 0 ); - scene_tree_sway = 0.0f; + glUniformMatrix4fv( SHADER_UNIFORM( shader_standard_lit, "uPv" ), + 1, GL_FALSE, (float *)vg_pv ); + glUniform1i( SHADER_UNIFORM( shader_standard_lit, "uTexMain" ), 0 ); - m4x3_identity( temp ); - m4x3_expand( temp, temp1 ); - glUniformMatrix4fv( SHADER_UNIFORM( shader_debug_vcol, "uMdl" ), + glUniformMatrix4fv( SHADER_UNIFORM( shader_standard_lit, "uMdl" ), 1, GL_FALSE, (float *)temp1 ); - scene_draw( &player_scene, -1, 0 ); + + vg_tex2d_bind( &tex_grid, 0 ); + + scene_bind( &world.geo ); + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.2f,0.36f,0.25f,1.0f ); + submodel_draw( &world.terrain ); + + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.2f,0.2f,0.21f,1.0f ); + submodel_draw( &world.terrain_rocks ); + + glUniform4f( SHADER_UNIFORM(shader_standard_lit,"uColour"), + 0.4f,0.4f,0.4f,1.0f ); + submodel_draw( &world.terrain_road ); - m4x3_identity( temp ); - m4x3_expand( temp, temp1 ); - glUniformMatrix4fv( SHADER_UNIFORM( shader_debug_vcol, "uMdl" ), - 1, GL_FALSE, (float *)temp1 ); + scene_bind( &world.detail ); + scene_draw( &world.detail ); - vg_tex2d_bind( &tex_norwey, 0 ); - scene_tree_sway = 0.1f; - scene_draw( &test_scene, -1, 0 ); + draw_player(); - vg_tex2d_bind( &tex_grid, 0 ); - scene_tree_sway = 0.0f; - scene_draw( &world_scene, world_terrain_count, 0 ); + glDisable( GL_DEPTH_TEST ); + vg_lines_drawall( (float *)vg_pv ); + + /* Debugger camera */ + glViewport( 0,0, 512, 512 ); + glClearColor( 0.1f, 0.0f, 0.2f, 1.0f ); + glClear( GL_DEPTH_BUFFER_BIT ); + + m4x3_identity( world_matrix ); - vg_tex2d_bind( &tex_road, 0 ); - scene_draw( &world_scene, world_road_count, world_terrain_count ); + 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.01f, 1000.0f ); + m4x4_mul( vg_pv, world_4x4, vg_pv ); + + if(sv_debugcam) + { + glEnable( GL_DEPTH_TEST ); + draw_player(); + } glDisable( GL_DEPTH_TEST ); + vg_lines_drawall( (float *)vg_pv ); + + glViewport( 0,0, vg_window_x, vg_window_y ); } void vg_ui(void) diff --git a/model.h b/model.h new file mode 100644 index 0000000..2aaf483 --- /dev/null +++ b/model.h @@ -0,0 +1,185 @@ +#include "vg/vg.h" + +typedef struct model model; +typedef struct glmesh glmesh; +typedef struct submodel submodel; +typedef struct model_vert model_vert; +typedef struct scene scene; +typedef struct sdf_primative sdf_primative; +typedef enum esdf_type esdf_type; + +#pragma pack(push,1) +struct model +{ + u32 identifier; + + u32 vertex_count, + indice_count, + layer_count; +}; + +struct sdf_primative +{ + v4f origin; /* xyz, yaw */ + /* Cone: + x base scale + y height + */ + v4f info; +}; + +struct submodel +{ + u32 indice_start, + indice_count, + vertex_start, + vertex_count; + + boxf bbx; + sdf_primative sdf; + + enum esdf_type + { + k_sdf_none = 0, + k_sdf_cone, + k_sdf_sphere, + k_sdf_box + } + sdf_type; + + char name[32]; +}; + +struct model_vert +{ + v3f co, + norm; + v4f colour; + v2f uv; +}; +#pragma pack(pop) + +struct glmesh +{ + GLuint vao, vbo, ebo; + u32 indice_count; +}; + +static void mesh_upload( glmesh *mesh, + model_vert *verts, u32 vert_count, + u32 *indices, u32 indice_count ) +{ + glGenVertexArrays( 1, &mesh->vao ); + glGenBuffers( 1, &mesh->vbo ); + glGenBuffers( 1, &mesh->ebo ); + glBindVertexArray( mesh->vao ); + + glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo ); + glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert), + verts, GL_STATIC_DRAW ); + + glBindVertexArray( mesh->vao ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32), + indices, GL_STATIC_DRAW ); + + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, + sizeof(model_vert), (void*)0 ); + glEnableVertexAttribArray( 0 ); + + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, + sizeof(model_vert), (void *)offsetof(model_vert, norm) ); + glEnableVertexAttribArray( 1 ); + + glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, + sizeof(model_vert), (void *)offsetof(model_vert, colour) ); + glEnableVertexAttribArray( 2 ); + + glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE, + sizeof(model_vert), (void *)offsetof(model_vert, uv) ); + glEnableVertexAttribArray( 3 ); + + VG_CHECK_GL(); + mesh->indice_count = indice_count; +} + +static void mesh_bind( glmesh *mesh ) +{ + glBindVertexArray( mesh->vao ); +} + +static void mesh_drawn( u32 start, u32 count ) +{ + glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, + (void *)(start*sizeof(u32)) ); +} + +static void mesh_draw( glmesh *mesh ) +{ + mesh_drawn( 0, mesh->indice_count ); +} + +/* + * Helper functions for file offsets + */ +static submodel *model_get_submodel( model *mdl, int id ) +{ + return ((submodel*)(mdl+1)) + id; +} + +static model_vert *model_vertex_base( model *mdl ) +{ + return (model_vert *)model_get_submodel( mdl, mdl->layer_count ); +} + +static u32 *model_indice_base( model *mdl ) +{ + return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count); +} + +static model_vert *submodel_vert_data( model *mdl, submodel *sub ) +{ + return model_vertex_base(mdl) + sub->vertex_start; +} + +static u32 *submodel_indice_data( model *mdl, submodel *sub ) +{ + return model_indice_base(mdl) + sub->indice_start; +} + +static submodel *submodel_get( model *mdl, const char *name ) +{ + for( int i=0; ilayer_count; i++ ) + { + submodel *pmdl =model_get_submodel(mdl,i); + + if( !strcmp( pmdl->name, name ) ) + return pmdl; + } + + return NULL; +} + +static void submodel_draw( submodel *sm ) +{ + mesh_drawn( sm->indice_start, sm->indice_count ); +} + +static void model_unpack( model *model, glmesh *mesh ) +{ + u32 offset = model_get_submodel( model, 0 )->vertex_count; + + for( int i=1; ilayer_count; i++ ) + { + submodel *sm = model_get_submodel( model, i ); + u32 *indices = submodel_indice_data( model, sm ); + + for( u32 j=0; jindice_count; j++ ) + indices[j] += offset; + + offset += sm->vertex_count; + } + + mesh_upload( mesh, model_vertex_base( model ), model->vertex_count, + model_indice_base( model ), model->indice_count ); +} diff --git a/scene.h b/scene.h index af9e26a..bf61fba 100644 --- a/scene.h +++ b/scene.h @@ -1,66 +1,11 @@ -typedef struct model model; -typedef struct submodel submodel; -typedef struct model_vert model_vert; -typedef struct scene scene; -typedef struct sdf_primative sdf_primative; -typedef enum esdf_type esdf_type; +#include "vg/vg.h" +#include "model.h" GLuint tex_dual_noise; -#pragma pack(push,1) -struct model -{ - u32 identifier; - - u32 vertex_count, - indice_count, - layer_count; -}; - -struct sdf_primative -{ - v4f origin; /* xyz, yaw */ - /* Cone: - x base scale - y height - */ - v4f info; -}; - -struct submodel -{ - u32 indice_start, - indice_count, - vertex_start, - vertex_count; - - boxf bbx; - sdf_primative sdf; - - enum esdf_type - { - k_sdf_none = 0, - k_sdf_cone, - k_sdf_sphere, - k_sdf_box - } - sdf_type; - - char name[32]; -}; - -struct model_vert -{ - v3f co, - norm; - v4f colour; - v2f uv; -}; -#pragma pack(pop) - struct scene { - GLuint vao, vbo, ebo; + glmesh mesh; model_vert *verts; u32 *indices; @@ -81,6 +26,8 @@ struct scene u32 shadower_count, shadower_cap; + + submodel submesh; }; static void scene_init( scene *pscene ) @@ -92,6 +39,8 @@ static void scene_init( scene *pscene ) pscene->shadowers = NULL; pscene->shadower_count = 0; pscene->shadower_cap = 0; + pscene->submesh.indice_start = 0; + pscene->submesh.indice_count = 0; v3_fill( pscene->bbx[0], 999999.9f ); v3_fill( pscene->bbx[1], -999999.9f ); @@ -161,12 +110,16 @@ static void scene_init( scene *pscene ) "return f;" \ "}" -SHADER_DEFINE( shader_debug_vcol, - "layout (location=0) in vec3 a_co;" - "layout (location=1) in vec3 a_norm;" - "layout (location=2) in vec4 a_colour;" +#define VERTEX_STANDARD_ATTRIBUTES \ + "layout (location=0) in vec3 a_co;" \ + "layout (location=1) in vec3 a_norm;" \ + "layout (location=2) in vec4 a_colour;" \ "layout (location=3) in vec2 a_uv;" - "" + +SHADER_DEFINE( shader_debug_vcol, + + /*Include*/ VERTEX_STANDARD_ATTRIBUTES + "uniform mat4 uPv;" "uniform mat4 uMdl;" "uniform float uTime;" @@ -204,7 +157,7 @@ SHADER_DEFINE( shader_debug_vcol, "uniform sampler2D uTexMain;" "uniform sampler2D uTexGradients;" "" - /* Include */ SHADER_VALUE_NOISE_3D + /*Include*/ SHADER_VALUE_NOISE_3D "" "in vec4 aColour;" "in vec2 aUv;" @@ -247,9 +200,22 @@ SHADER_DEFINE( shader_debug_vcol, "}" "if( uMode == 7 )" "{" - "if( diffuse.a < 0.45 ) discard;" - "float lighting = 1.0 - aColour.g;" + "if( diffuse.a < 0.2 ) discard;" + "float lighting = 1.0 - aColour.g*0.8;" + + "float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));" + "float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));" + "vec3 lt = vec3(0.2,0.2,0.2 ) + " + "vec3(1.0,1.0,0.9)*light1 + " + "vec3(0.1,0.3,0.4 )*light2;" + + "colour = vec4(vec3(pow(lighting,1.6)*(diffuse.r*0.7+0.5)),1.0);" + "colour = vec4(colour.rgb*lt,1.0);" + + "vec2 gradUV = vec2(lighting*1.9,aColour.b*0.8);" + "vec4 gradient_sample = texture( uTexGradients, gradUV );" + "colour = colour*gradient_sample;" "}" "if( uMode == 8 )" "{" @@ -258,9 +224,9 @@ SHADER_DEFINE( shader_debug_vcol, "light = pow(light,1.6)*(diffuse.r*0.7+0.5);" "float r1 = fractalNoise(aCo*0.01);" - "vec2 gradUV = vec2(light*1.9,r1+aColour.b*0.1);" + "vec2 gradUV = vec2(light*1.9,r1+aColour.b);" "vec4 gradient_sample = texture( uTexGradients, gradUV );" - "colour = aColour*light;" + "colour = gradient_sample*light;" "}" "FragColor = colour;" @@ -270,47 +236,93 @@ SHADER_DEFINE( shader_debug_vcol, "uTime", "uSwayAmt", "uMdl" }) ) -/* - * Helper functions for file offsets - */ -static submodel *model_get_submodel( model *mdl, int id ) -{ - return ((submodel*)(mdl+1)) + id; -} +SHADER_DEFINE( shader_standard_lit, -static model_vert *model_vertex_base( model *mdl ) -{ - return (model_vert *)model_get_submodel( mdl, mdl->layer_count ); -} + /*Include*/ VERTEX_STANDARD_ATTRIBUTES -static u32 *model_indice_base( model *mdl ) -{ - return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count); -} + "uniform mat4 uPv;" + "uniform mat4 uMdl;" + "" + "out vec4 aColour;" + "out vec2 aUv;" + "out vec3 aNorm;" + "out vec3 aCo;" + "" + "void main()" + "{" + "gl_Position = uPv * uMdl * vec4( a_co, 1.0 );" + "aColour = a_colour;" + "aUv = a_uv;" + "aNorm = mat3(uMdl) * a_norm;" + "aCo = a_co;" + "}", + /* Fragment */ + "out vec4 FragColor;" + "" + "uniform sampler2D uTexMain;" + "uniform vec4 uColour;" + "" + "in vec4 aColour;" + "in vec2 aUv;" + "in vec3 aNorm;" + "in vec3 aCo;" + "" + "void main()" + "{" + "vec3 diffuse = texture( uTexMain, aUv ).rgb;" -static model_vert *submodel_vert_data( model *mdl, submodel *sub ) -{ - return model_vertex_base(mdl) + sub->vertex_start; -} + "float light1 = max(0.0,dot(-vec3(0.5,-0.8,0.25), aNorm));" + "float light2 = max(0.0,dot(-vec3(-0.8,0.5,-0.25), aNorm));" + "diffuse += vec3(0.2,0.2,0.2 ) + " + "vec3(1.0,1.0,0.9)*light1 + " + "vec3(0.1,0.3,0.4 )*light2;" -static u32 *submodel_indice_data( model *mdl, submodel *sub ) -{ - return model_indice_base(mdl) + sub->indice_start; -} + "FragColor = vec4((diffuse*uColour.rgb)," + "aColour.a*uColour.a);" + "}" + , + UNIFORMS({ "uColour","uTexMain","uPv","uMdl" }) +) -/* Returns -1 if not found */ -static int submodel_get( model *mdl, const char *name ) -{ - for( int i=0; ilayer_count; i++ ) - { - if( !strcmp( model_get_submodel(mdl,i)->name, name )) - { - return i; - } - } - - return -1; -} +SHADER_DEFINE( shader_unlit, + + /*Include*/ VERTEX_STANDARD_ATTRIBUTES + + "uniform mat4 uPv;" + "uniform mat4 uMdl;" + "" + "out vec4 aColour;" + "out vec2 aUv;" + "out vec3 aNorm;" + "out vec3 aCo;" + "" + "void main()" + "{" + "gl_Position = uPv * uMdl * vec4( a_co, 1.0 );" + "aColour = a_colour;" + "aUv = a_uv;" + "aNorm = mat3(uMdl) * a_norm;" + "aCo = a_co;" + "}", + /* Fragment */ + "out vec4 FragColor;" + "" + "uniform sampler2D uTexMain;" + "uniform vec4 uColour;" + "" + "in vec4 aColour;" + "in vec2 aUv;" + "in vec3 aNorm;" + "in vec3 aCo;" + "" + "void main()" + "{" + "vec3 diffuse = texture( uTexMain, aUv ).rgb;" + "FragColor = vec4(pow(diffuse,vec3(1.0/2.2)),1.0);" + "}" + , + UNIFORMS({ "uTexMain", "uPv", "uMdl" }) +) static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount, size_t emsize ) @@ -328,11 +340,9 @@ static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount, /* * Append a model into the scene with a given transform */ -static void scene_add_model( scene *pscene, model *mdl, int id, +static void scene_add_model( scene *pscene, model *mdl, submodel *submodel, v3f pos, float yaw, float scale ) { - submodel *submodel = model_get_submodel( mdl, id ); - 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, @@ -401,6 +411,14 @@ static void scene_add_model( scene *pscene, model *mdl, int id, pscene->indice_count += submodel->indice_count; } +static void scene_copy_slice( scene *pscene, submodel *sm ) +{ + sm->indice_start = pscene->submesh.indice_start; + sm->indice_count = pscene->indice_count - sm->indice_start; + + pscene->submesh.indice_start = pscene->indice_count; +} + static void scene_shadow_sphere( scene *pscene, v3f sphere, v4f params, v3f lightdir ) { @@ -438,19 +456,30 @@ static void scene_shadow_gradient( scene *pscene, int comp, } /* Temporary */ -static int sample_scene_height( scene *pscene, v3f pos ) +static int sample_scene_height( scene *pscene, v3f pos, v3f norm ) { for( int i=0; iindice_count/3; i++ ) { u32 *tri = &pscene->indices[i*3]; + + float *pA = pscene->verts[tri[0]].co, + *pB = pscene->verts[tri[1]].co, + *pC = pscene->verts[tri[2]].co; float height; - if( triangle_raycast( - pscene->verts[ tri[0] ].co, - pscene->verts[ tri[1] ].co, - pscene->verts[ tri[2] ].co, pos, &height )) + if( triangle_raycast( pA, pB, pC, pos, &height )) { pos[1] = height; + + if( norm ) + { + v3f v0, v1; + v3_sub( pA, pB, v0 ); + v3_sub( pC, pB, v1 ); + v3_cross( v1, v0, norm ); + v3_normalize( norm ); + } + return 1; } } @@ -757,37 +786,9 @@ static void scene_compute_occlusion( scene *pscene ) static void scene_upload( scene *pscene ) { - glGenVertexArrays( 1, &pscene->vao ); - glGenBuffers( 1, &pscene->vbo ); - glGenBuffers( 1, &pscene->ebo ); - glBindVertexArray( pscene->vao ); - - glBindBuffer( GL_ARRAY_BUFFER, pscene->vbo ); - glBufferData( GL_ARRAY_BUFFER, pscene->vertex_count*sizeof(model_vert), - pscene->verts, GL_STATIC_DRAW ); - - glBindVertexArray( pscene->vao ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, pscene->ebo ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, pscene->indice_count*sizeof(u32), - pscene->indices, GL_STATIC_DRAW ); - - glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void*)0 ); - glEnableVertexAttribArray( 0 ); - - glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, norm) ); - glEnableVertexAttribArray( 1 ); - - glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, colour) ); - glEnableVertexAttribArray( 2 ); - - glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, uv) ); - glEnableVertexAttribArray( 3 ); - - VG_CHECK_GL(); + mesh_upload( &pscene->mesh, + pscene->verts, pscene->vertex_count, + pscene->indices, pscene->indice_count ); vg_info( "Scene upload\n" ); vg_info( " indices:%u\n", pscene->indice_count ); @@ -795,7 +796,8 @@ static void scene_upload( scene *pscene ) } float scene_tree_sway = 0.1f; -static void scene_draw( scene *pscene, int count, int start ) + +static void scene_foliage_shader_use(void) { SHADER_USE( shader_debug_vcol ); @@ -815,70 +817,65 @@ static void scene_draw( scene *pscene, int count, int start ) glUniform1f( SHADER_UNIFORM( shader_debug_vcol, "uTime" ), vg_time ); glUniform1f( SHADER_UNIFORM( shader_debug_vcol, "uSwayAmt" ), scene_tree_sway ); +} - glBindVertexArray( pscene->vao ); +static void scene_bind( scene *pscene ) +{ + mesh_bind( &pscene->mesh ); +} - if( count == -1 ) - { - glDrawElements( GL_TRIANGLES, pscene->indice_count, - GL_UNSIGNED_INT, - (void *)0 - ); - } - else - { - glDrawElements( GL_TRIANGLES, count, - GL_UNSIGNED_INT, - (void *)(start*sizeof(u32)) - ); - } +static void scene_draw( scene *pscene ) +{ + mesh_drawn( 0, pscene->indice_count ); +} - if( debugsdf ) +static void scene_debugsdf( scene *pscene ) +{ + for( int i=0; ishadower_count; i++ ) { - for( int i=0; ishadower_count; i++ ) - { - struct shadower *shadower = &pscene->shadowers[i]; + struct shadower *shadower = &pscene->shadowers[i]; - v3f base, side; - v3_copy( shadower->sdf.origin, base ); - base[1] -= shadower->sdf.info[1]; - v3_copy( base, side ); - side[0] += shadower->sdf.info[0]; + v3f base, side; + v3_copy( shadower->sdf.origin, base ); + base[1] -= shadower->sdf.info[1]; + v3_copy( base, side ); + side[0] += shadower->sdf.info[0]; - vg_line2( shadower->sdf.origin, base, 0xff00ff00, 0xff0000ff ); - vg_line2( side, base, 0xff00ff00, 0xff0000ff ); - vg_line( side, shadower->sdf.origin, 0xff00ff00 ); - } + vg_line2( shadower->sdf.origin, base, 0xff00ff00, 0xff0000ff ); + vg_line2( side, base, 0xff00ff00, 0xff0000ff ); + vg_line( side, shadower->sdf.origin, 0xff00ff00 ); + } - v3f p0 = { pscene->bbx[0][0], pscene->bbx[0][1], pscene->bbx[0][2] }, - p1 = { pscene->bbx[0][0], pscene->bbx[1][1], pscene->bbx[0][2] }, - p2 = { pscene->bbx[1][0], pscene->bbx[1][1], pscene->bbx[0][2] }, - p3 = { pscene->bbx[1][0], pscene->bbx[0][1], pscene->bbx[0][2] }, + v3f p0 = { pscene->bbx[0][0], pscene->bbx[0][1], pscene->bbx[0][2] }, + p1 = { pscene->bbx[0][0], pscene->bbx[1][1], pscene->bbx[0][2] }, + p2 = { pscene->bbx[1][0], pscene->bbx[1][1], pscene->bbx[0][2] }, + p3 = { pscene->bbx[1][0], pscene->bbx[0][1], pscene->bbx[0][2] }, - p4 = { pscene->bbx[0][0], pscene->bbx[0][1], pscene->bbx[1][2] }, - p5 = { pscene->bbx[0][0], pscene->bbx[1][1], pscene->bbx[1][2] }, - p6 = { pscene->bbx[1][0], pscene->bbx[1][1], pscene->bbx[1][2] }, - p7 = { pscene->bbx[1][0], pscene->bbx[0][1], pscene->bbx[1][2] }; - - u32 col = 0xffff00c8; - vg_line( p0, p1, col ); - vg_line( p1, p2, col ); - vg_line( p2, p3, col ); - vg_line( p3, p0, col ); - - vg_line( p4, p5, col ); - vg_line( p5, p6, col ); - vg_line( p6, p7, col ); - vg_line( p7, p4, col ); - - vg_line( p0, p4, col ); - vg_line( p1, p5, col ); - vg_line( p2, p6, col ); - vg_line( p3, p7, col ); - } + p4 = { pscene->bbx[0][0], pscene->bbx[0][1], pscene->bbx[1][2] }, + p5 = { pscene->bbx[0][0], pscene->bbx[1][1], pscene->bbx[1][2] }, + p6 = { pscene->bbx[1][0], pscene->bbx[1][1], pscene->bbx[1][2] }, + p7 = { pscene->bbx[1][0], pscene->bbx[0][1], pscene->bbx[1][2] }; + + u32 col = 0xffff00c8; + vg_line( p0, p1, col ); + vg_line( p1, p2, col ); + vg_line( p2, p3, col ); + vg_line( p3, p0, col ); + + vg_line( p4, p5, col ); + vg_line( p5, p6, col ); + vg_line( p6, p7, col ); + vg_line( p7, p4, col ); + + vg_line( p0, p4, col ); + vg_line( p1, p5, col ); + vg_line( p2, p6, col ); + vg_line( p3, p7, col ); } static void scene_register(void) { SHADER_INIT( shader_debug_vcol ); + SHADER_INIT( shader_standard_lit ); + SHADER_INIT( shader_unlit ); } diff --git a/textures/gradients.png b/textures/gradients.png index 8b60c3b..f596bf6 100644 Binary files a/textures/gradients.png and b/textures/gradients.png differ diff --git a/textures/sky.png b/textures/sky.png new file mode 100644 index 0000000..fb3fb5b Binary files /dev/null and b/textures/sky.png differ