Quake Motion Blur

Post tutorials on how to do certain tasks within game or engine code here.
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Quake Motion Blur

Post by mh »

This somewhere in gl_rmain.c:

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;
}
(Declare and register the r_motionblur cvar somewhere too, and you may also need to have a global called r_frametime, so just set it up the same way as frametime in R_DrawParticles...)

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 ();
Finally, in gl_vidnt.c, when setting up your PIXELFORMATDESCRIPTOR, just set the cAccumBits member to 64.

There's no need to clear the accumulation buffer between frames, should work just fine on any engine out of the box.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
MeTcHsteekle
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Post by MeTcHsteekle »

sweet 8)
bah
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Post by leileilol »

Just chiming in that this can also be applied to Q3A as well (though replacing the whole stat/damage checking with some variable framerate smoothing thing, since you can't access player stats from the renderer module anyway).

Thanks!
i should not be here
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: Quake Motion Blur

Post by r00k »

works!
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Post by leileilol »

By the way and FYI - accumulation buffers in consumer videogaming video hardware only begin their support starting from shader model 2.0 hardware, despite this predating the whole programmable shader thing for ages.
i should not be here
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Post by toneddu2000 »

I can't understand the last step.
Finally, in gl_vidnt.c, when setting up your PIXELFORMATDESCRIPTOR, just set the cAccumBits member to 64.
I use quakespasm and there's no gl_vidnt.c but gl_vidsdl.c. I hope it's the same. Now what should I set?
thanks
Meadow Fun!! - my first commercial game, made with FTEQW game engine
hogsy
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK
Contact:

Re: Quake Motion Blur

Post by hogsy »

Rather than doing that I'd suppose you'd set the following in the case of SDL.

Code: Select all

SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,8);
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Post by toneddu2000 »

thanks hogsy but where should I put those functions?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
hogsy
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK
Contact:

Re: Quake Motion Blur

Post by hogsy »

I haven't touched QuakeSpasm but if you take a look in gl_vidsdl there should be a bunch of the same functions where the SDL window is created and you can just plop it in with those, shouldn't be too hard to find if you just do a quick search :wink:
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Post by toneddu2000 »

the only SDL_GL_SetAttribute() function I found it's in VID_SetMode () int gl_vidsdl.c and it's called like this:

Code: Select all

if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vid_vsync.value) ? 1 : 0) == -1)
		gl_swap_control = false;
There's no bunch of SDL functions

thanks
Meadow Fun!! - my first commercial game, made with FTEQW game engine
hogsy
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK
Contact:

Re: Quake Motion Blur

Post by hogsy »

Just plop it under those two lines then.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Post by toneddu2000 »

It worked! Thanks a lot hogsy and of course mh for this great addition!

For the QuakeSpasm lovers:
declare at the start of the gl_rmain.c

Code: Select all

float  r_frametime;
put at the start of the DrawAccumBlur() function

Code: Select all

r_frametime = cl.time - cl.oldtime;
in gl_vidsdl.c, in VID_SetMode function,after:

Code: Select all

if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vid_vsync.value) ? 1 : 0) == -1)
		gl_swap_control = false;
put those lines as hogsy stated

Code: Select all

SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
I avoided the

Code: Select all

if (!r_motionblur.value) return;
line because I still didn't understand how send the cvars to quakec, so in my case motion blur is on by default.

There's a chance to mimic that cool Doom3 pain rotating head effect?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Post by leileilol »

You could do something derivative of v_idlescale in view.c to make that scale from damagetime.
i should not be here
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Post by toneddu2000 »

thanks leilei, I tried in V_AddIdle:

Code: Select all

void V_AddIdle (void)
{
	r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
	r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
	r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
	//code below added by me
	if (cl.cshifts[CSHIFT_DAMAGE].percent)
	{
		cl.viewent.angles[ROLL] -= v_idlescale.value * 250.0f;
		cl.viewent.angles[PITCH] -= v_idlescale.value * 250.0f;
		cl.viewent.angles[YAW] -= v_idlescale.value * 250.0f;
	}
}
Then I set cvar r_idlescale to 1 but nothing. I exagerated roll,pitch and yaw movements to maximum just to test if it could work but it doesn't do anything
Meadow Fun!! - my first commercial game, made with FTEQW game engine
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Post by leileilol »

Because you have to alter the refdef's angles not the viewent itself. IIRC, viewent is the gun. The gun gets its origin and angles calculated in another function that comes after addidle. iirc
i should not be here
Post Reply