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
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
R_DrawSkyBox (); 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.
AKA E.Laverick |