Tutorial *91*

Author:  Tomaz  Contact:   tompsson@hotmail.com

First of all I just want to apologies for my bad English. :)
This is my first tutorial so it might not be so good in learning out any c++ but I will do my best. Basically its the fog code from NATAS done by Brambo with a few small adjustments by me "VERY small".

U don't have to have any skills in c++ at all. U only have to be familiar on how to use VC++ 6.0 and know how to compile GLQuake with it. No other tutorials is required as this tutorial uses the "clean" source code from ID SoftWare. (Of course it will work on altered sources to but I cant guarantee it).

This fog really adds a lot to the game. When u have added it u and played with it for I while u start to wonder why ID did do the code for it but didn't use it. Maybe its because the computers at that date couldn't draw the fog and still maintain a good speed of the game.

Without Fog With Fog
Original Quake                                     Quake with Fog


Well, that's it with that and now down to the coding.

First off we have to register all the cvars we are going to use.

in gl_rmisc.c    R_Init

before

R_InitParticles ();

R_InitParticleTexture ();


add



// NATAS - BramBo - Fog code
Cvar_RegisterVariable (&gl_fogenable); Cvar_RegisterVariable (&gl_fogstart); Cvar_RegisterVariable (&gl_fogend); Cvar_RegisterVariable (&gl_fogdensity); Cvar_RegisterVariable (&gl_fogalpha); Cvar_RegisterVariable (&gl_fogred); Cvar_RegisterVariable (&gl_fogblue); Cvar_RegisterVariable (&gl_foggreen); // END
Then we have to extern the cvars.

in gl_quake.h near bottom

before



extern	 int	gl_lightmap_format;

extern	 int    gl_solid_format;

extern	 int	gl_alpha_format;

add



// NATAS - BramBo - fog code

extern cvar_t gl_fogenable;

extern cvar_t gl_fogstart;

extern cvar_t gl_fogend;

extern cvar_t gl_fogdensity;

extern cvar_t gl_fogalpha;

extern cvar_t gl_fogred;

extern cvar_t gl_fogblue;

extern cvar_t gl_foggreen;

// END


We also have to set the value of all the cvars.

in gl_rmain.c at top

before



extern cvar_t

gl_ztrick;

add



// NATAS - BramBo - Fog Code

cvar_t gl_fogenable = {"gl_fogenable", "1"};

cvar_t gl_fogstart = {"gl_fogstart", "50.0"};

cvar_t gl_fogend = {"gl_fogend", "800.0"};

cvar_t gl_fogdensity = {"gl_fogdensity", "0.8"};

cvar_t gl_fogred = {"gl_fogred","0.6"};

cvar_t gl_foggreen = {"gl_foggreen","0.5"};

cvar_t gl_fogblue = {"gl_fogblue","0.4"};

cvar_t gl_fogalpha = {"gl_fogalpha", "0.5"};

// END

Next thing to do is to put up the code that actually does the fog.

in gl_rmain.c    R_Renderview

replace



/***** Experimental silly looking fog ******

****** Use r_fullbright if you enable ******

glFogi(GL_FOG_MODE, GL_LINEAR);
glFogfv(GL_FOG_COLOR, colors);
glFogf(GL_FOG_END, 512.0);
glEnable(GL_FOG);
********************************************/
with


// NATAS - BramBo - fog code

if( gl_fogenable.value )

{

glFogi(GL_FOG_MODE, GL_LINEAR);

colors[0] = gl_fogred.value;

colors[1] = gl_foggreen.value;

colors[2] = gl_fogblue.value;

glFogfv(GL_FOG_COLOR, colors);

glFogf(GL_FOG_START, gl_fogstart.value);

glFogf(GL_FOG_END, gl_fogend.value);

glFogf(GL_FOG_DENSITY, gl_fogdensity.value);

glEnable(GL_FOG);

}

; else

{

glDisable(GL_FOG);

}

// END

and a few lines further down

replace



    // More fog right here :)
    //    glDisable(GL_FOG);
    // End of all fog code...
with



    // NATAS - BramBo - Fog code
        glDisable(GL_FOG);
    // END

Now we are going to disable drawing fog on the lights because that does look ugly.

in gl_rlight    R_RenderDlights

replace



   glDepthMask (0);

    glDisable (GL_TEXTURE_2D);
    glShadeModel (GL_SMOOTH);
    glEnable (GL_BLEND);
    glBlendFunc (GL_ONE, GL_ONE);

    l = cl_dlights;
    for (I=0 ; I<MAX_DLIGHTS ; I++, l++)
    {
    if (l->die < cl.time || !l->radius)
    continue;
    R_RenderDlight (l);
    }

    glColor3f (1,1,1);
    glDisable (GL_BLEND);
    glEnable (GL_TEXTURE_2D);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthMask (1);
with



   // NATAS - BramBo - Disable drawing fog on lights - looks better
        if (gl_fogenable.value) {
            glDisable(GL_FOG);
        }
        glDepthMask (0);
        glDisable (GL_TEXTURE_2D);
        glShadeModel (GL_SMOOTH);
        glEnable (GL_BLEND);
        glBlendFunc (GL_ONE, GL_ONE);
        l = cl_dlights;
        for (I=0 ; I<MAX_DLIGHTS ; I++, l++)
        {
            if (l->die < cl.time || !l->radius)
        continue;
            R_RenderDlight (l);
        }

        glColor3f (1,1,1);
        glDisable (GL_BLEND);
        glEnable (GL_TEXTURE_2D);
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDepthMask (1);
    // NATAS - BramBo - re-enable fog again
        if (gl_fogenable.value) {
        glEnable(GL_FOG);
        }
    // END
As an last thing we will make the Menu Background a little more transparent so it is easier to see the changes to the fog.
to this:

in gl_draw find the function Draw_Fadescreen
replace with the code below.



    /*
    ================
    Draw_FadeScreen

    ================
    */
    void Draw_FadeScreen (void)
    {
    glEnable (GL_BLEND);
    glDisable (GL_TEXTURE_2D);
    // NATAS - BramBo - Make menu background more alpha
    glDisable(GL_ALPHA_TEST);
    glColor4f (0, 0, 0, 0.4);
    // END
    glBegin (GL_QUADS);

    glVertex2f (0,0);
    glVertex2f (vid.width, 0);
    glVertex2f (vid.width, vid.height);
    glVertex2f (0, vid.height);

    glEnd ();
    glColor4f (1,1,1,1);
    // NATAS - BramBo - enable again
    glEnable(GL_ALPHA_TEST);
    // END
    glEnable (GL_TEXTURE_2D);
    glDisable (GL_BLEND);

    Sbar_Changed();
    }

Now we have an good looking fog. We can change the depth of it with the Variable:
GL_FogEnd with an value between 200-4096. We can also change color of the fog with:
GL_FogRed, GL_FogGreen and GL_FogBlue with a value between 0-1.

But now we are going to add all the above to Quakes ingame Options Menu.
Note that this is done for fullscreen mode and that the WindowedMouse option could mess things up if u run the game in windowed mode.

First of all we have to change the number of options to choose from.

in menu.c    M_Menu_Options_f
replace



    #ifdef _WIN32
    #define    OPTIONS_ITEMS    14
    #else
    #define    OPTIONS_ITEMS    13
    #endif
with



    // Tomaz options
    #ifdef _WIN32
    #define    OPTIONS_ITEMS    19
    #else
    #define    OPTIONS_ITEMS    18
    #endif
    // End

Then we add the new options to the existing ones.

in menu.c    M_AdjustSliders
after



    #ifdef _WIN32
        case 13:    // _windowed_mouse
            Cvar_SetValue ("_windowed_mouse", !_windowed_mouse.value);
            break;
    #endif
add



    // NATAS - Brambo Options
    // Modified by Tomaz
        case 14:    // fog
            Cvar_SetValue ("gl_fogenable", !gl_fogenable.value);
            break;
   
        case 15:    // fog depth
            gl_fogend.value += dir * 100.0f;
            if (gl_fogend.value < 200.0f)
            gl_fogend.value = 200.0f;
            if (gl_fogend.value > 4096.0f)
            gl_fogend.value = 4096.0f;
            Cvar_SetValue ("gl_fogend", gl_fogend.value);
            break;

        case 16:    // fog red
            gl_fogred.value += dir * 0.1f;
            if (gl_fogred.value < 0.0f)
            gl_fogred.value = 0.0f;
            if (gl_fogred.value > 1.0f)
            gl_fogred.value = 1.0f;
            Cvar_SetValue ("gl_fogred", gl_fogred.value);
            break;

        case 17:    // fog green
            gl_foggreen.value += dir * 0.1f;
            if (gl_foggreen.value < 0.0f)
            gl_foggreen.value = 0.0f;
            if (gl_foggreen.value > 1.0f)
            gl_foggreen.value = 1.0f;
            Cvar_SetValue ("gl_foggreen", gl_foggreen.value);
            break;

        case 18:    // fog blue
            gl_fogblue.value += dir * 0.1f;
            if (gl_fogblue.value < 0.0f)
            gl_fogblue.value = 0.0f;
            if (gl_fogblue.value > 1.0f)
            gl_fogblue.value = 1.0f;
            Cvar_SetValue ("gl_fogblue", gl_fogblue.value);
            break;
    // END

We also have to add if we want on/off buttons or sliders.

in menu.c    M_Options_Draw
after



    #ifdef _WIN32
        if (modestate == MS_WINDOWED)
        {
            M_Print (16, 136, " Use Mouse");
            M_DrawCheckbox (220, 136, _windowed_mouse.value);
        }
    #endif
add



    // NATAS - Brambo Options
    // Modified by Tomaz
        M_Print (16, 144, " Fog");
        M_DrawCheckbox (220, 144, (int)gl_fogenable.value);
   
        M_Print (16, 152, " Fog Depth");
        r = gl_fogend.value / 4096.0f;
        M_DrawSlider (220, 152, r);
   
        M_Print (16, 160, " Red Fog");
        r = gl_fogred.value;
        M_DrawSlider (220, 160, r);
   
        M_Print (16, 168, " Green Fog");
        r = gl_foggreen.value;
        M_DrawSlider (220, 168, r);
   
        M_Print (16, 176, " Blue Fog");
        r = gl_fogblue.value;
        M_DrawSlider (220, 176, r);
    // END
We also have to change some of the existing code in order to make the new options avaliable. Basically this does that when u get down to the vid_options button and press down it wont jump up to the top but down to the Fog Enable button.

in menu.c    M_Options_Key
replace



   #ifdef _WIN32
        if ((options_cursor == 13) && (modestate != MS_WINDOWED))
        {
            if (k == K_UPARROW)
                options_cursor = 12;
            else
                options_cursor = 0;
        }
    #endif

with



   // NATAS - Brambo Options
    // Modified by Tomaz
    #ifdef _WIN32
        if ((options_cursor == 13) && (modestate != MS_WINDOWED))
        {
            if (k == K_UPARROW)
                options_cursor = 12;
            else
                options_cursor = 14;
        }
    #endif
    // END

Now u can change the color and depth of the fog from the Options menu in the game.
If u have any problems, bug fixes or ideas feel free to mail me at:
tompsson@hotmail.com



 
Sign up
Login:
Passwd:
[Remember Me]