[ioquake3] 12/21: Fix floating point precision loss in renderer [part 1]
Simon McVittie
smcv at debian.org
Fri Aug 4 20:39:13 UTC 2017
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian/master
in repository ioquake3.
commit 30fdd88c9fecd152080044360fc33bbc65500b5d
Author: Zack Middleton <zack at cloemail.com>
Date: Wed Aug 2 22:39:27 2017 -0500
Fix floating point precision loss in renderer [part 1]
Patch for https://bugzilla.icculus.org/show_bug.cgi?id=5931 by
Eugene C. from 2013 plus recent fix for tcMod rotate.
I merged the changes into the OpenGL2 renderer though the fix for
tcMod turb doesn't translate.
---
code/renderergl1/tr_backend.c | 9 ++++++---
code/renderergl1/tr_local.h | 18 +++++++++---------
code/renderergl1/tr_shade.c | 9 ++++++---
code/renderergl1/tr_shade_calc.c | 20 +++++++++++---------
code/renderergl2/tr_backend.c | 9 ++++++---
code/renderergl2/tr_local.h | 18 +++++++++---------
code/renderergl2/tr_shade.c | 9 ++++++---
code/renderergl2/tr_shade_calc.c | 18 ++++++++++--------
8 files changed, 63 insertions(+), 47 deletions(-)
diff --git a/code/renderergl1/tr_backend.c b/code/renderergl1/tr_backend.c
index 41fe47a..22ec048 100644
--- a/code/renderergl1/tr_backend.c
+++ b/code/renderergl1/tr_backend.c
@@ -509,7 +509,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;
@@ -562,7 +562,10 @@ 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
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
@@ -713,7 +716,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 = (double)backEnd.refdef.time * 0.001f;
}
diff --git a/code/renderergl1/tr_local.h b/code/renderergl1/tr_local.h
index 37e0e07..54279a6 100644
--- a/code/renderergl1/tr_local.h
+++ b/code/renderergl1/tr_local.h
@@ -189,10 +189,10 @@ typedef enum {
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
@@ -252,7 +252,7 @@ typedef struct {
typedef struct {
image_t *image[MAX_IMAGE_ANIMATIONS];
int numImageAnimations;
- float imageAnimationSpeed;
+ double imageAnimationSpeed;
texCoordGen_t tcGen;
vec3_t tcGenVectors[2];
@@ -362,8 +362,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
@@ -388,7 +388,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];
@@ -1217,7 +1217,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/code/renderergl1/tr_shade.c b/code/renderergl1/tr_shade.c
index d26cb1a..ab5813f 100644
--- a/code/renderergl1/tr_shade.c
+++ b/code/renderergl1/tr_shade.c
@@ -218,7 +218,8 @@ R_BindAnimatedImage
=================
*/
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 @@ 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 >>= 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
diff --git a/code/renderergl1/tr_shade_calc.c b/code/renderergl1/tr_shade_calc.c
index 82f7c0c..34975e2 100644
--- a/code/renderergl1/tr_shade_calc.c
+++ b/code/renderergl1/tr_shade_calc.c
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#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_CalcEnvironmentTexCoords( float *st )
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_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;
+ double adjustedScrollS, adjustedScrollT;
- adjustedScrollS = scrollSpeed[0] * timeScale;
- adjustedScrollT = scrollSpeed[1] * timeScale;
+ timeScale = tess.shaderTime;
+
+ adjustedScrollS = (double)scrollSpeed[0] * timeScale;
+ adjustedScrollT = (double)scrollSpeed[1] * timeScale;
// clamp so coordinates don't continuously get larger, causing problems
// with hardware limits
@@ -994,9 +996,9 @@ void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st )
*/
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/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c
index d6ff122..4f8f3f4 100644
--- a/code/renderergl2/tr_backend.c
+++ b/code/renderergl2/tr_backend.c
@@ -433,7 +433,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;
@@ -498,7 +498,10 @@ 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
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
@@ -658,7 +661,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 = (double)backEnd.refdef.time * 0.001f;
}
diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h
index dd959d5..9426ede 100644
--- a/code/renderergl2/tr_local.h
+++ b/code/renderergl2/tr_local.h
@@ -268,10 +268,10 @@ typedef enum {
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
@@ -331,7 +331,7 @@ typedef struct {
typedef struct {
image_t *image[MAX_IMAGE_ANIMATIONS];
int numImageAnimations;
- float imageAnimationSpeed;
+ double imageAnimationSpeed;
texCoordGen_t tcGen;
vec3_t tcGenVectors[2];
@@ -471,8 +471,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
@@ -733,7 +733,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;
@@ -1978,7 +1978,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/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c
index 657f507..0fd1548 100644
--- a/code/renderergl2/tr_shade.c
+++ b/code/renderergl2/tr_shade.c
@@ -65,7 +65,8 @@ R_BindAnimatedImageToTMU
=================
*/
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
- int index;
+ int64_t index;
+ double v;
if ( bundle->isVideoMap ) {
ri.CIN_RunCinematic(bundle->videoMapHandle);
@@ -81,8 +82,10 @@ 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 >>= 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
diff --git a/code/renderergl2/tr_shade_calc.c b/code/renderergl2/tr_shade_calc.c
index cb7bcf7..c411e03 100644
--- a/code/renderergl2/tr_shade_calc.c
+++ b/code/renderergl2/tr_shade_calc.c
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#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 )
{
@@ -776,16 +776,18 @@ 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;
+ double adjustedScrollS, adjustedScrollT;
+
+ timeScale = tess.shaderTime;
adjustedScrollS = scrollSpeed[0] * timeScale;
adjustedScrollT = scrollSpeed[1] * timeScale;
// clamp so coordinates don't continuously get larger, causing problems
// with hardware limits
- adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
- adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
+ adjustedScrollS = (double)adjustedScrollS - floor( adjustedScrollS );
+ adjustedScrollT = (double)adjustedScrollT - floor( adjustedScrollT );
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;
@@ -805,9 +807,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;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/ioquake3.git
More information about the Pkg-games-commits
mailing list