Tutorial *103*

If like me, you've tried the various OpenGL fogging tutorials and found them to be a little excessive (lets face it even London's best pea-soupers tended not to stretch inside the buildings...) then this might be for you. It came from an idea I had whilst playing the demo of Croteam's Serious Sam (http://www.croteam.com/www/index.html) underwater fogging. Whilst it might not immediately seem to have many benefits, the sense of scale and depth that you can achieve in water bound levels is phenomenal especially if you meant to showing the depths of a huge lake or ocean. What's even better is that it's dead easy to code.

Open View .c
in the V_SetContentsColor routine
at the top, with the other variable definitions
add:



	GLfloat colors[4];// laverick@bigfoot.com - Underwater fogging

	GLfloat lava[4] = {(GLfloat) 1.0, (GLfloat) 0.314, (GLfloat) 0.0, (GLfloat) 0.588};// laverick@bigfoot.com - Underwater fogging

	GLfloat slime[4] = {(GLfloat) 0.0, (GLfloat) 0.25, (GLfloat) 0.5, (GLfloat) 0.588};// laverick@bigfoot.com - Underwater fogging

	GLfloat water[4] = {(GLfloat) 0.039, (GLfloat) 0.584, (GLfloat) 0.788, (GLfloat) 0.2};// laverick@bigfoot.com - Underwater fogging

This defines the three colours we want for our Lava, Slime and Water. And a fourth variable to stick them in. Next alter the case statement (that's from the word switch to the first '}') to look like this



	switch (contents)

	{

	case CONTENTS_EMPTY:

	case CONTENTS_SOLID:

		cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;

		break;

	case CONTENTS_LAVA:

		cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;

		for(i=0;i<4;i++)

			colors[i]=lava[i];

		break;

	case CONTENTS_SLIME:

		cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;

		for(i=0;i<4;i++)

			colors[i]=slime[i];

		break;

	default:

		cl.cshifts[CSHIFT_CONTENTS] = cshift_water;

		for(i=0;i<4;i++)

			colors[i]=water[i];

	}

This will set our colours to the correct colour for our environment type. Just under this case statement add the following text:



if (contents!=CONTENTS_EMPTY||contents!=CONTENTS_SOLID)	// laverick@bigfoot.com - Underwater foggining

	{

		glFogi(GL_FOG_MODE, GL_LINEAR);

		glFogfv(GL_FOG_COLOR, colors);

		glFogf(GL_FOG_START, 150.0);

		glFogf(GL_FOG_END, 1536.0);

		glFogf(GL_FOG_DENSITY, 0.2);

		glEnable(GL_FOG);

	}

This checks to see if we are still in a liquid and if so begins fogging (in exactly the same way as all the other fogging tutorials)


One final point for anyone who has added skyboxes, Open the file gl_rsurf.c
And in the routine R_Drawworld Find the line used to enable skyboxes (which will mostly likely look like this...)



	R_DrawSkyBox ();

And change it to read


	if(GL_FOG) //laverick@bigfoot.com - Don't fog skyboxes

	glDisable(GL_FOG); //laverick@bigfoot.com - Don't fog skyboxes

	R_DrawSkyBox ();

	if(GL_FOG) //laverick@bigfoot.com - Don't fog skyboxes

	glEnable(GL_FOG); //laverick@bigfoot.com - Don't fog skyboxes

This is because skyboxes are treated as large brushes with a different content_type and so are prone to excessive fogging. All we do here is to temporarily turn off our fogging as we render our skybox.
I hope that's been of use to someone.

Arch Angel
AKA
E.Laverick


 
Not logged in
Sign up
Login:
Passwd: