From ce693aa912190ba0ea2c6a7ff8a3b992a098cbca Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 30 Dec 2024 20:30:14 +0100 Subject: [PATCH] dont use portals for skyboxes on binary maps resolves alot of performance issues on some maps --- src/hardware/hw_main.c | 2 +- src/p_setup.c | 4 +++ src/p_tick.c | 8 ++++-- src/r_main.cpp | 62 ++++++++++++++++++++++++++++++++++++++---- src/r_main.h | 2 +- src/r_plane.cpp | 6 ++++ src/r_portal.c | 10 ------- 7 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 80a3ae52e..b9f2ee63b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6100,7 +6100,7 @@ void HWR_RenderPlayerView(void) } // note: sets viewangle, viewx, viewy, viewz - R_SetupFrame(viewssnum); + R_SetupFrame(viewssnum, skybox); framecount++; // timedemo // copy view cam position for local use diff --git a/src/p_setup.c b/src/p_setup.c index ea7af87c0..feb8ae642 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8454,6 +8454,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) memset(&(bossinfo.weakspots), 0, sizeof(weakspot_t)*NUMWEAKSPOTS); } + // assume the skybox is visible on level load. + skyVisible = true; + memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer)); + if (!fromnetsave) { INT32 buf = gametic % BACKUPTICS; diff --git a/src/p_tick.c b/src/p_tick.c index 73737cde6..b17204636 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -925,14 +925,18 @@ void P_Ticker(boolean run) for (i = 0; i <= r_splitscreen; i++) { player_t *player = &players[displayplayers[i]]; + if (!player->mo) continue; + + const boolean isSkyVisibleForPlayer = (!udmf ? skyVisiblePerPlayer[i] : true); const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on - if (skybox) + + if (isSkyVisibleForPlayer && skybox) { R_SkyboxFrame(i); } - R_SetupFrame(i); + R_SetupFrame(i, skybox); } } } diff --git a/src/r_main.cpp b/src/r_main.cpp index d0b6222a5..66ee99202 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -80,6 +80,8 @@ fixed_t viewx, viewy, viewz; angle_t viewangle, aimingangle, viewroll; UINT8 viewssnum; fixed_t viewcos, viewsin; +boolean skyVisible; +boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible for each splitscreen player sector_t *viewsector; player_t *viewplayer; mobj_t *r_viewmobj; @@ -1226,7 +1228,7 @@ static void R_SetupAimingFrame(int s) } } -void R_SetupFrame(int s) +void R_SetupFrame(int s, boolean skybox) { player_t *player = &players[displayplayers[s]]; camera_t *thiscam = &camera[s]; @@ -1245,7 +1247,7 @@ void R_SetupFrame(int s) else if (!chasecam) thiscam->chase = false; - newview->sky = false; + newview->sky = udmf ? false : !skybox; // force this to false for udmf R_SetupAimingFrame(s); @@ -1502,8 +1504,45 @@ void R_RenderPlayerView(void) { INT32 nummasks = 1; maskcount_t* masks = static_cast(malloc(sizeof(maskcount_t))); + player_t * player = &players[displayplayers[viewssnum]]; + const boolean skybox = (skyboxmo[0] && cv_skybox.value); + UINT8 i; - R_SetupFrame(viewssnum); + srb2::ThreadPool::Sema tp_sema; + srb2::g_main_threadpool->begin_sema(); + + if (!udmf) + { + // load previous saved value of skyVisible for the player + for (i = 0; i <= splitscreen; i++) + { + if (player != &players[displayplayers[i]]) + continue; + skyVisible = skyVisiblePerPlayer[i]; + break; + } + if (skybox && skyVisible) + { + R_SkyboxFrame(viewssnum); + R_ClearClipSegs(); + R_ClearDrawSegs(); + R_ClearPlanes(); + R_ClearSprites(); + Mask_Pre(&masks[nummasks - 1]); + R_RenderBSPNode((INT32)numnodes - 1); + Mask_Post(&masks[nummasks - 1]); + R_ClipSprites(drawsegs, NULL); + R_DrawPlanes(); + // hope this crap is right lmao idk how tf multithreading works + tp_sema = srb2::g_main_threadpool->end_sema(); + srb2::g_main_threadpool->notify_sema(tp_sema); + srb2::g_main_threadpool->wait_sema(tp_sema); + srb2::g_main_threadpool->begin_sema(); + R_DrawMasked(masks, nummasks); + } + } + R_SetupFrame(viewssnum, skybox); + skyVisible = false; framecount++; validcount++; @@ -1541,8 +1580,6 @@ void R_RenderPlayerView(void) ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; ps_bsptime = I_GetPreciseTime(); - srb2::ThreadPool::Sema tp_sema; - srb2::g_main_threadpool->begin_sema(); R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1); ps_bsptime = I_GetPreciseTime() - ps_bsptime; @@ -1561,7 +1598,7 @@ void R_RenderPlayerView(void) // Add skybox portals caused by sky visplanes. - if (cv_skybox.value && skyboxmo[0]) + if (udmf && skybox) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. @@ -1714,6 +1751,19 @@ void R_RenderPlayerView(void) } } + if (!udmf) + { + // save value to skyVisiblePerPlayer + // this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa + for (i = 0; i <= splitscreen; i++) + { + if (player != &players[displayplayers[i]]) + continue; + skyVisiblePerPlayer[i] = skyVisible; + break; + } + } + free(masks); } diff --git a/src/r_main.h b/src/r_main.h index 92df1e605..b23bdff06 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -176,7 +176,7 @@ void R_SetViewSize(void); // do it (sometimes explicitly called) void R_ExecuteSetViewSize(void); -void R_SetupFrame(int split); +void R_SetupFrame(int split, boolean skybox); void R_SkyboxFrame(int split); boolean R_ViewpointHasChasecam(player_t *player); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 4092f777d..41fa8f6c6 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -691,6 +691,12 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc)(drawcolumndata_t*), bo ZoneScoped; + if (!udmf && !newview->sky) + { + skyVisible = true; + return; + } + R_CheckDebugHighlight(SW_HI_SKY); // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) diff --git a/src/r_portal.c b/src/r_portal.c index 03c99d0a4..f5e9874d6 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -247,16 +247,6 @@ void Portal_AddSkybox (const visplane_t* plane) portal->viewz = skyboxmo[0]->z; portal->viewangle = viewangle + skyboxmo[0]->angle; - if (!udmf) - { - if (skyboxmo[0]->spawnpoint) - portal->viewz = ((fixed_t)skyboxmo[0]->spawnpoint->angle)<viewz = 0; - } - else - portal->viewz = skyboxmo[0]->z; // 26/04/17: use actual Z position instead of spawnpoint angle! - mh = mapheaderinfo[gamemap-1]; // If a relative viewpoint exists, offset the viewpoint.