Fix frame interpolation issues and sky rendering

This commit is contained in:
Lactozilla 2023-06-26 16:28:30 -03:00
parent c2ff2c4f94
commit b760f0dffe
16 changed files with 114 additions and 114 deletions

View file

@ -513,7 +513,10 @@ static void D_Display(void)
D_RenderView(1);
for (INT32 wi = 0; wi < numworlds; wi++)
{
R_RestoreLevelInterpolators(worldlist[wi]);
worldlist[wi]->interpolated_level_this_frame = false;
}
// Image postprocessing effect
if (rendermode == render_soft)
@ -527,7 +530,6 @@ static void D_Display(void)
V_DoPostProcessor(1, postimgtype2, postimgparam2);
}
PS_STOP_TIMING(ps_rendercalltime);
R_RestoreLevelInterpolators();
}
if (lastdraw)

View file

@ -5569,7 +5569,7 @@ void HWR_BuildSkyDome(void)
gl_sky_t *sky = &gl_sky;
gl_skyvertex_t *vertex_p;
texture_t *texture = textures[texturetranslation[skytexture]];
texture_t *texture = textures[texturetranslation[viewworld->skytexture]];
sky->detail = 16;
col_count *= sky->detail;
@ -5588,7 +5588,7 @@ void HWR_BuildSkyDome(void)
if (!sky->data)
sky->data = malloc(sky->vertex_count * sizeof(sky->data[0]));
sky->texture = texturetranslation[skytexture];
sky->texture = texturetranslation[viewworld->skytexture];
sky->width = texture->width;
sky->height = texture->height;
@ -5674,9 +5674,9 @@ static void HWR_DrawSkyBackground(player_t *player)
}
dometransform.splitscreen = splitscreen;
HWR_GetTexture(texturetranslation[skytexture]);
HWR_GetTexture(texturetranslation[viewworld->skytexture]);
if (gl_sky.texture != texturetranslation[skytexture])
if (gl_sky.texture != texturetranslation[viewworld->skytexture])
{
HWR_ClearSkyDome();
HWR_BuildSkyDome();
@ -5694,7 +5694,7 @@ static void HWR_DrawSkyBackground(player_t *player)
float aspectratio;
float angleturn;
HWR_GetTexture(texturetranslation[skytexture]);
HWR_GetTexture(texturetranslation[viewworld->skytexture]);
aspectratio = (float)vid.width/(float)vid.height;
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
@ -5721,7 +5721,7 @@ static void HWR_DrawSkyBackground(player_t *player)
angle = (dup_viewangle + gl_xtoviewangle[0]);
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
dimensionmultiply = ((float)textures[texturetranslation[viewworld->skytexture]]->width/256.0f);
v[0].s = v[3].s = (-1.0f * angle) / (((float)ANGLE_90-1.0f)*dimensionmultiply); // left
v[2].s = v[1].s = v[0].s + (1.0f/dimensionmultiply); // right (or left + 1.0f)
@ -5729,7 +5729,7 @@ static void HWR_DrawSkyBackground(player_t *player)
// Y
angle = aimingangle;
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
dimensionmultiply = ((float)textures[texturetranslation[viewworld->skytexture]]->height/(128.0f*aspectratio));
if (splitscreen)
{

View file

@ -525,7 +525,7 @@ void T_ContinuousFalling(continuousfall_t *faller)
faller->sector->ceilingheight = faller->ceilingstartheight;
faller->sector->floorheight = faller->floorstartheight;
R_ClearLevelInterpolatorState(&faller->thinker);
R_ClearLevelInterpolatorState(world, &faller->thinker);
}
P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong

View file

@ -11158,14 +11158,14 @@ void P_RemoveMobj(mobj_t *mobj)
P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL));
R_RemoveMobjInterpolator(mobj);
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
#ifdef SCRAMBLE_REMOVED
// Invalidate mobj_t data to cause crashes if accessed!
memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t));
#endif
R_RemoveMobjInterpolator(mobj);
// free block
if (!mobj->thinker.next)
{ // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through!

View file

@ -3088,8 +3088,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
R_AddMobjInterpolator(mobj);
return &mobj->thinker;
}
@ -3712,7 +3710,7 @@ static void P_NetUnArchiveThinkers(void)
else
{
(next->prev = currentthinker->prev)->next = next;
R_DestroyLevelInterpolators(currentthinker);
R_DestroyLevelInterpolators(unarchiveworld, currentthinker);
Z_Free(currentthinker);
}
}
@ -4871,6 +4869,8 @@ static void RelinkWorldsToEntities(void)
I_Error("RelinkWorldsToEntities: Mobj type %d has a world mismatch (mobj: %d, set: %d)", mo->type, mo->worldnum, i);
mo->world = worldlist[mo->worldnum];
R_AddMobjInterpolator(mo);
}
}
@ -4892,7 +4892,10 @@ static void RelinkWorldsToEntities(void)
w = worldlist[player->worldnum];
player->world = w;
if (player->mo)
{
player->mo->world = w;
R_AddMobjInterpolator(player->mo);
}
}
}

View file

@ -6886,10 +6886,6 @@ static void P_InitLevelSky(INT32 skynum, player_t *player)
P_SetupWorldSky(skynum, world);
levelskynum = skynum;
// scale up the old skies, if needed
if (!dedicated)
R_SetupSkyDraw();
}
/** Sets up a sky texture to use for the level.
@ -6903,26 +6899,18 @@ void P_SetupLevelSky(INT32 skynum, boolean global)
// Global change
if (global)
P_SetupWorldSky(skynum, world);
// scale up the old skies, if needed
if (!dedicated)
R_SetupSkyDraw();
}
void P_SetupWorldSky(INT32 skynum, world_t *w)
{
w->skynum = skynum;
// scale up the old skies, if needed
if (!dedicated)
R_SetupSkyDraw();
}
void P_SetupSkyTexture(INT32 skynum)
{
char skytexname[12];
sprintf(skytexname, "SKY%d", skynum);
skytexture = R_TextureNumForName(skytexname);
world->skytexture = R_TextureNumForName(skytexname);
}
static const char *maplumpname;
@ -7784,7 +7772,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
if (!addworld || player == &players[consoleplayer])
localworld = world;
R_InitializeLevelInterpolators();
R_InitializeLevelInterpolators(world);
P_InitThinkers();
R_InitMobjInterpolators();

View file

@ -262,7 +262,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
* thinker->prev->next = thinker->next */
(next->prev = currentthinker = thinker->prev)->next = next;
R_DestroyLevelInterpolators(thinker);
R_DestroyLevelInterpolators(world, thinker);
Z_Free(thinker);
}
@ -762,7 +762,7 @@ void P_Ticker(boolean run)
if (OP_FreezeObjectplace())
{
P_MapStart();
R_UpdateMobjInterpolators(world);
R_UpdateAllMobjInterpolators();
OP_ObjectplaceMovement(&players[0]);
P_MoveChaseCamera(&players[0], &camera, false);
R_UpdateViewInterpolation();
@ -788,7 +788,7 @@ void P_Ticker(boolean run)
if (run)
{
R_UpdateMobjInterpolators(world);
R_UpdateAllMobjInterpolators();
if (demorecording)
G_WriteDemoTiccmd(&players[consoleplayer].cmd, 0);
@ -935,8 +935,8 @@ void P_Ticker(boolean run)
if (rendermode != render_none)
{
player_t *player1 = &players[displayplayer];
world_t *world1 = (world_t*)player1->world;
if (player1->mo && world1 && world1->skyboxmo[0] && cv_skybox.value)
R_PrepareViewWorld(player1);
if (player1->mo && viewworld && viewworld->skyboxmo[0] && cv_skybox.value)
{
R_SkyboxFrame(player1);
}
@ -948,8 +948,8 @@ void P_Ticker(boolean run)
if (splitscreen)
{
player_t *player2 = &players[secondarydisplayplayer];
world_t *world2 = (world_t*)player2->world;
if (player2->mo && world2 && world2->skyboxmo[0] && cv_skybox.value)
R_PrepareViewWorld(player2);
if (player2->mo && viewworld && viewworld->skyboxmo[0] && cv_skybox.value)
{
R_SkyboxFrame(player2);
}
@ -979,7 +979,7 @@ void P_PreTicker(INT32 frames)
{
P_MapStart();
R_UpdateMobjInterpolators(world);
R_UpdateAllMobjInterpolators();
RunLuaHookForWorld(HOOK(PreThinkFrame));

View file

@ -29,6 +29,7 @@
#include "r_draw.h"
#include "r_sky.h"
#include "r_patch.h"
#include "r_fps.h"
#include "s_sound.h"
#include "w_wad.h"
@ -158,7 +159,10 @@ void P_DetachPlayerWorld(player_t *player)
player->world = NULL;
if (player->mo && !P_MobjWasRemoved(player->mo))
{
R_RemoveMobjInterpolator(player->mo);
player->mo->world = NULL;
}
}
//
@ -170,7 +174,10 @@ void P_SwitchPlayerWorld(player_t *player, world_t *newworld)
player->world = newworld;
if (player->mo && !P_MobjWasRemoved(player->mo))
{
player->mo->world = newworld;
R_AddMobjInterpolator(player->mo);
}
newworld->players++;
}
@ -267,26 +274,19 @@ void P_SwitchWorld(player_t *player, world_t *w)
P_SwitchPlayerWorld(player, w);
if (!splitscreen)
{
P_SetWorld(w);
if (local)
P_InitSpecials();
}
P_SetWorld(w);
if (local || splitscreen)
P_InitSpecials();
P_UnsetThingPosition(player->mo);
P_MoveThinkerToWorld(w, THINK_MAIN, (thinker_t *)(player->mo));
P_MoveThinkerToWorld(w, THINK_MOBJ, (thinker_t *)(player->mo));
G_MovePlayerToSpawnOrStarpost(playernum);
if (local)
if (local && !splitscreen)
{
localworld = world;
S_Start();
if (!dedicated)
{
P_SetupSkyTexture(w->skynum);
R_SetupSkyDraw();
}
P_SetupSkyTexture(w->skynum);
}
if (player == &players[displayplayer])

View file

@ -70,6 +70,9 @@ typedef struct
INT32 skynum; // used for keeping track of the current sky
UINT8 weather;
// the texture number of the sky texture
INT32 skytexture;
// Needed to store the number of the dummy sky flat.
// Used for rendering, as well as tracking projectiles etc.
INT32 skyflatnum;

View file

@ -1265,7 +1265,7 @@ void R_PrecacheLevel(void)
// Sky texture is always present.
// Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat,
// while the sky texture is stored like a wall texture, with a skynum dependent name.
texturepresent[skytexture] = 1;
texturepresent[world->skytexture] = 1;
texturememory = 0;
for (j = 0; j < (unsigned)numtextures; j++)

View file

@ -467,11 +467,12 @@ void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta;
}
void R_InitializeLevelInterpolators(void)
void R_InitializeLevelInterpolators(void *wptr)
{
world->interpolators_len = 0;
world->interpolators_size = 0;
world->interpolators = NULL;
world_t *w = (world_t *)wptr;
w->interpolators_len = 0;
w->interpolators_size = 0;
w->interpolators = NULL;
}
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
@ -536,13 +537,14 @@ void R_UpdateLevelInterpolators(void)
}
}
void R_ClearLevelInterpolatorState(thinker_t *thinker)
void R_ClearLevelInterpolatorState(void *wptr, thinker_t *thinker)
{
world_t *w = (world_t *)wptr;
size_t i;
for (i = 0; i < world->interpolators_len; i++)
for (i = 0; i < w->interpolators_len; i++)
{
levelinterpolator_t *interp = world->interpolators[i];
levelinterpolator_t *interp = w->interpolators[i];
if (interp->thinker == thinker)
{
@ -614,8 +616,9 @@ void R_ApplyLevelInterpolators(void *wptr, fixed_t frac)
w->interpolated_level_this_frame = true;
}
static void R_RestoreLevelInterpolatorsForWorld(world_t *w)
void R_RestoreLevelInterpolators(void *wptr)
{
world_t *w = (world_t *)wptr;
size_t i, ii;
for (i = 0; i < w->interpolators_len; i++)
@ -669,31 +672,22 @@ static void R_RestoreLevelInterpolatorsForWorld(world_t *w)
}
}
void R_RestoreLevelInterpolators(void)
void R_DestroyLevelInterpolators(void *wptr, thinker_t *thinker)
{
for (INT32 wi = 0; wi < numworlds; wi++)
{
world_t *w = worldlist[wi];
R_RestoreLevelInterpolatorsForWorld(w);
}
}
world_t *w = (world_t *)wptr;
void R_DestroyLevelInterpolators(thinker_t *thinker)
{
size_t i;
for (i = 0; i < world->interpolators_len; i++)
for (size_t i = 0; i < w->interpolators_len; i++)
{
levelinterpolator_t *interp = world->interpolators[i];
levelinterpolator_t *interp = w->interpolators[i];
if (interp->thinker == thinker)
{
// Swap the tail of the level interpolators to this spot
world->interpolators[i] = world->interpolators[world->interpolators_len - 1];
world->interpolators_len -= 1;
w->interpolators[i] = w->interpolators[w->interpolators_len - 1];
w->interpolators_len--;
Z_Free(interp);
i -= 1;
i--;
}
}
}
@ -702,28 +696,32 @@ void R_DestroyLevelInterpolators(thinker_t *thinker)
// reasons.
void R_AddMobjInterpolator(mobj_t *mobj)
{
if (world->interpolated_mobjs_len >= world->interpolated_mobjs_capacity)
world_t *w = (world_t *)mobj->world;
if (!w)
return;
if (w->interpolated_mobjs_len >= w->interpolated_mobjs_capacity)
{
if (world->interpolated_mobjs_capacity == 0)
if (w->interpolated_mobjs_capacity == 0)
{
world->interpolated_mobjs_capacity = 256;
w->interpolated_mobjs_capacity = 256;
}
else
{
world->interpolated_mobjs_capacity *= 2;
w->interpolated_mobjs_capacity *= 2;
}
world->interpolated_mobjs = Z_ReallocAlign(
world->interpolated_mobjs,
sizeof(mobj_t *) * world->interpolated_mobjs_capacity,
w->interpolated_mobjs = Z_ReallocAlign(
w->interpolated_mobjs,
sizeof(mobj_t *) * w->interpolated_mobjs_capacity,
PU_LEVEL,
NULL,
64
);
}
world->interpolated_mobjs[world->interpolated_mobjs_len] = mobj;
world->interpolated_mobjs_len++;
w->interpolated_mobjs[w->interpolated_mobjs_len] = mobj;
w->interpolated_mobjs_len++;
R_ResetMobjInterpolationState(mobj);
mobj->resetinterp = true;
@ -731,18 +729,20 @@ void R_AddMobjInterpolator(mobj_t *mobj)
void R_RemoveMobjInterpolator(mobj_t *mobj)
{
size_t i;
world_t *w = (world_t *)mobj->world;
if (!w)
return;
if (world->interpolated_mobjs_len == 0) return;
if (w->interpolated_mobjs_len == 0) return;
for (i = 0; i < world->interpolated_mobjs_len; i++)
for (size_t i = 0; i < w->interpolated_mobjs_len; i++)
{
if (world->interpolated_mobjs[i] == mobj)
if (w->interpolated_mobjs[i] == mobj)
{
world->interpolated_mobjs[i] = world->interpolated_mobjs[
world->interpolated_mobjs_len - 1
w->interpolated_mobjs[i] = w->interpolated_mobjs[
w->interpolated_mobjs_len - 1
];
world->interpolated_mobjs_len--;
w->interpolated_mobjs_len--;
return;
}
}
@ -774,7 +774,10 @@ void R_UpdateAllMobjInterpolators(void)
for (INT32 wi = 0; wi < numworlds; wi++)
{
world_t *w = worldlist[wi];
R_UpdateMobjInterpolators(w);
// Don't care about updating if nobody is there
if (w->players)
R_UpdateMobjInterpolators(w);
}
}

View file

@ -137,17 +137,17 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj);
void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope);
// Initialize level interpolators after a level change
void R_InitializeLevelInterpolators(void);
void R_InitializeLevelInterpolators(void *wptr);
// Update level interpolators, storing the previous and current states.
void R_UpdateLevelInterpolators(void);
// Clear states for all level interpolators for the thinker
void R_ClearLevelInterpolatorState(thinker_t *thinker);
void R_ClearLevelInterpolatorState(void *wptr, thinker_t *thinker);
// Apply level interpolators to the actual game state
void R_ApplyLevelInterpolators(void *wptr, fixed_t frac);
// Restore level interpolators to the real game state
void R_RestoreLevelInterpolators(void);
void R_RestoreLevelInterpolators(void *wptr);
// Destroy interpolators associated with a thinker
void R_DestroyLevelInterpolators(thinker_t *thinker);
void R_DestroyLevelInterpolators(void *wptr, thinker_t *thinker);
// Initialize internal mobj interpolator list (e.g. during level loading)
void R_InitMobjInterpolators(void);

View file

@ -1141,6 +1141,9 @@ static boolean R_SetViewMobj(player_t *player)
//
void R_SetupFrame(player_t *player)
{
if (viewworld == NULL)
return;
camera_t *thiscam = r_viewcam;
boolean chasecam = R_ViewpointHasChasecam(player);
@ -1211,14 +1214,18 @@ void R_SetupFrame(player_t *player)
newview->sector = R_PointInWorldSubsector(viewworld, newview->x, newview->y)->sector;
}
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
// scale up the old skies, if needed
if (!dedicated)
R_SetupSkyDraw();
}
void R_SkyboxFrame(player_t *player)
{
if (viewworld == NULL)
return;
camera_t *thiscam = r_viewcam;
if (splitscreen && player == &players[secondarydisplayplayer]
@ -1353,10 +1360,11 @@ void R_SkyboxFrame(player_t *player)
else
newview->sector = R_PointInWorldSubsector(viewworld, newview->x, newview->y)->sector;
// newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT);
// newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
R_InterpolateView(R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT);
// scale up the old skies, if needed
if (!dedicated)
R_SetupSkyDraw();
}
boolean R_ViewpointHasChasecam(player_t *player)
@ -1380,7 +1388,7 @@ boolean R_ViewpointHasChasecam(player_t *player)
chasecam = true; // force chasecam on
else if (player->spectator) // no spectator chasecam
chasecam = false; // force chasecam off
if (chasecam && !thiscam->chase)
{
P_ResetCamera(player, thiscam);
@ -1391,7 +1399,7 @@ boolean R_ViewpointHasChasecam(player_t *player)
P_ResetCamera(player, thiscam);
thiscam->chase = false;
}
if (isplayer2)
{
R_SetViewContext(VIEWCONTEXT_PLAYER2);

View file

@ -657,8 +657,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
// by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant).
dc_colormap = colormaps;
dc_texturemid = skytexturemid;
dc_texheight = textureheight[skytexture]
>>FRACBITS;
dc_texheight = textureheight[viewworld->skytexture]>>FRACBITS;
for (x = pl->minx; x <= pl->maxx; x++)
{
dc_yl = pl->top[x];
@ -669,9 +668,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
dc_x = x;
dc_source =
R_GetColumn(texturetranslation[skytexture],
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
dc_source = R_GetColumn(texturetranslation[viewworld->skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
colfunc();
}
}

View file

@ -32,10 +32,6 @@
*/
INT32 levelskynum;
/** \brief the lump number of the sky texture
*/
INT32 skytexture;
/** \brief the horizon line in a 256x128 sky texture
*/
INT32 skytexturemid;
@ -56,7 +52,7 @@ fixed_t skyscale;
void R_SetupSkyDraw(void)
{
// the horizon line in a 256x128 sky texture
skytexturemid = (textures[skytexture]->height/2)<<FRACBITS;
skytexturemid = (textures[viewworld->skytexture]->height/2)<<FRACBITS;
R_SetSkyScale();
}

View file

@ -27,7 +27,7 @@
/// \brief The sky map is 256*128*4 maps.
#define ANGLETOSKYSHIFT 22
extern INT32 skytexture, skytexturemid;
extern INT32 skytexturemid;
extern fixed_t skyscale;
extern INT32 levelskynum;