mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-10 23:02:01 +00:00
Fix floating point precision loss in renderer [part 2]
Fix floatTime using float precision instead of double using GCC. Fix R_BindAnimatedImage to be in sync with function table. Fix vertexDeform bulge, vertexDeform normals, noise wave function at high level time. Revert unnecessary float -> double conversions.
This commit is contained in:
parent
30fdd88c9f
commit
59b1262b82
12 changed files with 62 additions and 69 deletions
|
@ -116,7 +116,7 @@ extern cvar_t *r_saveFontData;
|
||||||
|
|
||||||
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
|
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
|
||||||
|
|
||||||
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_NoiseInit( void );
|
||||||
|
|
||||||
image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
|
image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
|
||||||
|
|
|
@ -49,7 +49,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 i;
|
||||||
int ix, iy, iz, it;
|
int ix, iy, iz, it;
|
||||||
|
|
|
@ -716,7 +716,7 @@ void RB_SetGL2D (void) {
|
||||||
|
|
||||||
// set time for 2D shaders
|
// set time for 2D shaders
|
||||||
backEnd.refdef.time = ri.Milliseconds();
|
backEnd.refdef.time = ri.Milliseconds();
|
||||||
backEnd.refdef.floatTime = (double)backEnd.refdef.time * 0.001f;
|
backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -189,10 +189,10 @@ typedef enum {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
genFunc_t func;
|
genFunc_t func;
|
||||||
|
|
||||||
double base;
|
float base;
|
||||||
double amplitude;
|
float amplitude;
|
||||||
double phase;
|
float phase;
|
||||||
double frequency;
|
float frequency;
|
||||||
} waveForm_t;
|
} waveForm_t;
|
||||||
|
|
||||||
#define TR_MAX_TEXMODS 4
|
#define TR_MAX_TEXMODS 4
|
||||||
|
@ -252,7 +252,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
image_t *image[MAX_IMAGE_ANIMATIONS];
|
image_t *image[MAX_IMAGE_ANIMATIONS];
|
||||||
int numImageAnimations;
|
int numImageAnimations;
|
||||||
double imageAnimationSpeed;
|
float imageAnimationSpeed;
|
||||||
|
|
||||||
texCoordGen_t tcGen;
|
texCoordGen_t tcGen;
|
||||||
vec3_t tcGenVectors[2];
|
vec3_t tcGenVectors[2];
|
||||||
|
|
|
@ -344,7 +344,7 @@ void RE_RenderScene( const refdef_t *fd ) {
|
||||||
|
|
||||||
// derived info
|
// 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.numDrawSurfs = r_firstSceneDrawSurf;
|
||||||
tr.refdef.drawSurfs = backEndData->drawSurfs;
|
tr.refdef.drawSurfs = backEndData->drawSurfs;
|
||||||
|
|
|
@ -219,7 +219,6 @@ R_BindAnimatedImage
|
||||||
*/
|
*/
|
||||||
static void R_BindAnimatedImage( textureBundle_t *bundle ) {
|
static void R_BindAnimatedImage( textureBundle_t *bundle ) {
|
||||||
int64_t index;
|
int64_t index;
|
||||||
double v;
|
|
||||||
|
|
||||||
if ( bundle->isVideoMap ) {
|
if ( bundle->isVideoMap ) {
|
||||||
ri.CIN_RunCinematic(bundle->videoMapHandle);
|
ri.CIN_RunCinematic(bundle->videoMapHandle);
|
||||||
|
@ -234,10 +233,8 @@ static void R_BindAnimatedImage( textureBundle_t *bundle ) {
|
||||||
|
|
||||||
// it is necessary to do this messy calc to make sure animations line up
|
// it is necessary to do this messy calc to make sure animations line up
|
||||||
// exactly with waveforms of the same frequency
|
// 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;
|
index >>= FUNCTABLE_SIZE2;
|
||||||
v = tess.shaderTime * bundle->imageAnimationSpeed;
|
|
||||||
index = v;
|
|
||||||
|
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
index = 0; // may happen with shader time offsets
|
index = 0; // may happen with shader time offsets
|
||||||
|
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ (int)( ( ( (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 )
|
static float *TableForFunc( genFunc_t func )
|
||||||
{
|
{
|
||||||
|
@ -206,12 +206,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
|
||||||
const float *st = ( const float * ) tess.texCoords[0];
|
const float *st = ( const float * ) tess.texCoords[0];
|
||||||
float *xyz = ( float * ) tess.xyz;
|
float *xyz = ( float * ) tess.xyz;
|
||||||
float *normal = ( float * ) tess.normal;
|
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 ) {
|
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
|
||||||
int off;
|
int64_t off;
|
||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
|
off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
|
||||||
|
@ -929,8 +929,8 @@ void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
|
||||||
float s = st[0];
|
float s = st[0];
|
||||||
float t = st[1];
|
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[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[ ( ( int ) ( ( tess.xyz[i][1] * 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,13 +954,11 @@ void RB_CalcScaleTexCoords( const float scale[2], float *st )
|
||||||
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
|
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double timeScale;
|
double timeScale = tess.shaderTime;
|
||||||
double adjustedScrollS, adjustedScrollT;
|
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
|
// clamp so coordinates don't continuously get larger, causing problems
|
||||||
// with hardware limits
|
// with hardware limits
|
||||||
|
|
|
@ -661,7 +661,7 @@ void RB_SetGL2D (void) {
|
||||||
|
|
||||||
// set time for 2D shaders
|
// set time for 2D shaders
|
||||||
backEnd.refdef.time = ri.Milliseconds();
|
backEnd.refdef.time = ri.Milliseconds();
|
||||||
backEnd.refdef.floatTime = (double)backEnd.refdef.time * 0.001f;
|
backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -268,10 +268,10 @@ typedef enum {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
genFunc_t func;
|
genFunc_t func;
|
||||||
|
|
||||||
double base;
|
float base;
|
||||||
double amplitude;
|
float amplitude;
|
||||||
double phase;
|
float phase;
|
||||||
double frequency;
|
float frequency;
|
||||||
} waveForm_t;
|
} waveForm_t;
|
||||||
|
|
||||||
#define TR_MAX_TEXMODS 4
|
#define TR_MAX_TEXMODS 4
|
||||||
|
@ -331,7 +331,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
image_t *image[MAX_IMAGE_ANIMATIONS];
|
image_t *image[MAX_IMAGE_ANIMATIONS];
|
||||||
int numImageAnimations;
|
int numImageAnimations;
|
||||||
double imageAnimationSpeed;
|
float imageAnimationSpeed;
|
||||||
|
|
||||||
texCoordGen_t tcGen;
|
texCoordGen_t tcGen;
|
||||||
vec3_t tcGenVectors[2];
|
vec3_t tcGenVectors[2];
|
||||||
|
@ -479,29 +479,6 @@ typedef struct shader_s {
|
||||||
struct shader_s *next;
|
struct shader_s *next;
|
||||||
} shader_t;
|
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ATTR_INDEX_POSITION = 0,
|
ATTR_INDEX_POSITION = 0,
|
||||||
|
@ -1791,6 +1768,32 @@ extern cvar_t *r_marksOnTriangleMeshes;
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
||||||
|
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_SwapBuffers( int );
|
||||||
|
|
||||||
void R_RenderView( viewParms_t *parms );
|
void R_RenderView( viewParms_t *parms );
|
||||||
|
|
|
@ -400,7 +400,7 @@ void RE_BeginScene(const refdef_t *fd)
|
||||||
|
|
||||||
// derived info
|
// 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.numDrawSurfs = r_firstSceneDrawSurf;
|
||||||
tr.refdef.drawSurfs = backEndData->drawSurfs;
|
tr.refdef.drawSurfs = backEndData->drawSurfs;
|
||||||
|
|
|
@ -66,7 +66,6 @@ R_BindAnimatedImageToTMU
|
||||||
*/
|
*/
|
||||||
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
|
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
|
||||||
int64_t index;
|
int64_t index;
|
||||||
double v;
|
|
||||||
|
|
||||||
if ( bundle->isVideoMap ) {
|
if ( bundle->isVideoMap ) {
|
||||||
ri.CIN_RunCinematic(bundle->videoMapHandle);
|
ri.CIN_RunCinematic(bundle->videoMapHandle);
|
||||||
|
@ -82,10 +81,8 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
|
||||||
|
|
||||||
// it is necessary to do this messy calc to make sure animations line up
|
// it is necessary to do this messy calc to make sure animations line up
|
||||||
// exactly with waveforms of the same frequency
|
// 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;
|
index >>= FUNCTABLE_SIZE2;
|
||||||
v = tess.shaderTime * bundle->imageAnimationSpeed;
|
|
||||||
index = v;
|
|
||||||
|
|
||||||
if ( index < 0 ) {
|
if ( index < 0 ) {
|
||||||
index = 0; // may happen with shader time offsets
|
index = 0; // may happen with shader time offsets
|
||||||
|
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ (int)( ( ( (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 )
|
static float *TableForFunc( genFunc_t func )
|
||||||
{
|
{
|
||||||
|
@ -204,12 +204,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
|
||||||
const float *st = ( const float * ) tess.texCoords[0];
|
const float *st = ( const float * ) tess.texCoords[0];
|
||||||
float *xyz = ( float * ) tess.xyz;
|
float *xyz = ( float * ) tess.xyz;
|
||||||
int16_t *normal = tess.normal[0];
|
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 ) {
|
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 2, normal += 4 ) {
|
||||||
int off;
|
int64_t off;
|
||||||
float scale;
|
float scale;
|
||||||
vec3_t fNormal;
|
vec3_t fNormal;
|
||||||
|
|
||||||
|
@ -776,18 +776,16 @@ void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
|
||||||
*/
|
*/
|
||||||
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
||||||
{
|
{
|
||||||
double timeScale;
|
double timeScale = tess.shaderTime;
|
||||||
double adjustedScrollS, adjustedScrollT;
|
double adjustedScrollS, adjustedScrollT;
|
||||||
|
|
||||||
timeScale = tess.shaderTime;
|
|
||||||
|
|
||||||
adjustedScrollS = scrollSpeed[0] * timeScale;
|
adjustedScrollS = scrollSpeed[0] * timeScale;
|
||||||
adjustedScrollT = scrollSpeed[1] * timeScale;
|
adjustedScrollT = scrollSpeed[1] * timeScale;
|
||||||
|
|
||||||
// clamp so coordinates don't continuously get larger, causing problems
|
// clamp so coordinates don't continuously get larger, causing problems
|
||||||
// with hardware limits
|
// with hardware limits
|
||||||
adjustedScrollS = (double)adjustedScrollS - floor( adjustedScrollS );
|
adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
|
||||||
adjustedScrollT = (double)adjustedScrollT - floor( adjustedScrollT );
|
adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
|
||||||
|
|
||||||
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
|
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
|
||||||
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;
|
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;
|
||||||
|
|
Loading…
Reference in a new issue