mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-26 22:21:16 +00:00
Underwater / dead / hit / UI blur. Frustum culling for the sun flare.
This commit is contained in:
parent
61f08e2ddd
commit
4c7007f694
11 changed files with 204 additions and 26 deletions
|
@ -2710,6 +2710,25 @@ Makro - changed to 0..1 instead of 0/1
|
|||
*/
|
||||
#define MAX_DAMAGE_ALPHA 0.75
|
||||
#define MAX_BLEND_TIME 1500
|
||||
|
||||
static float CG_GetDamageBlendAlpha( void )
|
||||
{
|
||||
float dmg, blend = Com_Clamp(0, 1, cg_RQ3_painblend.value);
|
||||
|
||||
if (cg.rq3_blendTime <= 0.f)
|
||||
return 0.f;
|
||||
|
||||
//Clamp blend time
|
||||
if (cg.rq3_blendTime > MAX_BLEND_TIME)
|
||||
cg.rq3_blendTime = MAX_BLEND_TIME;
|
||||
|
||||
dmg = cg.rq3_trueDamage;
|
||||
dmg = blend * MAX_DAMAGE_ALPHA * (dmg / 100.0) * (1.0 - (cg.time - cg.damageTime) / cg.rq3_blendTime);
|
||||
dmg = Com_Clamp(0.f, MAX_DAMAGE_ALPHA, dmg);
|
||||
|
||||
return dmg;
|
||||
}
|
||||
|
||||
static void CG_DrawDamageBlend( void )
|
||||
{
|
||||
float dmg, blend = Com_Clamp(0, 1, cg_RQ3_painblend.value);
|
||||
|
@ -2863,6 +2882,36 @@ void CG_DrawBigPolygon(void) {
|
|||
trap_R_AddPolyToScene(cgs.media.blackHackShader, 4, Corners);
|
||||
}
|
||||
|
||||
static qboolean CG_UnderWater( void )
|
||||
{
|
||||
return 0 != (CG_PointContents(cg.refdef.vieworg, -1) & (CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA));
|
||||
}
|
||||
|
||||
static qboolean CG_IsDead( void )
|
||||
{
|
||||
return cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0;
|
||||
}
|
||||
|
||||
static void CG_SetupPostProcess( void )
|
||||
{
|
||||
cg.refdefex.blurFactor = CG_GetDamageBlendAlpha();
|
||||
|
||||
if (CG_UnderWater() || CG_IsDead())
|
||||
cg.refdefex.blurFactor = 1.f;
|
||||
if (CG_IsDead())
|
||||
cg.refdefex.blurFactor = 1.f;
|
||||
|
||||
if (trap_Key_GetCatcher() & KEYCATCH_UI)
|
||||
cg.refdefex.blurFactor = 1.f;
|
||||
|
||||
cg.refdefex.blurFactor = Com_Clamp(0.f, 1.f, cg.refdefex.blurFactor);
|
||||
|
||||
if (cg.refdefex.blurFactor > 0.f)
|
||||
{
|
||||
cg.refdef.rdflags |= RDF_EXTRA;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CG_DrawActive
|
||||
|
@ -2894,6 +2943,8 @@ void CG_DrawActive(stereoFrame_t stereoView)
|
|||
//Makro - sun flare
|
||||
CG_AddLensFlare(qtrue);
|
||||
|
||||
CG_SetupPostProcess();
|
||||
|
||||
// draw 3D view
|
||||
trap_R_RenderScene(&cg.refdef);
|
||||
|
||||
|
|
|
@ -1002,6 +1002,7 @@ typedef struct {
|
|||
|
||||
// view rendering
|
||||
refdef_t refdef;
|
||||
refdefex_t refdefex; // Makro - extra data to be sent to the renderer; it absolutely needs to follow refdef
|
||||
vec3_t refdefViewAngles; // will be converted to refdef.viewaxis
|
||||
|
||||
// zoom key
|
||||
|
|
|
@ -492,6 +492,8 @@ void CG_ParseSkyPortal(const char *str)
|
|||
cgs.sunDir[0] = atof(Info_ValueForKey(str, "lx"));
|
||||
cgs.sunDir[1] = atof(Info_ValueForKey(str, "ly"));
|
||||
cgs.sunDir[2] = atof(Info_ValueForKey(str, "lz"));
|
||||
VectorNormalize(cgs.sunDir);
|
||||
|
||||
alphamin = Com_Clamp(0.0f, 1.0f, atof(Info_ValueForKey(str, "lamin")));
|
||||
alphamax = Com_Clamp(0.0f, 1.0f, atof(Info_ValueForKey(str, "lamax")));
|
||||
sizemin = atof(Info_ValueForKey(str, "lsmin"));
|
||||
|
|
|
@ -48,6 +48,11 @@
|
|||
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
|
||||
#define RDF_HYPERSPACE 4 // teleportation effect
|
||||
#define RDF_NOFOG 8
|
||||
#define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t
|
||||
|
||||
typedef struct {
|
||||
float blurFactor;
|
||||
} refdefex_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t xyz;
|
||||
|
|
|
@ -412,6 +412,19 @@ void GL_State( unsigned long stateBits )
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// color mask
|
||||
//
|
||||
if ( diff & GLS_COLORMASK_BITS )
|
||||
{
|
||||
qglColorMask(
|
||||
(stateBits & GLS_REDMASK_FALSE) == 0,
|
||||
(stateBits & GLS_GREENMASK_FALSE) == 0,
|
||||
(stateBits & GLS_BLUEMASK_FALSE) == 0,
|
||||
(stateBits & GLS_ALPHAMASK_FALSE) == 0
|
||||
);
|
||||
}
|
||||
|
||||
glState.glStateBits = stateBits;
|
||||
}
|
||||
|
||||
|
@ -700,7 +713,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
|||
tr.sunFlareQueryActive[tr.sunFlareQueryIndex] = qtrue;
|
||||
qglBeginQueryARB(GL_SAMPLES_PASSED_ARB, tr.sunFlareQuery[tr.sunFlareQueryIndex]);
|
||||
}
|
||||
backEnd.hasSunFlare = qtrue;
|
||||
//backEnd.hasSunFlare = qtrue;
|
||||
sunflare = qtrue;
|
||||
} else {
|
||||
depthRange = qtrue;
|
||||
|
|
|
@ -1545,6 +1545,8 @@ typedef struct {
|
|||
|
||||
float floatTime; // tr.refdef.time / 1000.0
|
||||
|
||||
float blurFactor;
|
||||
|
||||
// text messages for deform text shaders
|
||||
char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
|
||||
|
||||
|
@ -2555,12 +2557,13 @@ void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * tr
|
|||
#define CULL_IN 0 // completely unclipped
|
||||
#define CULL_CLIP 1 // clipped by one or more planes
|
||||
#define CULL_OUT 2 // completely outside the clipping planes
|
||||
void R_LocalNormalToWorld (vec3_t local, vec3_t world);
|
||||
void R_LocalPointToWorld (vec3_t local, vec3_t world);
|
||||
void R_LocalNormalToWorld (const vec3_t local, vec3_t world);
|
||||
void R_LocalPointToWorld (const vec3_t local, vec3_t world);
|
||||
int R_CullBox (vec3_t bounds[2]);
|
||||
int R_CullLocalBox (vec3_t bounds[2]);
|
||||
int R_CullPointAndRadius( vec3_t origin, float radius );
|
||||
int R_CullLocalPointAndRadius( vec3_t origin, float radius );
|
||||
int R_CullPointAndRadiusEx( const vec3_t origin, float radius, const cplane_t* frustum, int numPlanes );
|
||||
int R_CullPointAndRadius( const vec3_t origin, float radius );
|
||||
int R_CullLocalPointAndRadius( const vec3_t origin, float radius );
|
||||
|
||||
void R_SetupProjection(viewParms_t *dest, float zProj, qboolean computeFrustum);
|
||||
void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *or );
|
||||
|
|
|
@ -270,7 +270,7 @@ int R_CullBox(vec3_t worldBounds[2]) {
|
|||
/*
|
||||
** R_CullLocalPointAndRadius
|
||||
*/
|
||||
int R_CullLocalPointAndRadius( vec3_t pt, float radius )
|
||||
int R_CullLocalPointAndRadius( const vec3_t pt, float radius )
|
||||
{
|
||||
vec3_t transformed;
|
||||
|
||||
|
@ -280,13 +280,14 @@ int R_CullLocalPointAndRadius( vec3_t pt, float radius )
|
|||
}
|
||||
|
||||
/*
|
||||
** R_CullPointAndRadius
|
||||
** R_CullPointAndRadiusEx
|
||||
*/
|
||||
int R_CullPointAndRadius( vec3_t pt, float radius )
|
||||
|
||||
int R_CullPointAndRadiusEx( const vec3_t pt, float radius, const cplane_t* frustum, int numPlanes )
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
cplane_t *frust;
|
||||
const cplane_t *frust;
|
||||
qboolean mightBeClipped = qfalse;
|
||||
|
||||
if ( r_nocull->integer ) {
|
||||
|
@ -294,9 +295,9 @@ int R_CullPointAndRadius( vec3_t pt, float radius )
|
|||
}
|
||||
|
||||
// check against frustum planes
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
for (i = 0 ; i < numPlanes ; i++)
|
||||
{
|
||||
frust = &tr.viewParms.frustum[i];
|
||||
frust = &frustum[i];
|
||||
|
||||
dist = DotProduct( pt, frust->normal) - frust->dist;
|
||||
if ( dist < -radius )
|
||||
|
@ -317,6 +318,14 @@ int R_CullPointAndRadius( vec3_t pt, float radius )
|
|||
return CULL_IN; // completely inside frustum
|
||||
}
|
||||
|
||||
/*
|
||||
** R_CullPointAndRadius
|
||||
*/
|
||||
int R_CullPointAndRadius( const vec3_t pt, float radius )
|
||||
{
|
||||
return R_CullPointAndRadiusEx(pt, radius, tr.viewParms.frustum, ARRAY_LEN(tr.viewParms.frustum));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -324,7 +333,7 @@ R_LocalNormalToWorld
|
|||
|
||||
=================
|
||||
*/
|
||||
void R_LocalNormalToWorld (vec3_t local, vec3_t world) {
|
||||
void R_LocalNormalToWorld (const vec3_t local, vec3_t world) {
|
||||
world[0] = local[0] * tr.or.axis[0][0] + local[1] * tr.or.axis[1][0] + local[2] * tr.or.axis[2][0];
|
||||
world[1] = local[0] * tr.or.axis[0][1] + local[1] * tr.or.axis[1][1] + local[2] * tr.or.axis[2][1];
|
||||
world[2] = local[0] * tr.or.axis[0][2] + local[1] * tr.or.axis[1][2] + local[2] * tr.or.axis[2][2];
|
||||
|
@ -336,7 +345,7 @@ R_LocalPointToWorld
|
|||
|
||||
=================
|
||||
*/
|
||||
void R_LocalPointToWorld (vec3_t local, vec3_t world) {
|
||||
void R_LocalPointToWorld (const vec3_t local, vec3_t world) {
|
||||
world[0] = local[0] * tr.or.axis[0][0] + local[1] * tr.or.axis[1][0] + local[2] * tr.or.axis[2][0] + tr.or.origin[0];
|
||||
world[1] = local[0] * tr.or.axis[0][1] + local[1] * tr.or.axis[1][1] + local[2] * tr.or.axis[2][1] + tr.or.origin[1];
|
||||
world[2] = local[0] * tr.or.axis[0][2] + local[1] * tr.or.axis[1][2] + local[2] * tr.or.axis[2][2] + tr.or.origin[2];
|
||||
|
@ -348,7 +357,7 @@ R_WorldToLocal
|
|||
|
||||
=================
|
||||
*/
|
||||
void R_WorldToLocal (vec3_t world, vec3_t local) {
|
||||
void R_WorldToLocal (const vec3_t world, vec3_t local) {
|
||||
local[0] = DotProduct(world, tr.or.axis[0]);
|
||||
local[1] = DotProduct(world, tr.or.axis[1]);
|
||||
local[2] = DotProduct(world, tr.or.axis[2]);
|
||||
|
|
|
@ -287,13 +287,13 @@ static void RB_GodRays(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void RB_BlurAxis(float w, float h, qboolean horizontal)
|
||||
static void RB_BlurAxis(float w, float h, float strength, qboolean horizontal)
|
||||
{
|
||||
float dx, dy;
|
||||
float xmul, ymul;
|
||||
float weights[3] = {
|
||||
0.316216216f,
|
||||
0.227027027f,
|
||||
0.316216216f,
|
||||
0.070270270f,
|
||||
};
|
||||
float offsets[3] = {
|
||||
|
@ -308,34 +308,104 @@ static void RB_BlurAxis(float w, float h, qboolean horizontal)
|
|||
xmul /= w;
|
||||
ymul /= h;
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
xmul *= strength;
|
||||
ymul *= strength;
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_ALPHAMASK_FALSE );
|
||||
|
||||
RB_Color4f(weights[0], weights[0], weights[0], 1.f);
|
||||
RB_Color4f(weights[0], weights[0], weights[0], 0.f);
|
||||
RB_DrawQuad(0.f, 0.f, w, h, 0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_ALPHAMASK_FALSE );
|
||||
|
||||
RB_Color4f(weights[1], weights[1], weights[1], 1.f);
|
||||
RB_Color4f(weights[1], weights[1], weights[1], 0.f);
|
||||
dx = offsets[1] * xmul;
|
||||
dy = offsets[1] * ymul;
|
||||
RB_DrawQuad(0.f, 0.f, w, h, dx, dy, 1.f+dx, 1.f+dy);
|
||||
RB_DrawQuad(0.f, 0.f, w, h, -dx, -dy, 1.f-dx, 1.f-dy);
|
||||
|
||||
RB_Color4f(weights[2], weights[2], weights[2], 1.f);
|
||||
RB_Color4f(weights[2], weights[2], weights[2], 0.f);
|
||||
dx = offsets[2] * xmul;
|
||||
dy = offsets[2] * ymul;
|
||||
RB_DrawQuad(0.f, 0.f, w, h, dx, dy, 1.f+dx, 1.f+dy);
|
||||
RB_DrawQuad(0.f, 0.f, w, h, -dx, -dy, 1.f-dx, 1.f-dy);
|
||||
}
|
||||
|
||||
static void RB_HBlur(float w, float h)
|
||||
static void RB_HBlur(float w, float h, float strength)
|
||||
{
|
||||
RB_BlurAxis(w, h, qtrue);
|
||||
RB_BlurAxis(w, h, strength, qtrue);
|
||||
}
|
||||
|
||||
static void RB_VBlur(float w, float h)
|
||||
static void RB_VBlur(float w, float h, float strength)
|
||||
{
|
||||
RB_BlurAxis(w, h, qfalse);
|
||||
RB_BlurAxis(w, h, strength, qfalse);
|
||||
}
|
||||
|
||||
static void RB_Blur(void)
|
||||
{
|
||||
float w, h, w2, h2, w4, h4;
|
||||
float mul = 1.f;
|
||||
float factor = Com_Clamp(0.f, 1.f, backEnd.refdef.blurFactor);
|
||||
int i;
|
||||
|
||||
if (factor <= 0.f)
|
||||
return;
|
||||
|
||||
// viewport dimensions
|
||||
w = glConfig.vidWidth;
|
||||
h = glConfig.vidHeight;
|
||||
w2 = glConfig.vidWidth / 2;
|
||||
h2 = glConfig.vidHeight / 2;
|
||||
w4 = glConfig.vidWidth / 4;
|
||||
h4 = glConfig.vidHeight / 4;
|
||||
|
||||
RB_SetGL2D_Level(1);
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
RB_Color4f(mul, mul, mul, 1.f);
|
||||
|
||||
// first, downsample the main framebuffers
|
||||
R_FBO_Bind(tr.fbo.quarter[0]);
|
||||
R_FBO_BindColorBuffer(tr.fbo.full[0], 0);
|
||||
RB_DrawQuad(0.f, 0.f, w2, h2, 0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
RB_SetGL2D_Level(2);
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
RB_Color4f(mul, mul, mul, 1.f);
|
||||
|
||||
R_FBO_Bind(tr.fbo.tiny[0]);
|
||||
|
||||
R_FBO_BindColorBuffer(tr.fbo.quarter[0], 0);
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
mul = 1.f;
|
||||
RB_Color4f(mul, mul, mul, 1.f);
|
||||
RB_DrawQuad(0.f, 0.f, w4, h4, 0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_REDMASK_FALSE | GLS_BLUEMASK_FALSE | GLS_GREENMASK_FALSE );
|
||||
GL_Bind(tr.whiteImage);
|
||||
mul = 1.f;
|
||||
RB_Color4f(mul, mul, mul, 1.f);
|
||||
RB_DrawQuad(0.f, 0.f, w4, h4, 0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
//for (i=0; i<2; ++i)
|
||||
{
|
||||
R_FBO_Bind(tr.fbo.tiny[1]);
|
||||
R_FBO_BindColorBuffer(tr.fbo.tiny[0], 0);
|
||||
RB_HBlur(w4, h4, factor);
|
||||
|
||||
R_FBO_Bind(tr.fbo.tiny[0]);
|
||||
R_FBO_BindColorBuffer(tr.fbo.tiny[1], 0);
|
||||
RB_VBlur(w4, h4, factor);
|
||||
}
|
||||
|
||||
RB_SetGL2D_Level(0);
|
||||
R_FBO_BindColorBuffer(R_FBO_Bind(tr.fbo.full[0]), 0);
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
mul = 1.f;
|
||||
RB_Color4f(mul, mul, mul, factor);
|
||||
RB_DrawQuad(0.f, 0.f, w, h, 0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
}
|
||||
|
||||
void RB_FBO_Set2D(void)
|
||||
|
@ -363,7 +433,7 @@ void RB_FBO_Set2D(void)
|
|||
GLSL_SetUniform_Texture0Matrix(sp, matrix);
|
||||
GLSL_SetUniform_Texture1Env(sp, 0);
|
||||
GLSL_SetUniform_ColorGen(sp, CGEN_CONST);
|
||||
GLSL_SetUniform_AlphaGen(sp, AGEN_IDENTITY);
|
||||
GLSL_SetUniform_AlphaGen(sp, AGEN_CONST);
|
||||
|
||||
RB_Color4f = &GLSL_Color4f;
|
||||
}
|
||||
|
@ -429,4 +499,5 @@ void RB_PostProcess(void)
|
|||
|
||||
RB_FBO_Set2D();
|
||||
RB_GodRays();
|
||||
RB_Blur();
|
||||
}
|
||||
|
|
|
@ -360,6 +360,13 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
}
|
||||
}
|
||||
|
||||
// Makro - copy exta info if present
|
||||
if (fd->rdflags & RDF_EXTRA) {
|
||||
const refdefex_t* extra = (const refdefex_t*) (fd+1);
|
||||
tr.refdef.blurFactor = extra->blurFactor;
|
||||
} else {
|
||||
tr.refdef.blurFactor = 0.f;
|
||||
}
|
||||
|
||||
// derived info
|
||||
|
||||
|
|
|
@ -289,9 +289,17 @@ static void RB_SurfaceSprite( void ) {
|
|||
}
|
||||
|
||||
if (ent->e.renderfx & RF_SUNFLARE) {
|
||||
if (backEnd.hasSunFlare)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "Multiple sun flares not supported\n");
|
||||
return;
|
||||
}
|
||||
if (R_CullPointAndRadiusEx(ent->e.origin, ent->e.radius, backEnd.viewParms.frustum, ARRAY_LEN(backEnd.viewParms.frustum)) == CULL_OUT)
|
||||
return;
|
||||
colors[0] = colors[1] = colors[2] = colors[3] = ent->e.shaderRGBA[glRefConfig.framebufferObject];
|
||||
if (colors[0] == 0)
|
||||
return;
|
||||
backEnd.hasSunFlare = qtrue;
|
||||
} else {
|
||||
Vector4Copy(ent->e.shaderRGBA, colors);
|
||||
}
|
||||
|
|
|
@ -56,6 +56,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define RDF_HYPERSPACE 0x0004 // teleportation effect
|
||||
// JBravo: Fox fixes
|
||||
#define RDF_NOFOG 0x0008 // don't apply fog
|
||||
#define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t
|
||||
|
||||
// Makro - this should mirror the definition in cgame
|
||||
// TODO: single tr_types.h file!
|
||||
|
||||
typedef struct {
|
||||
float blurFactor;
|
||||
} refdefex_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t xyz;
|
||||
|
|
Loading…
Reference in a new issue