mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +00:00
- fixed: The frame timer for interpolating the renderer should always take its time from the actual beginning of the frame instead of checking the system timer in real time when rendering starts.
This fixes two issues: * timer related texture animations are not being recreated multiple times if a scene renders multiple viewpoints (e.g. camera textures or portals.) * interpolation is smoother when maps have a high think time of multiple milliseconds. A good map to see the difference would be ZDCMP2 which has a think time of 4-5 milliseconds. With the timer taken in real time after the thinkers have run and VSync on this resulted in alternating time slices of 11 and 21 ms between frame interpolations instead of an even 16 as should be done for smooth 60 fps because roughly every second frame was offset by those 5 ms.
This commit is contained in:
parent
bc38f7f776
commit
03ed0656e1
7 changed files with 36 additions and 4 deletions
|
@ -1017,7 +1017,8 @@ void D_DoomLoop ()
|
||||||
lasttic = gametic;
|
lasttic = gametic;
|
||||||
I_StartFrame ();
|
I_StartFrame ();
|
||||||
}
|
}
|
||||||
|
I_SetFrameTime();
|
||||||
|
|
||||||
// process one or more tics
|
// process one or more tics
|
||||||
if (singletics)
|
if (singletics)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1948,6 +1948,7 @@ void TryRunTics (void)
|
||||||
C_Ticker ();
|
C_Ticker ();
|
||||||
M_Ticker ();
|
M_Ticker ();
|
||||||
I_GetTime (true);
|
I_GetTime (true);
|
||||||
|
I_SetFrameTime();
|
||||||
G_Ticker();
|
G_Ticker();
|
||||||
gametic++;
|
gametic++;
|
||||||
|
|
||||||
|
|
|
@ -178,9 +178,17 @@ unsigned int I_FPSTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t FrameTime;
|
||||||
|
|
||||||
|
void I_SetFrameTime()
|
||||||
|
{
|
||||||
|
FrameTime = I_MSTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double I_GetTimeFrac(uint32_t* ms)
|
double I_GetTimeFrac(uint32_t* ms)
|
||||||
{
|
{
|
||||||
const uint32_t now = I_MSTime();
|
const uint32_t now = FrameTime;
|
||||||
|
|
||||||
if (NULL != ms)
|
if (NULL != ms)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ extern int (*I_WaitForTic) (int);
|
||||||
extern void (*I_FreezeTime) (bool frozen);
|
extern void (*I_FreezeTime) (bool frozen);
|
||||||
|
|
||||||
double I_GetTimeFrac (uint32_t *ms);
|
double I_GetTimeFrac (uint32_t *ms);
|
||||||
|
void I_SetFrameTime();
|
||||||
|
|
||||||
// Return a seed value for the RNG.
|
// Return a seed value for the RNG.
|
||||||
unsigned int I_MakeRNGSeed();
|
unsigned int I_MakeRNGSeed();
|
||||||
|
|
|
@ -208,10 +208,18 @@ void I_SelectTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t FrameTime;
|
||||||
|
|
||||||
|
void I_SetFrameTime()
|
||||||
|
{
|
||||||
|
FrameTime = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the fractional amount of a tic passed since the most recent tic
|
// Returns the fractional amount of a tic passed since the most recent tic
|
||||||
double I_GetTimeFrac (uint32_t *ms)
|
double I_GetTimeFrac (uint32_t *ms)
|
||||||
{
|
{
|
||||||
uint32_t now = SDL_GetTicks ();
|
uint32_t now = FrameTime;
|
||||||
if (ms) *ms = TicStart + (1000 / TICRATE);
|
if (ms) *ms = TicStart + (1000 / TICRATE);
|
||||||
if (TicStart == 0)
|
if (TicStart == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -484,10 +484,22 @@ static void CALLBACK TimerTicked(UINT id, UINT msg, DWORD_PTR user, DWORD_PTR dw
|
||||||
// saved tic.
|
// saved tic.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
static uint32_t FrameTime;
|
||||||
|
|
||||||
|
void I_SetFrameTime()
|
||||||
|
{
|
||||||
|
FrameTime = timeGetTime();
|
||||||
|
}
|
||||||
|
|
||||||
double I_GetTimeFrac(uint32_t *ms)
|
double I_GetTimeFrac(uint32_t *ms)
|
||||||
{
|
{
|
||||||
DWORD now = timeGetTime();
|
//DWORD now = MAX<uint32_t>(FrameTime, TicStart);
|
||||||
|
DWORD now = FrameTime;
|
||||||
|
if (FrameTime < TicStart)
|
||||||
|
{
|
||||||
|
// Preliminary kept in to see if this can happen. Should be removed once confirmed ok.
|
||||||
|
Printf("Timer underflow!\n");
|
||||||
|
}
|
||||||
if (ms != NULL)
|
if (ms != NULL)
|
||||||
{
|
{
|
||||||
*ms = TicNext;
|
*ms = TicNext;
|
||||||
|
|
|
@ -63,6 +63,7 @@ extern int (*I_WaitForTic) (int);
|
||||||
extern void (*I_FreezeTime) (bool frozen);
|
extern void (*I_FreezeTime) (bool frozen);
|
||||||
|
|
||||||
double I_GetTimeFrac (uint32_t *ms);
|
double I_GetTimeFrac (uint32_t *ms);
|
||||||
|
void I_SetFrameTime();
|
||||||
|
|
||||||
// Return a seed value for the RNG.
|
// Return a seed value for the RNG.
|
||||||
unsigned int I_MakeRNGSeed();
|
unsigned int I_MakeRNGSeed();
|
||||||
|
|
Loading…
Reference in a new issue