--- ./code/renderergl1/tr_backend.c +++ ./code/renderergl1/tr_backend.c @@ -511,7 +511,7 @@ int i; drawSurf_t *drawSurf; int oldSort; - float originalTime; + double originalTime; // save original time for entity shader offsets originalTime = backEnd.refdef.floatTime; @@ -564,7 +564,10 @@ if ( entityNum != REFENTITYNUM_WORLD ) { backEnd.currentEntity = &backEnd.refdef.entities[entityNum]; - backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime; + + // FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues + backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime; + // we have to reset the shaderTime as well otherwise image animations start // from the wrong frame tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; @@ -714,7 +717,7 @@ // set time for 2D shaders backEnd.refdef.time = ri.Milliseconds(); - backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; + backEnd.refdef.floatTime = (double)backEnd.refdef.time * 0.001f; } --- ./code/renderergl1/tr_local.h +++ ./code/renderergl1/tr_local.h @@ -193,10 +193,10 @@ typedef struct { genFunc_t func; - float base; - float amplitude; - float phase; - float frequency; + double base; + double amplitude; + double phase; + double frequency; } waveForm_t; #define TR_MAX_TEXMODS 4 @@ -256,7 +256,7 @@ typedef struct { image_t *image[MAX_IMAGE_ANIMATIONS]; int numImageAnimations; - float imageAnimationSpeed; + double imageAnimationSpeed; texCoordGen_t tcGen; vec3_t tcGenVectors[2]; @@ -367,8 +367,8 @@ void (*optimalStageIteratorFunc)( void ); - float clampTime; // time this shader is clamped to - float timeOffset; // current time offset for this shader + double clampTime; // time this shader is clamped to + double timeOffset; // current time offset for this shader int numStates; // if non-zero this is a state shader struct shader_s *currentShader; // current state if this is a state shader @@ -409,7 +409,7 @@ byte areamask[MAX_MAP_AREA_BYTES]; qboolean areamaskModified; // qtrue if areamask changed since last scene - float floatTime; // tr.refdef.time / 1000.0 + double floatTime; // tr.refdef.time / 1000.0 // text messages for deform text shaders char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH]; @@ -1230,7 +1230,7 @@ color4ub_t constantColor255[SHADER_MAX_VERTEXES] QALIGN(16); shader_t *shader; - float shaderTime; + double shaderTime; int fogNum; int dlightBits; // or together of all vertexDlightBits --- ./code/renderergl1/tr_shade.c +++ ./code/renderergl1/tr_shade.c @@ -218,7 +218,8 @@ ================= */ static void R_BindAnimatedImage( textureBundle_t *bundle ) { - int index; + int64_t index; + double v; if ( bundle->isVideoMap ) { ri.CIN_RunCinematic(bundle->videoMapHandle); @@ -233,8 +234,10 @@ // it is necessary to do this messy calc to make sure animations line up // exactly with waveforms of the same frequency - index = ri.ftol(tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE); - index >>= FUNCTABLE_SIZE2; + //index = ri.ftol(tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE); + //index >>= FUNCTABLE_SIZE2; + v = tess.shaderTime * bundle->imageAnimationSpeed; + index = v; if ( index < 0 ) { index = 0; // may happen with shader time offsets --- ./code/renderergl1/tr_shade_calc.c +++ ./code/renderergl1/tr_shade_calc.c @@ -27,7 +27,7 @@ #endif -#define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ ri.ftol( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude)) +#define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ (int)( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude)) static float *TableForFunc( genFunc_t func ) { @@ -920,7 +920,7 @@ void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) { int i; - float now; + double now; now = ( wf->phase + tess.shaderTime * wf->frequency ); @@ -954,11 +954,13 @@ void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st ) { int i; - float timeScale = tess.shaderTime; - float adjustedScrollS, adjustedScrollT; + double timeScale; + double adjustedScrollS, adjustedScrollT; + + timeScale = tess.shaderTime; - adjustedScrollS = scrollSpeed[0] * timeScale; - adjustedScrollT = scrollSpeed[1] * timeScale; + adjustedScrollS = (double)scrollSpeed[0] * timeScale; + adjustedScrollT = (double)scrollSpeed[1] * timeScale; // clamp so coordinates don't continuously get larger, causing problems // with hardware limits @@ -994,8 +996,8 @@ */ void RB_CalcRotateTexCoords( float degsPerSecond, float *st ) { - float timeScale = tess.shaderTime; - float degs; + double timeScale = tess.shaderTime; + double degs; int index; float sinValue, cosValue; texModInfo_t tmi;