Flare-related speedup:

- r_flareDelay - delays the glReadPixels every specified tics to keep the video bus from being congested by excess reads (maps with way too many flares (i.e. pvomit) sohuld not slow down as much as before)
- TestFlareFast actually now is working as intended because of it
- normal high quality flare functionality moved to r_flareQuality 2.
- r_flareQuality default is now 1.
This commit is contained in:
leilei-
2016-02-22 00:47:59 -05:00
parent 444e8bc25f
commit ed43aa0c02
3 changed files with 112 additions and 73 deletions

View File

@@ -91,6 +91,7 @@ typedef struct flare_s {
// 8 - anamorphic like it's 2009
struct shader_s *theshader; // leilei - custom flare shaders
int type; // 0 - map, 1 - dlight, 2 - sun
float delay; // update delay time
} flare_t;
#define MAX_FLARES 256 // was 128
@@ -101,6 +102,8 @@ flare_t *r_activeFlares, *r_inactiveFlares;
vec3_t sunorg; // sun flare hack
int flareCoeff;
/*
==================
R_SetFlareCoeff
@@ -150,6 +153,7 @@ This is called at surface tesselation time
float flaredsize; // leilei - dirty flare fix for widescreens
void RB_AddFlare(srfFlare_t *surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal, int radii, int efftype, float scaled, int type) {
int i;
flare_t *f, *oldest;
@@ -356,51 +360,79 @@ static void RB_TestFlareFast( flare_t *f ) {
qboolean visible;
float fade;
float screenZ;
if (f->fadeTime == -666)
{
RB_TestFlareFast(f);
return;
}
backEnd.pc.c_flareTests++;
// doing a readpixels is as good as doing a glFinish(), so
// don't bother with another sync
glState.finishCalled = qfalse;
backEnd.pc.c_flareTests++;
// visible = 1; // it's visible damnit
// doing a readpixels is as good as doing a glFinish(), so
// don't bother with another sync
glState.finishCalled = qfalse;
// leilei - delay hack, to speed up the renderer
// read back the z buffer contents
if (backEnd.refdef.time > f->delay){
// read back the z buffer contents
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
f->delay = backEnd.refdef.time + r_flareDelay->value;
screenZ = backEnd.viewParms.projectionMatrix[14] /
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
visible = ( -f->eyeZ - -screenZ ) < 24;
screenZ = backEnd.viewParms.projectionMatrix[14] /
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
visible = ( -f->eyeZ - -screenZ ) < 24;
if ( visible ) {
if ( !f->visible ) {
f->visible = qtrue;
f->fadeTime = backEnd.refdef.time - 1;
if ( visible ) {
if ( !f->visible ) {
f->visible = qtrue;
f->fadeTime = backEnd.refdef.time - 1;
}
{
fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
}
} else {
if ( f->visible ) {
f->visible = qfalse;
f->fadeTime = backEnd.refdef.time - 1;
}
fade = 1.0f - ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
}
if ( fade < 0 ) {
fade = 0;
}
if ( fade > 1 ) {
fade = 1;
}
f->drawIntensity = fade;
}
else
// leilei - continue drawing the flare from where we last checked
{
if (f->visible) {
f->drawIntensity = 1;
}
else
{
fade = 1; // instant fade
f->drawIntensity = 0;
}
} else {
if ( f->visible ) {
f->visible = qfalse;
f->fadeTime = backEnd.refdef.time - 1;
}
fade = 0; // instant appear
}
if ( fade < 0 ) {
fade = 0;
}
if ( fade > 1 ) {
fade = 1;
}
f->drawIntensity = fade;
}
/*
@@ -414,54 +446,58 @@ static void RB_TestFlare( flare_t *f ) {
float fade;
float screenZ;
if (f->fadeTime == -666)
if (r_flareQuality->integer < 2)
{
RB_TestFlareFast(f);
RB_TestFlareFast(f); // leilei - use the faster hacky path
return;
}
backEnd.pc.c_flareTests++;
backEnd.pc.c_flareTests++;
// doing a readpixels is as good as doing a glFinish(), so
// don't bother with another sync
glState.finishCalled = qfalse;
// doing a readpixels is as good as doing a glFinish(), so
// don't bother with another sync
glState.finishCalled = qfalse;
// read back the z buffer contents
// read back the z buffer contents
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
screenZ = backEnd.viewParms.projectionMatrix[14] /
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
visible = ( -f->eyeZ - -screenZ ) < 24;
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
screenZ = backEnd.viewParms.projectionMatrix[14] /
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
visible = ( -f->eyeZ - -screenZ ) < 24;
if ( visible ) {
if ( !f->visible ) {
f->visible = qtrue;
f->fadeTime = backEnd.refdef.time - 1;
if ( visible ) {
if ( !f->visible ) {
f->visible = qtrue;
f->fadeTime = backEnd.refdef.time - 1;
}
{
fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
}
} else {
if ( f->visible ) {
f->visible = qfalse;
f->fadeTime = backEnd.refdef.time - 1;
}
fade = 1.0f - ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
}
{
fade = ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
if ( fade < 0 ) {
fade = 0;
}
} else {
if ( f->visible ) {
f->visible = qfalse;
f->fadeTime = backEnd.refdef.time - 1;
if ( fade > 1 ) {
fade = 1;
}
fade = 1.0f - ( ( backEnd.refdef.time - f->fadeTime ) / 1000.0f ) * r_flareFade->value;
}
if ( fade < 0 ) {
fade = 0;
}
if ( fade > 1 ) {
fade = 1;
}
f->drawIntensity = fade;
f->drawIntensity = fade;
}

View File

@@ -191,6 +191,7 @@ cvar_t *r_lensReflectionBrightness;
cvar_t *r_flareMethod; // method of flare intensity
cvar_t *r_flareQuality; // testing quality of the flares.
cvar_t *r_flareSun; // type of flare to use for the sun
cvar_t *r_flareDelay; // time delay for medium quality flare testing
cvar_t *r_specMode;
//cvar_t *r_waveMode;
@@ -1273,7 +1274,7 @@ void R_Register( void )
r_lensReflection2 = ri.Cvar_Get( "r_lensReflection2", "0" , CVAR_ARCHIVE); // fuzzy reflection
r_lensReflectionBrightness = ri.Cvar_Get( "r_lensReflectionBrightness", "0.5" , CVAR_ARCHIVE);
r_flareQuality = ri.Cvar_Get( "r_flareQuality", "0" , CVAR_ARCHIVE); // use fast flares for default
r_flareQuality = ri.Cvar_Get( "r_flareQuality", "1" , CVAR_ARCHIVE); // use medium flares for default
r_flareMethod = ri.Cvar_Get( "r_flareMethod", "0" , CVAR_ARCHIVE);
r_flaresDlight = ri.Cvar_Get( "r_flaresDlight", "0" , CVAR_ARCHIVE ); // dynamic light flares
r_flaresDlightShrink = ri.Cvar_Get( "r_flaresDlightShrink", "1" , CVAR_ARCHIVE ); // dynamic light flares shrinking when close (reducing muzzleflash blindness)
@@ -1281,6 +1282,7 @@ void R_Register( void )
r_flaresDlightOpacity = ri.Cvar_Get( "r_flaresDlightOpacity", "0.5" , CVAR_ARCHIVE ); // dynamic light flares (workaround poor visibility)
r_flaresDlightScale = ri.Cvar_Get( "r_flaresDlightScale", "0.7" , CVAR_ARCHIVE ); // dynamic light flares (workaround poor visibility)
r_flareSun = ri.Cvar_Get( "r_flareSun", "0" , CVAR_ARCHIVE); // it's 0 because mappers expect 0.
r_flareDelay = ri.Cvar_Get( "r_flareDelay", "100" , CVAR_CHEAT); // update delay for flare pixel read checking.
r_mockvr = ri.Cvar_Get( "r_mockvr", "0" , CVAR_CHEAT);

View File

@@ -1234,6 +1234,7 @@ extern cvar_t *r_flareFade;
extern cvar_t *r_flareQuality;
extern cvar_t *r_flareSun;
extern cvar_t *r_flareMethod;
extern cvar_t *r_flareDelay;
// coefficient for the flare intensity falloff function.
#define FLARE_STDCOEFF "150"