mirror of
https://github.com/UberGames/ioef.git
synced 2025-06-01 09:41:57 +00:00
Fix for flares. Can be enabled by setting r_flares 1
This commit is contained in:
parent
7aed801011
commit
c552a46e5f
5 changed files with 121 additions and 86 deletions
|
@ -75,6 +75,7 @@ typedef struct flare_s {
|
||||||
int windowX, windowY;
|
int windowX, windowY;
|
||||||
float eyeZ;
|
float eyeZ;
|
||||||
|
|
||||||
|
vec3_t origin;
|
||||||
vec3_t color;
|
vec3_t color;
|
||||||
} flare_t;
|
} flare_t;
|
||||||
|
|
||||||
|
@ -83,6 +84,8 @@ typedef struct flare_s {
|
||||||
flare_t r_flareStructs[MAX_FLARES];
|
flare_t r_flareStructs[MAX_FLARES];
|
||||||
flare_t *r_activeFlares, *r_inactiveFlares;
|
flare_t *r_activeFlares, *r_inactiveFlares;
|
||||||
|
|
||||||
|
int flareCoeff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
R_ClearFlares
|
R_ClearFlares
|
||||||
|
@ -113,11 +116,22 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t
|
||||||
int i;
|
int i;
|
||||||
flare_t *f, *oldest;
|
flare_t *f, *oldest;
|
||||||
vec3_t local;
|
vec3_t local;
|
||||||
float d;
|
float d = 1;
|
||||||
vec4_t eye, clip, normalized, window;
|
vec4_t eye, clip, normalized, window;
|
||||||
|
|
||||||
backEnd.pc.c_flareAdds++;
|
backEnd.pc.c_flareAdds++;
|
||||||
|
|
||||||
|
if(normal && (normal[0] || normal[1] || normal[2]))
|
||||||
|
{
|
||||||
|
VectorSubtract( backEnd.viewParms.or.origin, point, local );
|
||||||
|
VectorNormalizeFast(local);
|
||||||
|
d = DotProduct(local, normal);
|
||||||
|
|
||||||
|
// If the viewer is behind the flare don't add it.
|
||||||
|
if(d < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if the point is off the screen, don't bother adding it
|
// if the point is off the screen, don't bother adding it
|
||||||
// calculate screen coordinates and depth
|
// calculate screen coordinates and depth
|
||||||
R_TransformModelToClip( point, backEnd.or.modelMatrix,
|
R_TransformModelToClip( point, backEnd.or.modelMatrix,
|
||||||
|
@ -171,16 +185,12 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t
|
||||||
f->addedFrame = backEnd.viewParms.frameCount;
|
f->addedFrame = backEnd.viewParms.frameCount;
|
||||||
f->fogNum = fogNum;
|
f->fogNum = fogNum;
|
||||||
|
|
||||||
|
VectorCopy(point, f->origin);
|
||||||
VectorCopy( color, f->color );
|
VectorCopy( color, f->color );
|
||||||
|
|
||||||
// fade the intensity of the flare down as the
|
// fade the intensity of the flare down as the
|
||||||
// light surface turns away from the viewer
|
// light surface turns away from the viewer
|
||||||
if ( normal ) {
|
|
||||||
VectorSubtract( backEnd.viewParms.or.origin, point, local );
|
|
||||||
VectorNormalizeFast( local );
|
|
||||||
d = DotProduct( local, normal );
|
|
||||||
VectorScale( f->color, d, f->color );
|
VectorScale( f->color, d, f->color );
|
||||||
}
|
|
||||||
|
|
||||||
// save info needed to test
|
// save info needed to test
|
||||||
f->windowX = backEnd.viewParms.viewportX + window[0];
|
f->windowX = backEnd.viewParms.viewportX + window[0];
|
||||||
|
@ -197,16 +207,21 @@ RB_AddDlightFlares
|
||||||
void RB_AddDlightFlares( void ) {
|
void RB_AddDlightFlares( void ) {
|
||||||
dlight_t *l;
|
dlight_t *l;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
fog_t *fog;
|
fog_t *fog = NULL;
|
||||||
|
|
||||||
if ( !r_flares->integer ) {
|
if ( !r_flares->integer ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = backEnd.refdef.dlights;
|
l = backEnd.refdef.dlights;
|
||||||
|
|
||||||
|
if(tr.world)
|
||||||
fog = tr.world->fogs;
|
fog = tr.world->fogs;
|
||||||
|
|
||||||
for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
|
for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
|
||||||
|
|
||||||
|
if(fog)
|
||||||
|
{
|
||||||
// find which fog volume the light is in
|
// find which fog volume the light is in
|
||||||
for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
|
for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
|
||||||
fog = &tr.world->fogs[j];
|
fog = &tr.world->fogs[j];
|
||||||
|
@ -222,6 +237,9 @@ void RB_AddDlightFlares( void ) {
|
||||||
if ( j == tr.world->numfogs ) {
|
if ( j == tr.world->numfogs ) {
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
j = 0;
|
||||||
|
|
||||||
RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
|
RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
|
||||||
}
|
}
|
||||||
|
@ -294,15 +312,60 @@ void RB_RenderFlare( flare_t *f ) {
|
||||||
float size;
|
float size;
|
||||||
vec3_t color;
|
vec3_t color;
|
||||||
int iColor[3];
|
int iColor[3];
|
||||||
|
float distance, intensity, factor;
|
||||||
|
byte fogFactors[3] = {255, 255, 255};
|
||||||
|
|
||||||
backEnd.pc.c_flareRenders++;
|
backEnd.pc.c_flareRenders++;
|
||||||
|
|
||||||
VectorScale( f->color, f->drawIntensity*tr.identityLight, color );
|
// We don't want too big values anyways when dividing by distance.
|
||||||
iColor[0] = color[0] * 255;
|
if(f->eyeZ > -1.0f)
|
||||||
iColor[1] = color[1] * 255;
|
distance = 1.0f;
|
||||||
iColor[2] = color[2] * 255;
|
else
|
||||||
|
distance = -f->eyeZ;
|
||||||
|
|
||||||
size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / -f->eyeZ );
|
// calculate the flare size..
|
||||||
|
size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an alternative to intensity scaling. It changes the size of the flare on screen instead
|
||||||
|
* with growing distance. See in the description at the top why this is not the way to go.
|
||||||
|
// size will change ~ 1/r.
|
||||||
|
size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f));
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As flare sizes stay nearly constant with increasing distance we must decrease the intensity
|
||||||
|
* to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be
|
||||||
|
* got by considering the ratio of
|
||||||
|
* (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare)
|
||||||
|
* An important requirement is:
|
||||||
|
* intensity <= 1 for all distances.
|
||||||
|
*
|
||||||
|
* The formula used here to compute the intensity is as follows:
|
||||||
|
* intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2
|
||||||
|
* As you can see, the intensity will have a max. of 1 when the distance is 0.
|
||||||
|
* The coefficient flareCoeff will determine the falloff speed with increasing distance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
factor = distance + size * sqrt(flareCoeff);
|
||||||
|
|
||||||
|
intensity = flareCoeff * size * size / (factor * factor);
|
||||||
|
|
||||||
|
VectorScale(f->color, f->drawIntensity * tr.identityLight * intensity, color);
|
||||||
|
|
||||||
|
// Calculations for fogging
|
||||||
|
if(f->fogNum)
|
||||||
|
{
|
||||||
|
tess.numVertexes = 1;
|
||||||
|
VectorCopy(f->origin, tess.xyz[0]);
|
||||||
|
tess.fogNum = f->fogNum;
|
||||||
|
|
||||||
|
RB_CalcModulateColorsByFog(fogFactors);
|
||||||
|
}
|
||||||
|
|
||||||
|
iColor[0] = color[0] * fogFactors[0];
|
||||||
|
iColor[1] = color[1] * fogFactors[1];
|
||||||
|
iColor[2] = color[2] * fogFactors[2];
|
||||||
|
|
||||||
RB_BeginSurface( tr.flareShader, f->fogNum );
|
RB_BeginSurface( tr.flareShader, f->fogNum );
|
||||||
|
|
||||||
|
@ -382,6 +445,21 @@ void RB_RenderFlares (void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(r_flareCoeff->modified)
|
||||||
|
{
|
||||||
|
if(r_flareCoeff->value == 0.0f)
|
||||||
|
flareCoeff = atof(FLARE_STDCOEFF);
|
||||||
|
else
|
||||||
|
flareCoeff = r_flareCoeff->value;
|
||||||
|
|
||||||
|
r_flareCoeff->modified = qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset currentEntity to world so that any previously referenced entities
|
||||||
|
// don't have influence on the rendering of these flares (i.e. RF_ renderer flags).
|
||||||
|
backEnd.currentEntity = &tr.worldEntity;
|
||||||
|
backEnd.or = backEnd.viewParms.world;
|
||||||
|
|
||||||
// RB_AddDlightFlares();
|
// RB_AddDlightFlares();
|
||||||
|
|
||||||
// perform z buffer readback on each flare in this view
|
// perform z buffer readback on each flare in this view
|
||||||
|
|
|
@ -30,6 +30,7 @@ static void GfxInfo_f( void );
|
||||||
|
|
||||||
cvar_t *r_flareSize;
|
cvar_t *r_flareSize;
|
||||||
cvar_t *r_flareFade;
|
cvar_t *r_flareFade;
|
||||||
|
cvar_t *r_flareCoeff;
|
||||||
|
|
||||||
cvar_t *r_railWidth;
|
cvar_t *r_railWidth;
|
||||||
cvar_t *r_railCoreWidth;
|
cvar_t *r_railCoreWidth;
|
||||||
|
@ -997,6 +998,7 @@ void R_Register( void )
|
||||||
|
|
||||||
r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
|
r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
|
||||||
r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
|
r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
|
||||||
|
r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", FLARE_STDCOEFF, CVAR_CHEAT);
|
||||||
|
|
||||||
r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
|
r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
|
||||||
r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
|
r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
|
||||||
|
|
|
@ -976,6 +976,9 @@ extern glstate_t glState; // outside of TR since it shouldn't be cleared during
|
||||||
//
|
//
|
||||||
extern cvar_t *r_flareSize;
|
extern cvar_t *r_flareSize;
|
||||||
extern cvar_t *r_flareFade;
|
extern cvar_t *r_flareFade;
|
||||||
|
// coefficient for the flare intensity falloff function.
|
||||||
|
#define FLARE_STDCOEFF "150"
|
||||||
|
extern cvar_t *r_flareCoeff;
|
||||||
|
|
||||||
extern cvar_t *r_railWidth;
|
extern cvar_t *r_railWidth;
|
||||||
extern cvar_t *r_railCoreWidth;
|
extern cvar_t *r_railCoreWidth;
|
||||||
|
|
|
@ -3010,6 +3010,17 @@ static void CreateInternalShaders( void ) {
|
||||||
static void CreateExternalShaders( void ) {
|
static void CreateExternalShaders( void ) {
|
||||||
tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
|
tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
|
||||||
tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
|
tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
|
||||||
|
|
||||||
|
// Hack to make fogging work correctly on flares. Fog colors are calculated
|
||||||
|
// in tr_flare.c already.
|
||||||
|
if(!tr.flareShader->defaultShader)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for(index = 0; index < tr.flareShader->numUnfoggedPasses; index++)
|
||||||
|
tr.flareShader->stages[index]->adjustColorsForFog = ACFF_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
|
tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1214,71 +1214,12 @@ void RB_SurfaceBad( surfaceType_t *surfType ) {
|
||||||
ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
|
ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void RB_SurfaceFlare(srfFlare_t *surf)
|
||||||
|
{
|
||||||
void RB_SurfaceFlare( srfFlare_t *surf ) {
|
if (r_flares->integer)
|
||||||
vec3_t left, up;
|
RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
|
||||||
float radius;
|
|
||||||
byte color[4];
|
|
||||||
vec3_t dir;
|
|
||||||
vec3_t origin;
|
|
||||||
float d;
|
|
||||||
|
|
||||||
// calculate the xyz locations for the four corners
|
|
||||||
radius = 30;
|
|
||||||
VectorScale( backEnd.viewParms.or.axis[1], radius, left );
|
|
||||||
VectorScale( backEnd.viewParms.or.axis[2], radius, up );
|
|
||||||
if ( backEnd.viewParms.isMirror ) {
|
|
||||||
VectorSubtract( vec3_origin, left, left );
|
|
||||||
}
|
|
||||||
|
|
||||||
color[0] = color[1] = color[2] = color[3] = 255;
|
|
||||||
|
|
||||||
VectorMA( surf->origin, 3, surf->normal, origin );
|
|
||||||
VectorSubtract( origin, backEnd.viewParms.or.origin, dir );
|
|
||||||
VectorNormalize( dir );
|
|
||||||
VectorMA( origin, r_ignore->value, dir, origin );
|
|
||||||
|
|
||||||
d = -DotProduct( dir, surf->normal );
|
|
||||||
if ( d < 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
color[0] *= d;
|
|
||||||
color[1] *= d;
|
|
||||||
color[2] *= d;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RB_AddQuadStamp( origin, left, up, color );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void RB_SurfaceFlare( srfFlare_t *surf ) {
|
|
||||||
#if 0
|
|
||||||
vec3_t left, up;
|
|
||||||
byte color[4];
|
|
||||||
|
|
||||||
color[0] = surf->color[0] * 255;
|
|
||||||
color[1] = surf->color[1] * 255;
|
|
||||||
color[2] = surf->color[2] * 255;
|
|
||||||
color[3] = 255;
|
|
||||||
|
|
||||||
VectorClear( left );
|
|
||||||
VectorClear( up );
|
|
||||||
|
|
||||||
left[0] = r_ignore->value;
|
|
||||||
|
|
||||||
up[1] = r_ignore->value;
|
|
||||||
|
|
||||||
RB_AddQuadStampExt( surf->origin, left, up, color, 0, 0, 1, 1 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
|
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
|
||||||
// all apropriate state must be set in RB_BeginSurface
|
// all apropriate state must be set in RB_BeginSurface
|
||||||
// this isn't implemented yet...
|
// this isn't implemented yet...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue