From da09f4f4fd68cbc5797ff330f11aee7c361b8ee8 Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 12 Feb 2025 03:07:57 +0000 Subject: [PATCH] absolute shit --- build.c | 1 + content_skaterift/maps/dev_heaven/main.mdl | Bin 897528 -> 897528 bytes content_skaterift/models/rs_gate.mdl | Bin 54936 -> 7072 bytes content_skaterift/models/rs_skydome.mdl | Bin 38944 -> 77200 bytes shaders/model_sky.vs | 34 ++++ shaders/model_sky_cubemap.fs | 19 +++ src/entity.h | 7 +- src/world.h | 6 +- src/world_entity.c | 42 ++++- src/world_gate.c | 20 ++- src/world_gate.h | 1 + src/world_gen.c | 3 - src/world_load.c | 2 + src/world_render.c | 176 +++++++++++++++++++-- src/world_render.h | 2 + 15 files changed, 288 insertions(+), 25 deletions(-) create mode 100644 shaders/model_sky.vs create mode 100644 shaders/model_sky_cubemap.fs 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 2adad981918fe04d61a849b16bdfa286b61e54c8..113569b272a243acd85c8d7814d60419916dd741 100644 GIT binary patch delta 151 zcmezI*zCt+vkgo5)k9{<9O7VLa85eva)5!M!5)Db7!>B10Qn3JUAd;4PxJFiqA3PS xAps=C&Hpvp|7$P;F%u9o12GE_vjQ<25VHd@2M}`tF&7YX12NC`{~EkMI{=*3F^T{H delta 151 zcmezI*zCt+vkgo5)!)h}AL3wOaQ^yO^8f=wgFON>FueS14CFI3q==YpKF!Z7iKZAR yg#?fkH~-gY|F6La#7scU48$xz%nHP8K+F!r96-zo#9Tnk4a7X#|7-C6>;M3`r8GPM diff --git a/content_skaterift/models/rs_gate.mdl b/content_skaterift/models/rs_gate.mdl index 1cae7c174d2adcbdca5ce1aaa00211b0511bf6e3..597b12c801048494d4d0d63d56ddee8c2865eae1 100644 GIT binary patch literal 7072 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 diff --git a/content_skaterift/models/rs_skydome.mdl b/content_skaterift/models/rs_skydome.mdl index 53980b142be1d98c70985d67d7cf05e730329c21..066a5232976d92d5f62828b434b5a4cb67e52053 100644 GIT binary patch delta 21119 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 delta 9052 zcmb7Kdwfi1`aj6vJ%fx&#FErt=DZ^=(;=- zK`q4;(be6yary0LPD;n7+O4kL(X|%sZyU5lx4R8p+h%^>=bY)1P5$}K=aWzJo%cQO z^Ssafc}_N6jM?+crh|QoqB!x>3O|YXnO!j5w-~>F{LF2lC_Mr2OPRl5-t2;z^M71Y z_TbAVn+GS@J~jWCoUqc-)Y>@!d!C;@XUg;W3w-lt=g;9sad6E;_W{j#P7}X&mU-R} zpA5c0A#61#N7pIr#?^9NcRPU5J zE3X5+a-J5(Xe|QO-+KP{oAI=<wxDCoO3kYbm~k6sK&vJ(a6l>!&EIg;eK4gr|U>89>={HL>T&78X7( z6TsFlp_o2EL}8#duJu7yOghY%#ni+Y&qG6}4MaIaCJD%A%q>PFk8 z^t!5v>0s@*ke`#nsuX)IwvDS~v&-1vq0dddc1=tHxnw5yAIk07h;r>NwQKq3<|Uko zblR?o-9>g|1sHgnYVA^7?AONFdTG;JspM`2iian$FpTq*3$(SUnE_MxmXaUnNdMiz z*3jqU_KLSo|)=WB4})-ufHW#LC!#SY)@Fw6?7`66xGP{EoBaG5lgL*Bh8 z;E-wp82A??3lu7-?*kY(~)Ou6yW-g4^C@Cp+1psuqNZZGW*fB|-_j$oigg4<-a8hW2Zo&+hb<6i7quaXaFEm&u@`>7;B zs_E7(jaDu?ouG*uy=NKxpqpy3by?0rV-AR1B6kOv`i52p$J_(tUM)qR>XRnP$>hh{ z!~stlzr~@mr~+u)$TSw6@fWHADg#P`ATLn-Po$WPoruTAbCd;Cj5FD{4pJe|O;G1l z*pUK2Q40EW3IiCY8?guSxv(cQT zT%gRTwqGPa(Dz-rvGAaaO-Lt!e zDFDQ$u#>wf4D_S!SCY+X>3%T;{~39JmPK{{8u^^Er2*X!%lj^kwmOp?W3a?I^XJ=~ zm35J?O(8q(PnzFH?szFtb=FUu$z5EgeNBdx|3SH3q^N;=y$Fhz$q&>SzRyM3Y^ne% ziu&^*s_7!_?JU>RU2wgGu5K|2{=NKquk@~z)m1uHSbL4bNal5sD~&O9tr3R))YT=f zfrUKN`E1>!JwEE;$sp6Gn_D=+5(|9}`MTZn@B>r=#2(Jh_%jN1vpk$@mDY%3-83~V z8rEW6q`5TV$6i*+X3BM;9*Rc5gX9M~grLmlY@`YxLKJ=v6t__g(0qh%7>|)d@op*h zBVgNMEaj916b ztbzdffFvS2C(rMwL`$))Mc(|3LYj1pu)a5LqkM@(&NdYA50OtA5%4(a5^saRCo@`{W+YeE;}}h9q|vy^-H%gT*u|OqPyf z>lq^tzw07KW32qP5ms7ucZr8_&=X)KgFM|)5=WD`vw&uF*TiZhaaQ%qRD#8pNa7Hn z(Gt}N7Jp+EF8X^^+Z_cKY7^GV>*Vf%630S%fO3I?*!eE>5F&q%dqoY7Iod-LYpg;c z=%*TNRqX{!$pf?}T8n*3KA@eb#U?_I$El>JRAZwBWmgoGJ$p3SO5gNMaeNK^a!~IA zeMcg1HWY4M$&Sw`^>OVJz!_|CP> z)2C4u(C<*I!vTX|QQ^bV@%L3$IldkqttfjMGVnv>KqCya?B!B}_saatUYht2=ROX8 zz9L^Qss02dI*i`<$x}8gFD7?ys|R5vWl}Cs zD|944dLQxwMRyv-Q~|{O3H#g)ssYLe1rBCiC_YuHPK&$_^4Y1HxQvE~kJ&+msZz{A z?}Xr>PoeBLeWyp4?EZ&WE$VW^CqY&z>Ce=?7 z2Qysar%RTka}27caE26@W5;9+2Zi%w^GMs5r{B+bl~O$^>hC@%&0vKlZ>Jd^O`N$J z%;3CVO(h;F?k*gg!IWR55KuR|k;Y-OfNFuJ=1t7to~M%BnNsB3_NTLYFHkPfxtG^v zu-E;W{6O-#Jg0HnPOwP7f=np|L0qd3>Z&vKE?NuYP-1!Z?oLxcFOLfwTn47 zG2>atoy!Sy=iVlYgLGR`{hsn*AD8&*z?Fe)F2xk?BgH>1we~XQ?PTjKMfYG|FX}^# zCp0>rN_FMk9Rryjgk0KJ6JOpP;$?bED1^mi6k{wqj16vM@lt50cLzKT zckL$~pJI_^#F@RRGPR+eG3aSb&;4BD7N`t_7M4>@KdH{NSTKe_&;2!#4sKc6Hz}*X z6lZWRmUb}}0<8e=EbZ|W0J>$}5=koDU#cjhy{y6qms0abG<80Tb7pUYlQJLC#0#kv z=Bb^@_XzSvW|g-;7`R3yK)WYS^fHaFCsgY9huj0CcmRk!4ekrX zJ2^NPlON~+PGJpvNfkh|K@W*H=%ktfQtb)exW(+Sl-du}#1)X|Aa$Lx21@lKaLQ7~ zKw;s)9F0c z9G+xyaEVHQe$jt7-&o&AA)r8!U4IJfp!@fN*YeLzb~-1Lrfaq<{o3eT=t(`raTom= zM{^7tf-#D-p~7R7-i>f}U3ZxjSl(|_{2(cgf*0<0uTU0H8MtPB6BPozVR2^crvT7K z+=2C7PGO+Y${ChEGMsI&6i-=5UrZjL;u%u^4NiH9d_Wl`sd_r-^`?@+QnepC!H5fiP3h*^f|d0G-56_MG>q;!*2V z?t+v}8H3{o4DvZE0x&w9)yYMcSSnEoo2JcbHjM8MO`_akQq8QDCJl7cMZ+{6A(%REtdS}pFG~6w2+GgpQ5c%&ZfV~GX5xfQ=@1yYW z6x*7Ofm9pW9+!??_@2G$b<`Uzl~oNz>`?YJBI2^gT_%Ap5b?(pdK_ctoP~OtNv;+M zUAd{@F6178ncDf`riOP?F3_XZCr#sAKz<Si)| zfJ#TEnc6^+34}2OyCYI)2@qOQQx^*;1jMJXfuE$>ke|dF>t}iSd)k3zYM2iz-X*ZN?UX8&^2H_k9({adKFQ^Xtx~=x=D@q z4+Va)a*obvyRg*-S_JIce%f@t_y3$k2S&TqKXqHG_l7z$FVgwZn*H*bk){SVoqm>D z_r8n@jLCUHD4Lz+o$E98Xr3WE*&qcbO zqqXY+Mz~himk-ZC{=jKd>B{J&dK~0E=@zdpBKPlt9P#4DzKa#PcEY|U)msX8V zjJxk%IBu1-;K)g=cY}nd+~PN|qs^F|T%xR}WZZHXLk6zT1qGjn!bPWFj!tZMPcFU8 z^UR7SCrSKU02F>o#%{KlGu}jzfyWz+gPJPKc<$o3|E)z6WtmPN<~Z*cNa@p>V+B}Y zH@O;Rg}%>m+V7JR-Fey_$L9J^NNw%E?>|+i-lGzEUUbin#<=4!@?gDtCCZdYWD(?1 z<)uy7SkIua5tXTFV4t9ZVF@5_>szqzenU;jb+^M@M(2ioK584@R~Ok$Q${7#GuTDg z_oHLr^+!~qgUGiK`9-J28 zl-+6zRpiMy3^JpkcRlVj7gjO|QlAjlmS51Fthiu&6^*w6iXSI=eqz#@Nm=8hy(8i+ z7gao6Sv1ZqzC^r5(hvTH0@%CBimUnw3XhXE40zBUH5s20`)ex>8^1!;1(JrtZkdMPK`&%Hpv|AmvJ_WA9n#R>p0 zFQVM3QnjJPFN<_Od4TZR&C4}XA^Cvt zO3uqQ(h({F+K*FM+^vGG6`$Pf+eO8He)EYzb0e zkBTy`@i#P0lt~T6czqg1IcSVHPhY3_=~Bd64VCVpEFjD^yqrayR0xC#h?i@vVhT)` z>HsuNFlikP-TCR7_yd|ISU=_yHlI|#i#AQAXzzSInm(FG&-!}ArbU~+5;!?e1RAP( zOhX>O^SQ)19Bzk-ZjpP2RC|CjJ9pAj8aqQ1Q@|w8@|*;d6tCbq{6^&qssQ?Lu*}hI zE!6;FpyOq4N~8Fhm=gVK$3V`+{i`W^rl#(VHq1-#-hQSg9!3Ir2d92RftgZ#faFxS zH5>g)7-+=7D+8GZCh4=Jcnc94N<`P|0ZP8y+En)z@&P>r#4o(IPzlhx*vTH7M)zPssR=_bLru<|)c!4b<@V;y-kF=>Gt{Y3(Nf 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; -- 2.25.1