From: hgn Date: Wed, 12 Feb 2025 03:07:57 +0000 (+0000) Subject: absolute shit X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=da09f4f4fd68cbc5797ff330f11aee7c361b8ee8;p=carveJwlIkooP6JGAAIwe30JlM.git absolute shit --- diff --git a/build.c b/build.c index c7e1a5d..e679783 100644 --- a/build.c +++ b/build.c @@ -115,6 +115,7 @@ void build_shaders(void){ /* Models */ _S( "model_sky", "model.vs", "model_sky.fs" ); _S( "model_sky_space", "model.vs", "model_sky_space.fs" ); + _S( "model_sky_cubemap", "model_sky.vs", "model_sky_cubemap.fs" ); _S( "model_menu", "model.vs", "model_menu.fs" ); _S( "model_character_view", "model_skinned.vs", "model_character_view.fs" ); _S( "model_board_view", "model.vs", "model_character_view.fs" ); diff --git a/content_skaterift/maps/dev_heaven/main.mdl b/content_skaterift/maps/dev_heaven/main.mdl index 2adad98..113569b 100644 Binary files a/content_skaterift/maps/dev_heaven/main.mdl and b/content_skaterift/maps/dev_heaven/main.mdl differ diff --git a/content_skaterift/models/rs_gate.mdl b/content_skaterift/models/rs_gate.mdl index 1cae7c1..597b12c 100644 Binary files a/content_skaterift/models/rs_gate.mdl and b/content_skaterift/models/rs_gate.mdl differ diff --git a/content_skaterift/models/rs_skydome.mdl b/content_skaterift/models/rs_skydome.mdl index 53980b1..066a523 100644 Binary files a/content_skaterift/models/rs_skydome.mdl and b/content_skaterift/models/rs_skydome.mdl differ diff --git a/shaders/model_sky.vs b/shaders/model_sky.vs new file mode 100644 index 0000000..baf4d77 --- /dev/null +++ b/shaders/model_sky.vs @@ -0,0 +1,34 @@ +layout (location=0) in vec3 a_co; +layout (location=1) in vec3 a_norm; +layout (location=2) in vec2 a_uv; +layout (location=3) in vec4 a_colour; +layout (location=4) in vec4 a_weights; +layout (location=5) in ivec4 a_groups; + +#include "motion_vectors_vs.glsl" + +uniform mat4x3 uMdl; +uniform mat4 uPv; +uniform mat4 uPvmPrev; + +out vec4 aColour; +out vec2 aUv; +out vec3 aNorm; +out vec3 aCo; +out vec3 aWorldCo; + +void main() +{ + vec3 world_pos0 = uMdl * vec4( a_co, 1.0 ); + vec4 vproj0 = uPv * vec4( world_pos0, 1.0 ); + vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 ); + + vs_motion_out( vproj0, vproj1 ); + + gl_Position = vproj0; + aWorldCo = world_pos0; + aColour = a_colour; + aUv = a_uv; + aNorm = a_norm; + aCo = a_co; +} diff --git a/shaders/model_sky_cubemap.fs b/shaders/model_sky_cubemap.fs new file mode 100644 index 0000000..8385714 --- /dev/null +++ b/shaders/model_sky_cubemap.fs @@ -0,0 +1,19 @@ +uniform samplerCube uTexCubemap; + +in vec4 aColour; +in vec2 aUv; +in vec3 aNorm; +in vec3 aCo; +in vec3 aWorldCo; + +#include "motion_vectors_fs.glsl" + +layout (location = 0) out vec4 oColour; + +void main() +{ + compute_motion_vectors(); + + vec3 rd = -normalize(aNorm); + oColour = vec4(texture(uTexCubemap,rd).rgb, 1.0); +} diff --git a/src/entity.h b/src/entity.h index 1f2ada4..50e202d 100644 --- a/src/entity.h +++ b/src/entity.h @@ -203,7 +203,12 @@ struct ent_gate{ }; }; - double timing_time; + union + { + double timing_time; + u32 cubemap_id; + }; + u16 routes[4]; /* routes that pass through this gate */ u8 route_count; diff --git a/src/world.h b/src/world.h index 662a3dd..7cd280f 100644 --- a/src/world.h +++ b/src/world.h @@ -183,10 +183,14 @@ struct world_instance struct script_info *story_script; } * events; + + GLuint *nonlocal_gates_cubemaps; + u32 nonlocal_gate_count; enum skybox { k_skybox_default, - k_skybox_space + k_skybox_space, + k_skybox_cubemap } skybox; ent_gate *rendering_gate; diff --git a/src/world_entity.c b/src/world_entity.c index c4b745f..025126a 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -183,8 +183,46 @@ void world_gen_entities_init( world_instance *world ) light->angle_sin_cos[1] = cosf( light->angle * 0.5f ); } - vg_async_call( world_link_gates_async, world, 0 ); - vg_async_stall(); + world->nonlocal_gate_count = 0; + for( u32 j=0; jent_gate); j ++ ) + { + ent_gate *gate = af_arritm( &world->ent_gate, j ); + if( gate->flags & k_ent_gate_nonlocal ) + { + gate->cubemap_id = world->nonlocal_gate_count; + world->nonlocal_gate_count ++; + } + } + + if( world->nonlocal_gate_count ) + { + world->nonlocal_gates_cubemaps = vg_linear_alloc( world->heap, + vg_align8(world->nonlocal_gate_count*sizeof(GLuint)) ); + for( u32 i=0; inonlocal_gate_count; i ++ ) + world->nonlocal_gates_cubemaps[i] = 0; + + vg_async_call( world_link_gates_async, world, 0 ); + vg_async_stall(); + + for( u32 j=0; jent_gate); j ++ ) + { + ent_gate *gate = af_arritm( &world->ent_gate, j ); + if( (gate->flags & k_ent_gate_nonlocal) && (gate->flags & k_ent_gate_linked) ) + { + if( gate->addon_reg != 0xffffffff ) + { + addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0 ); + + char cubemap_path[256]; + nonlocal_gate_cubemap_path( reg, af_str( &world->meta.af, gate->key ), cubemap_path ); + vg_tex2d_load_qoi_async_file( cubemap_path, VG_TEX2D_CUBEMAP, + &world->nonlocal_gates_cubemaps[ gate->cubemap_id ] ); + } + } + } + } + else + world->nonlocal_gates_cubemaps = NULL; /* water */ for( u32 j=0; jent_water); j++ ) diff --git a/src/world_gate.c b/src/world_gate.c index 6ab4c7b..adf0bd2 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -185,8 +185,11 @@ int render_gate( world_instance *world, world_instance *world_inside, shader_model_gate_uMdl( mmdl ); render_gate_mesh( world, gate ); - render_world( world_inside, &world_gates.cam, - 1, !localplayer.gate_waiting, 1, 1 ); + if( world_inside ) + { + render_world( world_inside, &world_gates.cam, + 1, !localplayer.gate_waiting, 1, 1 ); + } return 1; } @@ -316,6 +319,19 @@ entity_call_result ent_gate_call( world_instance *world, ent_call *call ) } } +void nonlocal_gate_cubemap_path( addon_reg *world_addon, const char *gate_key, char path[256] ) +{ + char id[76]; + addon_alias_uid( &world_addon->alias, id ); + + vg_str path_str; + vg_strnull( &path_str, path, 256 ); + vg_strcat( &path_str, id ); + vg_strcat( &path_str, "-cm-" ); + vg_strcat( &path_str, gate_key ); + vg_strcat( &path_str, ".qoi" ); +} + /* * This has to be synchronous because main thread looks at gate data for * rendering, and we modify gates that the main thread has ownership of. diff --git a/src/world_gate.h b/src/world_gate.h index a071e4b..6bdfe91 100644 --- a/src/world_gate.h +++ b/src/world_gate.h @@ -34,3 +34,4 @@ void world_link_gates_async( void *payload, u32 size ); void world_unlink_nonlocal( world_instance *world ); void render_gate_unlinked( world_instance *world, ent_gate *gate, vg_camera *cam ); +void nonlocal_gate_cubemap_path( addon_reg *world_addon, const char *gate_key, char path[256] ); diff --git a/src/world_gen.c b/src/world_gen.c index 6c1b8ee..30ee158 100644 --- a/src/world_gen.c +++ b/src/world_gen.c @@ -701,9 +701,6 @@ void async_world_postprocess( void *payload, u32 _size ) glBindRenderbuffer( GL_RENDERBUFFER, cm->renderbuffer_id ); glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, WORLD_CUBEMAP_RES, WORLD_CUBEMAP_RES ); - - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_CUBE_MAP_POSITIVE_X, cm->texture_id, 0 ); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cm->renderbuffer_id ); diff --git a/src/world_load.c b/src/world_load.c index 2cb8419..b75a80d 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -530,6 +530,8 @@ void world_instance_free_graphics_data( world_instance *world ) glDeleteFramebuffers( 1, &cm->framebuffer_id ); glDeleteRenderbuffers( 1, &cm->renderbuffer_id ); } + + glDeleteTextures( world->nonlocal_gate_count, world->nonlocal_gates_cubemaps ); } /* diff --git a/src/world_render.c b/src/world_render.c index bf71a7c..12b94fa 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -11,10 +11,14 @@ #include "player_remote.h" #include "ent_skateshop.h" #include "shaders/model_entity.h" +#include "shaders/model_sky_cubemap.h" struct world_render world_render; -static int ccmd_set_time( int argc, const char *argv[] ){ +static int ccmd_render_portals( int argc, const char *argv[] ); + +static int ccmd_set_time( int argc, const char *argv[] ) +{ world_instance *world = &_world.main; if( argc == 1 ) world->time = atof( argv[0] ); @@ -46,6 +50,7 @@ void world_render_init(void) VG_VAR_I32( k_light_preview ); VG_VAR_I32( k_light_editor ); vg_console_reg_cmd( "set_time", ccmd_set_time, NULL ); + vg_console_reg_cmd( "render_portals", ccmd_render_portals, NULL ); world_render.sky_rate = 1.0; world_render.sky_target_rate = 1.0; @@ -57,6 +62,8 @@ void world_render_init(void) mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch ); mdl_load_metadata_block( &msky, vg_mem.scratch ); mdl_async_load_glmesh( &msky, &world_render.skydome, NULL ); + world_render.skydome_complete_mesh = *mdl_find_submesh( &msky, "dome_complete" ); + world_render.skydome_squanched_mesh = *mdl_find_submesh( &msky, "dome_squanched" ); mdl_close( &msky ); vg_info( "Loading default world textures\n" ); @@ -850,6 +857,10 @@ static void render_sky( world_instance *world, vg_camera *cam ) glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise ); } + else if( world->skybox == k_skybox_cubemap ) + { + /* TODO */ + } else { vg_fatal_error( "Programming error\n" ); } @@ -858,7 +869,7 @@ static void render_sky( world_instance *world, vg_camera *cam ) glDisable( GL_DEPTH_TEST ); mesh_bind( &world_render.skydome ); - mesh_draw( &world_render.skydome ); + mdl_draw_submesh( &world_render.skydome_complete_mesh ); glEnable( GL_DEPTH_TEST ); glDepthMask( GL_TRUE ); @@ -904,7 +915,44 @@ void render_world_gates( world_instance *world, vg_camera *cam ) if( gate->flags & k_ent_gate_linked ) { + render_gate( world, NULL, gate, cam ); + + m4x3f mmdl; + m4x4f pvm; + + m4x3_copy( gate->to_world, mmdl ); + mmdl[3][1] += 2.0f; + + if( gate->flags & k_ent_gate_flip ) + { + m3x3f rotation = {{-1,0,0},{0,1,0},{0,0,-1}}; + m3x3_mul( mmdl, rotation, mmdl ); + } + + m4x3_expand( mmdl, pvm ); + m4x4_mul( cam->mtx_prev.pv, pvm, pvm ); + + shader_model_sky_cubemap_use(); + shader_model_sky_cubemap_uMdl( mmdl ); + shader_model_sky_cubemap_uPv( cam->mtx.pv ); + shader_model_sky_cubemap_uPvmPrev( pvm ); + shader_model_sky_cubemap_uTexCubemap(10); + + glActiveTexture( GL_TEXTURE10 ); + glBindTexture( GL_TEXTURE_CUBE_MAP, world->nonlocal_gates_cubemaps[ gate->cubemap_id ] ); + glClear( GL_DEPTH_BUFFER_BIT ); + glStencilFunc( GL_EQUAL, 1, 0xFF ); + glStencilMask( 0x00 ); + glEnable( GL_CULL_FACE ); + glEnable( GL_STENCIL_TEST ); + + mesh_bind( &world_render.skydome ); + mdl_draw_submesh( &world_render.skydome_squanched_mesh ); + + glStencilMask( 0xFF ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glDisable( GL_STENCIL_TEST ); } else { @@ -1229,13 +1277,9 @@ void render_world_override( world_instance *world, render_world_fxglow( world, world, cam, mmdl, 0, 0, 1 ); } -static void render_cubemap_side( world_instance *world, ent_cubemap *cm, - u32 side ){ +static void render_cubemap_side( world_instance *world, v3f co, m3x3f rotation, u32 side ) +{ vg_camera cam; - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, cm->texture_id, 0 ); - glClear( GL_DEPTH_BUFFER_BIT ); - v3f forward[6] = { { -1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, @@ -1253,13 +1297,17 @@ static void render_cubemap_side( world_instance *world, ent_cubemap *cm, { 0.0f, -1.0f, 0.0f } }; + v3f vz, vy; + m3x3_mulv( rotation, forward[side], vz ); + m3x3_mulv( rotation, up[side], vy ); + v3_zero( cam.angles ); - v3_copy( cm->co, cam.pos ); + v3_copy( co, cam.pos ); - v3_copy( forward[side], cam.transform[2] ); - v3_copy( up[side], cam.transform[1] ); - v3_cross( up[side], forward[side], cam.transform[0] ); - v3_copy( cm->co, cam.transform[3] ); + v3_copy( vz, cam.transform[2] ); + v3_copy( vy, cam.transform[1] ); + v3_cross( vy, vz, cam.transform[0] ); + v3_copy( co, cam.transform[3] ); m4x3_invert_affine( cam.transform, cam.transform_inverse ); vg_camera_update_view( &cam ); @@ -1272,18 +1320,23 @@ static void render_cubemap_side( world_instance *world, ent_cubemap *cm, vg_camera_finalize( &cam ); vg_camera_finalize( &cam ); - render_world( world, &cam, 0, 1, 1, 0 ); + /* TODO: CANT RENDER CUBEMAPS BECAUSE RENDER_WORLD FUCKS WITH GLVIEWPORT AND STUFF */ + render_world( world, &cam, 0, 1, 0, 0 ); } void render_world_cubemaps( world_instance *world ) { + m3x3f identity; + m3x3_identity( identity ); + if( world->cubemap_cooldown ) world->cubemap_cooldown --; else{ world->cubemap_cooldown = 60; glViewport( 0, 0, WORLD_CUBEMAP_RES, WORLD_CUBEMAP_RES ); - for( u32 i=0; ient_cubemap ); i++ ){ + for( u32 i=0; ient_cubemap ); i++ ) + { ent_cubemap *cm = af_arritm( &world->ent_cubemap, i ); glBindFramebuffer( GL_FRAMEBUFFER, cm->framebuffer_id ); @@ -1291,11 +1344,102 @@ void render_world_cubemaps( world_instance *world ) if( world->cubemap_side >= 6 ) world->cubemap_side = 0; - render_cubemap_side( world, cm, world->cubemap_side ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + world->cubemap_side, + cm->texture_id, 0 ); + glClear( GL_DEPTH_BUFFER_BIT ); + + render_cubemap_side( world, cm->co, identity, world->cubemap_side ); } } } +void render_world_portal_cubemaps(void) +{ + if( vg_loader_availible() ) + { + qoi_desc desc = + { + .width = 512, + .height = 512*6, + .channels = 3, + .colorspace = 0 + }; + + vg_linear_clear( vg_async.buffer ); + u8 *src_image = vg_linear_alloc( vg_async.buffer, 512*512*3*6 ); + u8 *compressed_image = vg_linear_alloc( vg_async.buffer, vg_query_qoi_storage_size( &desc ) ); + + GLuint temp_tex, temp_fb, temp_rb; + + glGenFramebuffers( 1, &temp_fb ); + glBindFramebuffer( GL_FRAMEBUFFER, temp_fb ); + + glGenRenderbuffers( 1, &temp_rb ); + glBindRenderbuffer( GL_RENDERBUFFER, temp_rb ); + glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512 ); + glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, temp_rb ); + + glGenTextures( 1, &temp_tex ); + glBindTexture( GL_TEXTURE_2D, temp_tex ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_tex, 0 ); + + if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ) + { + vg_error( "Cubemap framebuffer incomplete.\n" ); + return; + } + + glViewport( 0, 0, 512, 512 ); + + world_instance *world = &_world.main; + + for( u32 j=0; jent_gate); j ++ ) + { + ent_gate *gate = af_arritm( &world->ent_gate, j ); + if( gate->flags & k_ent_gate_nonlocal ) + { + v3f co; + v3_add( gate->co[0], (v3f){0,2,0}, co ); + + m3x3f rotation; + m3x3f correction = {{0,0,1},{0,1,0},{-1,0,0}}; + m3x3_mul( correction, gate->to_world, rotation ); + + for( u32 i=0; i<6; i ++ ) + { + glClear( GL_DEPTH_BUFFER_BIT ); + render_cubemap_side( &_world.main, co, gate->to_world, i ); + + u8 *dest_side = src_image + i*512*512*3; + glReadBuffer( GL_COLOR_ATTACHMENT0 ); + glReadPixels( 0,0, 512,512, GL_RGB, GL_UNSIGNED_BYTE, dest_side ); + } + + char path[256]; + nonlocal_gate_cubemap_path( world->addon, af_str( &world->meta.af, gate->key ), path ); + + int file_size; + if( vg_encode_qoi2( src_image, &desc, compressed_image, &file_size ) ) + { + vg_asset_write( path, compressed_image, file_size ); + } + } + } + + glDeleteTextures( 1, &temp_tex ); + glDeleteFramebuffers( 1, &temp_fb ); + glDeleteRenderbuffers( 1, &temp_rb ); + } +} + +static int ccmd_render_portals( int argc, const char *argv[] ) +{ + render_world_portal_cubemaps(); + return 1; +} + /* * Geo shaders * --------------------------------------------- diff --git a/src/world_render.h b/src/world_render.h index 1eb5ab1..8d512cb 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -30,6 +30,8 @@ struct world_render /* rendering */ glmesh skydome; + mdl_submesh skydome_complete_mesh, + skydome_squanched_mesh; double sky_time, sky_rate, sky_target_rate;