Code: Select all
extern cvar_t r_motionblur;
void DrawAccumBlur (void)
{
static int blurstate = 0;
float accblur;
static float damagetime = -1.0f;
if (!r_motionblur.value) return;
// evaluate blur conditions
if (cl.stats[STAT_HEALTH] <= 0)
{
// being dead always overrides everything else
accblur = 0.75f;
}
else if (cl.cshifts[CSHIFT_DAMAGE].percent)
{
// initial damage blur
accblur = 0.75f;
damagetime = 0.5f;
}
else if (damagetime >= 0.0f)
{
// persist damage blur
damagetime -= r_frametime;
accblur = 0.75f;
}
else if (cl.cshifts[CSHIFT_CONTENTS].percent)
{
// blur less if underwater
accblur = 0.666f;
}
else accblur = -1.0f;
if (accblur <= 0.0f)
{
// reinit if we're not blurring so that the contents of the
// accumulation buffer are valid for the frame
blurstate = 0;
return;
}
if (!blurstate)
{
// load the scene into the accumulation buffer
glAccum (GL_LOAD, 1.0f);
}
else
{
glAccum (GL_MULT, accblur); // scale contents of accumulation buffer
glAccum (GL_ACCUM, 1.0f - accblur); // add screen contents
glAccum (GL_RETURN, 1.0f); // read result back
}
blurstate = 1;
}
Call it like this, at the end of R_RenderView, after everything else is drawn:
Code: Select all
// draw motion blur effects on the full 3D view
DrawAccumBlur ();
There's no need to clear the accumulation buffer between frames, should work just fine on any engine out of the box.