[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