[iortcw] 82/89: All: Fix floating point precision loss in renderer
Simon McVittie
smcv at debian.org
Fri Sep 8 10:44:34 UTC 2017
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to tag 1.51b
in repository iortcw.
commit aecd5bcc8e30e8ea8df4f5c5b31c94c3fd3bdfb1
Author: MAN-AT-ARMS <M4N4T4RMS at gmail.com>
Date: Sat Aug 5 08:05:53 2017 -0400
All: Fix floating point precision loss in renderer
---
MP/code/rend2/tr_backend.c | 8 ++++--
MP/code/rend2/tr_local.h | 59 +++++++++++++++++++++-------------------
MP/code/rend2/tr_noise.c | 2 +-
MP/code/rend2/tr_scene.c | 2 +-
MP/code/rend2/tr_shade.c | 4 +--
MP/code/rend2/tr_shade_calc.c | 18 ++++++------
MP/code/renderer/tr_backend.c | 8 ++++--
MP/code/renderer/tr_local.h | 10 +++----
MP/code/renderer/tr_noise.c | 2 +-
MP/code/renderer/tr_scene.c | 2 +-
MP/code/renderer/tr_shade.c | 4 +--
MP/code/renderer/tr_shade_calc.c | 24 ++++++++--------
SP/code/rend2/tr_backend.c | 8 ++++--
SP/code/rend2/tr_local.h | 59 +++++++++++++++++++++-------------------
SP/code/rend2/tr_noise.c | 2 +-
SP/code/rend2/tr_scene.c | 2 +-
SP/code/rend2/tr_shade.c | 4 +--
SP/code/rend2/tr_shade_calc.c | 18 ++++++------
SP/code/renderer/tr_backend.c | 8 ++++--
SP/code/renderer/tr_local.h | 10 +++----
SP/code/renderer/tr_noise.c | 2 +-
SP/code/renderer/tr_scene.c | 2 +-
SP/code/renderer/tr_shade.c | 4 +--
SP/code/renderer/tr_shade_calc.c | 24 ++++++++--------
24 files changed, 150 insertions(+), 136 deletions(-)
diff --git a/MP/code/rend2/tr_backend.c b/MP/code/rend2/tr_backend.c
index 5e9b271..4bd525c 100644
--- a/MP/code/rend2/tr_backend.c
+++ b/MP/code/rend2/tr_backend.c
@@ -503,7 +503,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int i;
drawSurf_t *drawSurf;
int oldSort;
- float originalTime;
+ double originalTime;
FBO_t* fbo = NULL;
qboolean inQuery = qfalse;
@@ -568,7 +568,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
if ( entityNum != REFENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
- backEnd.refdef.floatTime = originalTime; // - backEnd.currentEntity->e.shaderTime; // JPW NERVE pulled this to match q3ta
+
+ // FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues
+ backEnd.refdef.floatTime = originalTime; // - (double)backEnd.currentEntity->e.shaderTime; // JPW NERVE pulled this to match q3ta
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
@@ -734,7 +736,7 @@ void RB_SetGL2D( void ) {
// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();
- backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
+ backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
}
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index 6c7e30f..2e9d099 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -518,37 +518,14 @@ typedef struct shader_s {
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
struct shader_s *remappedShader; // current shader this one is remapped too
struct shader_s *next;
} shader_t;
-static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
-{
- if(shader->numDeforms)
- {
- const deformStage_t *ds = &shader->deforms[0];
-
- if (shader->numDeforms > 1)
- return qtrue;
-
- switch (ds->deformation)
- {
- case DEFORM_WAVE:
- case DEFORM_BULGE:
- return qfalse;
-
- default:
- return qtrue;
- }
- }
-
- return qfalse;
-}
-
typedef struct cubemap_s {
char name[MAX_QPATH];
vec3_t origin;
@@ -823,7 +800,7 @@ typedef struct {
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
float blurFactor;
@@ -1997,9 +1974,35 @@ extern cvar_t *r_wolffog;
extern cvar_t *r_highQualityVideo;
//====================================================================
-float R_NoiseGet4f( float x, float y, float z, float t );
+float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
+static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
+{
+ if(shader->numDeforms)
+ {
+ const deformStage_t *ds = &shader->deforms[0];
+
+ if (shader->numDeforms > 1)
+ return qtrue;
+
+ switch (ds->deformation)
+ {
+ case DEFORM_WAVE:
+ case DEFORM_BULGE:
+ // need CPU deforms at high level-times to avoid floating point percision loss
+ return ( backEnd.refdef.floatTime != (float)backEnd.refdef.floatTime );
+
+ default:
+ return qtrue;
+ }
+ }
+
+ return qfalse;
+}
+
+//====================================================================
+
void R_SwapBuffers( int );
void R_RenderView( viewParms_t *parms );
@@ -2214,7 +2217,7 @@ typedef struct shaderCommands_s
//color4ub_t constantColor255[SHADER_MAX_VERTEXES] QALIGN(16);
shader_t *shader;
- float shaderTime;
+ double shaderTime;
int fogNum;
int cubemapIndex;
diff --git a/MP/code/rend2/tr_noise.c b/MP/code/rend2/tr_noise.c
index 2ad2385..7505680 100644
--- a/MP/code/rend2/tr_noise.c
+++ b/MP/code/rend2/tr_noise.c
@@ -56,7 +56,7 @@ void R_NoiseInit( void ) {
}
}
-float R_NoiseGet4f( float x, float y, float z, float t ) {
+float R_NoiseGet4f( float x, float y, float z, double t ) {
int i;
int ix, iy, iz, it;
float fx, fy, fz, ft;
diff --git a/MP/code/rend2/tr_scene.c b/MP/code/rend2/tr_scene.c
index cffe6c9..8a81480 100644
--- a/MP/code/rend2/tr_scene.c
+++ b/MP/code/rend2/tr_scene.c
@@ -516,7 +516,7 @@ void RE_BeginScene(const refdef_t *fd)
// derived info
- tr.refdef.floatTime = tr.refdef.time * 0.001f;
+ tr.refdef.floatTime = tr.refdef.time * 0.001;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/MP/code/rend2/tr_shade.c b/MP/code/rend2/tr_shade.c
index 424297e..83b9fbf 100644
--- a/MP/code/rend2/tr_shade.c
+++ b/MP/code/rend2/tr_shade.c
@@ -71,7 +71,7 @@ R_BindAnimatedImageToTMU
=================
*/
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
- int index;
+ int64_t index;
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic(bundle->videoMapHandle);
@@ -91,7 +91,7 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
// 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 = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
index >>= FUNCTABLE_SIZE2;
if ( index < 0 ) {
diff --git a/MP/code/rend2/tr_shade_calc.c b/MP/code/rend2/tr_shade_calc.c
index cc1ed17..e99ccc5 100644
--- a/MP/code/rend2/tr_shade_calc.c
+++ b/MP/code/rend2/tr_shade_calc.c
@@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "tr_local.h"
-#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[ ( ( int64_t ) ( ( ( phase ) + tess.shaderTime * ( freq ) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * ( amplitude ) )
static float *TableForFunc( genFunc_t func ) {
switch ( func )
@@ -259,12 +259,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
int16_t *normal = tess.normal[0];
- float now;
+ double now;
- now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+ now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 2, normal += 4 ) {
- int off;
+ int64_t off;
float scale;
vec3_t fNormal;
@@ -876,8 +876,8 @@ void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
*/
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
{
- float timeScale = tess.shaderTime;
- float adjustedScrollS, adjustedScrollT;
+ double timeScale = tess.shaderTime;
+ double adjustedScrollS, adjustedScrollT;
adjustedScrollS = scrollSpeed[0] * timeScale;
adjustedScrollT = scrollSpeed[1] * timeScale;
@@ -905,9 +905,9 @@ void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix )
*/
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
{
- float timeScale = tess.shaderTime;
- float degs;
- int index;
+ double timeScale = tess.shaderTime;
+ double degs;
+ int64_t index;
float sinValue, cosValue;
degs = -degsPerSecond * timeScale;
diff --git a/MP/code/renderer/tr_backend.c b/MP/code/renderer/tr_backend.c
index 235de69..1d9f76e 100644
--- a/MP/code/renderer/tr_backend.c
+++ b/MP/code/renderer/tr_backend.c
@@ -568,7 +568,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int i;
drawSurf_t *drawSurf;
int oldSort;
- float originalTime;
+ double originalTime;
// save original time for entity shader offsets
originalTime = backEnd.refdef.floatTime;
@@ -621,7 +621,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
if ( entityNum != REFENTITYNUM_WORLD ) {
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
- backEnd.refdef.floatTime = originalTime; // - backEnd.currentEntity->e.shaderTime; // JPW NERVE pulled this to match q3ta
+
+ // FIXME: e.shaderTime must be passed as int to avoid fp-precision loss issues
+ backEnd.refdef.floatTime = originalTime; // - (double)backEnd.currentEntity->e.shaderTime; // JPW NERVE pulled this to match q3ta
// we have to reset the shaderTime as well otherwise image animations start
// from the wrong frame
@@ -777,7 +779,7 @@ void RB_SetGL2D( void ) {
// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();
- backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
+ backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
}
diff --git a/MP/code/renderer/tr_local.h b/MP/code/renderer/tr_local.h
index b03b80a..9f39dad 100644
--- a/MP/code/renderer/tr_local.h
+++ b/MP/code/renderer/tr_local.h
@@ -425,8 +425,8 @@ typedef struct shader_s {
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
struct shader_s *remappedShader; // current shader this one is remapped too
@@ -477,7 +477,7 @@ typedef struct {
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];
@@ -1269,7 +1269,7 @@ extern cvar_t *r_wolffog;
extern cvar_t *r_highQualityVideo;
//====================================================================
-float R_NoiseGet4f( float x, float y, float z, float t );
+float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
void R_SwapBuffers( int );
@@ -1463,7 +1463,7 @@ typedef struct shaderCommands_s
color4ub_t constantColor255[SHADER_MAX_VERTEXES] QALIGN(16);
shader_t *shader;
- float shaderTime;
+ double shaderTime;
int fogNum;
int dlightBits; // or together of all vertexDlightBits
diff --git a/MP/code/renderer/tr_noise.c b/MP/code/renderer/tr_noise.c
index cd49009..bb91a1f 100644
--- a/MP/code/renderer/tr_noise.c
+++ b/MP/code/renderer/tr_noise.c
@@ -54,7 +54,7 @@ void R_NoiseInit( void ) {
}
}
-float R_NoiseGet4f( float x, float y, float z, float t ) {
+float R_NoiseGet4f( float x, float y, float z, double t ) {
int i;
int ix, iy, iz, it;
float fx, fy, fz, ft;
diff --git a/MP/code/renderer/tr_scene.c b/MP/code/renderer/tr_scene.c
index ce5dba2..6de3124 100644
--- a/MP/code/renderer/tr_scene.c
+++ b/MP/code/renderer/tr_scene.c
@@ -461,7 +461,7 @@ void RE_RenderScene( const refdef_t *fd ) {
// derived info
- tr.refdef.floatTime = tr.refdef.time * 0.001f;
+ tr.refdef.floatTime = tr.refdef.time * 0.001;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/MP/code/renderer/tr_shade.c b/MP/code/renderer/tr_shade.c
index 0aa2890..f91a711 100644
--- a/MP/code/renderer/tr_shade.c
+++ b/MP/code/renderer/tr_shade.c
@@ -243,7 +243,7 @@ R_BindAnimatedImage
=================
*/
static void R_BindAnimatedImage( textureBundle_t *bundle ) {
- int index;
+ int64_t index;
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic( bundle->videoMapHandle );
@@ -262,7 +262,7 @@ static void R_BindAnimatedImage( textureBundle_t *bundle ) {
// 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 = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
index >>= FUNCTABLE_SIZE2;
if ( index < 0 ) {
diff --git a/MP/code/renderer/tr_shade_calc.c b/MP/code/renderer/tr_shade_calc.c
index ef4a710..38eb38e 100644
--- a/MP/code/renderer/tr_shade_calc.c
+++ b/MP/code/renderer/tr_shade_calc.c
@@ -34,7 +34,7 @@ If you have questions concerning this license or the applicable additional terms
#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[ ( ( int64_t ) ( ( ( phase ) + tess.shaderTime * ( freq ) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * ( amplitude ) )
static float *TableForFunc( genFunc_t func ) {
switch ( func )
@@ -257,12 +257,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
float *normal = ( float * ) tess.normal;
- float now;
+ double now;
- now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+ now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
- int off;
+ int64_t off;
float scale;
off = (float)( FUNCTABLE_SIZE / ( M_PI * 2 ) ) * ( st[0] * ds->bulgeWidth + now );
@@ -1011,7 +1011,7 @@ void RB_CalcSwapTexCoords( float *st ) {
*/
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) {
int i;
- float now;
+ double now;
now = ( wf->phase + tess.shaderTime * wf->frequency );
@@ -1020,8 +1020,8 @@ void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) {
float s = st[0];
float t = st[1];
- st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] ) * 1.0 / 128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
- st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0 / 128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+ st[0] = s + tr.sinTable[ ( ( int64_t ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+ st[1] = t + tr.sinTable[ ( ( int64_t ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
}
}
@@ -1043,8 +1043,8 @@ void RB_CalcScaleTexCoords( const float scale[2], float *st ) {
*/
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st ) {
int i;
- float timeScale = tess.shaderTime;
- float adjustedScrollS, adjustedScrollT;
+ double timeScale = tess.shaderTime;
+ double adjustedScrollS, adjustedScrollT;
adjustedScrollS = scrollSpeed[0] * timeScale;
adjustedScrollT = scrollSpeed[1] * timeScale;
@@ -1081,9 +1081,9 @@ void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st ) {
** RB_CalcRotateTexCoords
*/
void RB_CalcRotateTexCoords( float degsPerSecond, float *st ) {
- float timeScale = tess.shaderTime;
- float degs;
- int index;
+ double timeScale = tess.shaderTime;
+ double degs;
+ int64_t index;
float sinValue, cosValue;
texModInfo_t tmi;
diff --git a/SP/code/rend2/tr_backend.c b/SP/code/rend2/tr_backend.c
index 103052e..2ad2b56 100644
--- a/SP/code/rend2/tr_backend.c
+++ b/SP/code/rend2/tr_backend.c
@@ -810,7 +810,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int i;
drawSurf_t *drawSurf;
int oldSort;
- float originalTime;
+ double originalTime;
FBO_t* fbo = NULL;
qboolean inQuery = qfalse;
@@ -902,7 +902,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
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
@@ -1085,7 +1087,7 @@ void RB_SetGL2D( void ) {
// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();
- backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
+ backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
}
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index 48f9ae1..885e3ca 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -521,37 +521,14 @@ typedef struct shader_s {
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
struct shader_s *remappedShader; // current shader this one is remapped too
struct shader_s *next;
} shader_t;
-static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
-{
- if(shader->numDeforms)
- {
- const deformStage_t *ds = &shader->deforms[0];
-
- if (shader->numDeforms > 1)
- return qtrue;
-
- switch (ds->deformation)
- {
- case DEFORM_WAVE:
- case DEFORM_BULGE:
- return qfalse;
-
- default:
- return qtrue;
- }
- }
-
- return qfalse;
-}
-
typedef struct cubemap_s {
char name[MAX_QPATH];
vec3_t origin;
@@ -827,7 +804,7 @@ typedef struct {
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
float blurFactor;
@@ -2017,9 +1994,35 @@ extern cvar_t *r_wolffog;
extern cvar_t *r_highQualityVideo;
//====================================================================
-float R_NoiseGet4f( float x, float y, float z, float t );
+float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
+static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
+{
+ if(shader->numDeforms)
+ {
+ const deformStage_t *ds = &shader->deforms[0];
+
+ if (shader->numDeforms > 1)
+ return qtrue;
+
+ switch (ds->deformation)
+ {
+ case DEFORM_WAVE:
+ case DEFORM_BULGE:
+ // need CPU deforms at high level-times to avoid floating point percision loss
+ return ( backEnd.refdef.floatTime != (float)backEnd.refdef.floatTime );
+
+ default:
+ return qtrue;
+ }
+ }
+
+ return qfalse;
+}
+
+//====================================================================
+
void R_SwapBuffers( int );
void R_RenderView( viewParms_t *parms );
@@ -2242,7 +2245,7 @@ typedef struct shaderCommands_s
//color4ub_t constantColor255[SHADER_MAX_VERTEXES] QALIGN(16);
shader_t *shader;
- float shaderTime;
+ double shaderTime;
int fogNum;
int cubemapIndex;
diff --git a/SP/code/rend2/tr_noise.c b/SP/code/rend2/tr_noise.c
index c218b97..da590fb 100644
--- a/SP/code/rend2/tr_noise.c
+++ b/SP/code/rend2/tr_noise.c
@@ -56,7 +56,7 @@ void R_NoiseInit( void ) {
}
}
-float R_NoiseGet4f( float x, float y, float z, float t ) {
+float R_NoiseGet4f( float x, float y, float z, double t ) {
int i;
int ix, iy, iz, it;
float fx, fy, fz, ft;
diff --git a/SP/code/rend2/tr_scene.c b/SP/code/rend2/tr_scene.c
index 7c50dcb..c73de51 100644
--- a/SP/code/rend2/tr_scene.c
+++ b/SP/code/rend2/tr_scene.c
@@ -529,7 +529,7 @@ void RE_BeginScene(const refdef_t *fd)
// derived info
- tr.refdef.floatTime = tr.refdef.time * 0.001f;
+ tr.refdef.floatTime = tr.refdef.time * 0.001;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/SP/code/rend2/tr_shade.c b/SP/code/rend2/tr_shade.c
index de5ff28..70dd53c 100644
--- a/SP/code/rend2/tr_shade.c
+++ b/SP/code/rend2/tr_shade.c
@@ -64,7 +64,7 @@ R_BindAnimatedImageToTMU
=================
*/
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
- int index;
+ int64_t index;
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic(bundle->videoMapHandle);
@@ -84,7 +84,7 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
// 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 = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
index >>= FUNCTABLE_SIZE2;
if ( index < 0 ) {
diff --git a/SP/code/rend2/tr_shade_calc.c b/SP/code/rend2/tr_shade_calc.c
index a946dbd..d77219a 100644
--- a/SP/code/rend2/tr_shade_calc.c
+++ b/SP/code/rend2/tr_shade_calc.c
@@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms
#include "tr_local.h"
-#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[ ( ( int64_t ) ( ( ( phase ) + tess.shaderTime * ( freq ) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * ( amplitude ) )
static float *TableForFunc( genFunc_t func ) {
switch ( func )
@@ -259,12 +259,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
int16_t *normal = tess.normal[0];
- float now;
+ double now;
- now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+ now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 2, normal += 4 ) {
- int off;
+ int64_t off;
float scale;
vec3_t fNormal;
@@ -877,8 +877,8 @@ void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
*/
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
{
- float timeScale = tess.shaderTime;
- float adjustedScrollS, adjustedScrollT;
+ double timeScale = tess.shaderTime;
+ double adjustedScrollS, adjustedScrollT;
adjustedScrollS = scrollSpeed[0] * timeScale;
adjustedScrollT = scrollSpeed[1] * timeScale;
@@ -906,9 +906,9 @@ void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix )
*/
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
{
- float timeScale = tess.shaderTime;
- float degs;
- int index;
+ double timeScale = tess.shaderTime;
+ double degs;
+ int64_t index;
float sinValue, cosValue;
degs = -degsPerSecond * timeScale;
diff --git a/SP/code/renderer/tr_backend.c b/SP/code/renderer/tr_backend.c
index 50d6281..cf92360 100644
--- a/SP/code/renderer/tr_backend.c
+++ b/SP/code/renderer/tr_backend.c
@@ -870,7 +870,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int i;
drawSurf_t *drawSurf;
int oldSort;
- float originalTime;
+ double originalTime;
int oldNumVerts, oldNumIndex;
//GR - tessellation flag
int atiTess = 0, oldAtiTess;
@@ -948,7 +948,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
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
@@ -1121,7 +1123,7 @@ void RB_SetGL2D( void ) {
// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();
- backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
+ backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
}
diff --git a/SP/code/renderer/tr_local.h b/SP/code/renderer/tr_local.h
index 7f83c54..df9266e 100644
--- a/SP/code/renderer/tr_local.h
+++ b/SP/code/renderer/tr_local.h
@@ -428,8 +428,8 @@ typedef struct shader_s {
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
struct shader_s *remappedShader; // current shader this one is remapped too
@@ -481,7 +481,7 @@ typedef struct {
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];
@@ -1289,7 +1289,7 @@ extern cvar_t *r_wolffog;
extern cvar_t *r_highQualityVideo;
//====================================================================
-float R_NoiseGet4f( float x, float y, float z, float t );
+float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
void R_SwapBuffers( int );
@@ -1489,7 +1489,7 @@ typedef struct shaderCommands_s
color4ub_t constantColor255[SHADER_MAX_VERTEXES] QALIGN(16);
shader_t *shader;
- float shaderTime;
+ double shaderTime;
int fogNum;
int dlightBits; // or together of all vertexDlightBits
diff --git a/SP/code/renderer/tr_noise.c b/SP/code/renderer/tr_noise.c
index b33672a..227f1f4 100644
--- a/SP/code/renderer/tr_noise.c
+++ b/SP/code/renderer/tr_noise.c
@@ -54,7 +54,7 @@ void R_NoiseInit( void ) {
}
}
-float R_NoiseGet4f( float x, float y, float z, float t ) {
+float R_NoiseGet4f( float x, float y, float z, double t ) {
int i;
int ix, iy, iz, it;
float fx, fy, fz, ft;
diff --git a/SP/code/renderer/tr_scene.c b/SP/code/renderer/tr_scene.c
index 78b511a..43af1d3 100644
--- a/SP/code/renderer/tr_scene.c
+++ b/SP/code/renderer/tr_scene.c
@@ -474,7 +474,7 @@ void RE_RenderScene( const refdef_t *fd ) {
// derived info
- tr.refdef.floatTime = tr.refdef.time * 0.001f;
+ tr.refdef.floatTime = tr.refdef.time * 0.001;
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/SP/code/renderer/tr_shade.c b/SP/code/renderer/tr_shade.c
index ba76811..e31834e 100644
--- a/SP/code/renderer/tr_shade.c
+++ b/SP/code/renderer/tr_shade.c
@@ -241,7 +241,7 @@ R_BindAnimatedImage
=================
*/
static void R_BindAnimatedImage( textureBundle_t *bundle ) {
- int index;
+ int64_t index;
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic( bundle->videoMapHandle );
@@ -260,7 +260,7 @@ static void R_BindAnimatedImage( textureBundle_t *bundle ) {
// 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 = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
index >>= FUNCTABLE_SIZE2;
if ( index < 0 ) {
diff --git a/SP/code/renderer/tr_shade_calc.c b/SP/code/renderer/tr_shade_calc.c
index e3c36c2..66388bd 100644
--- a/SP/code/renderer/tr_shade_calc.c
+++ b/SP/code/renderer/tr_shade_calc.c
@@ -34,7 +34,7 @@ If you have questions concerning this license or the applicable additional terms
#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[ ( ( int64_t ) ( ( ( phase ) + tess.shaderTime * ( freq ) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * ( amplitude ) )
static float *TableForFunc( genFunc_t func ) {
switch ( func )
@@ -257,12 +257,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
const float *st = ( const float * ) tess.texCoords[0];
float *xyz = ( float * ) tess.xyz;
float *normal = ( float * ) tess.normal;
- float now;
+ double now;
- now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+ now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
- int off;
+ int64_t off;
float scale;
off = (float)( FUNCTABLE_SIZE / ( M_PI * 2 ) ) * ( st[0] * ds->bulgeWidth + now );
@@ -1011,7 +1011,7 @@ void RB_CalcSwapTexCoords( float *st ) {
*/
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) {
int i;
- float now;
+ double now;
now = ( wf->phase + tess.shaderTime * wf->frequency );
@@ -1020,8 +1020,8 @@ void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st ) {
float s = st[0];
float t = st[1];
- st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] ) * 1.0 / 128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
- st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0 / 128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+ st[0] = s + tr.sinTable[ ( ( int64_t ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+ st[1] = t + tr.sinTable[ ( ( int64_t ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
}
}
@@ -1043,8 +1043,8 @@ void RB_CalcScaleTexCoords( const float scale[2], float *st ) {
*/
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st ) {
int i;
- float timeScale = tess.shaderTime;
- float adjustedScrollS, adjustedScrollT;
+ double timeScale = tess.shaderTime;
+ double adjustedScrollS, adjustedScrollT;
adjustedScrollS = scrollSpeed[0] * timeScale;
adjustedScrollT = scrollSpeed[1] * timeScale;
@@ -1081,9 +1081,9 @@ void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st ) {
** RB_CalcRotateTexCoords
*/
void RB_CalcRotateTexCoords( float degsPerSecond, float *st ) {
- float timeScale = tess.shaderTime;
- float degs;
- int index;
+ double timeScale = tess.shaderTime;
+ double degs;
+ int64_t index;
float sinValue, cosValue;
texModInfo_t tmi;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git
More information about the Pkg-games-commits
mailing list