Tutorial *120*

This was fairly easy to implement, and does not cripple your framerates (even with Multitexturing disabled) which makes me wonder why ID didn't do so in the first place. This code has been fully tested on a fresh build of the GLQuake engine with no other modifications.


Step 1 - new files
Create 2 new files - gl_fullbright.c and gl_fullbright.h - and add them to your project. The contents of these files should be as follows:


//gl_fullbright.c

#include "quakedef.h"

extern qboolean mtexenabled;

int FindFullbrightTexture (byte *pixels, int num_pix)

{

    int i;

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

        if (pixels[i] > 223)

            return 1;



    return 0;

}



void ConvertPixels (byte *pixels, int num_pixels)

{

    int i;



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

        if (pixels[i] < 224)

            pixels[i] = 255;

}



void DrawFullBrightTextures (msurface_t *first_surf, int num_surfs)

{

    // gl_texsort 1 version

    int i;

    msurface_t *fa;

    texture_t *t;



    if (r_fullbright.value)

        return;



    if (mtexenabled)

        return;



    GL_DisableMultitexture ();



    for (fa = first_surf, i = 0; i < num_surfs; fa++, i++)

    {

        // find the correct texture

        t = R_TextureAnimation (fa->texinfo->texture);



        if (t->fullbright != -1 && fa->draw_this_frame)

        {

            glEnable (GL_BLEND);

            GL_Bind (t->fullbright);

            DrawGLPoly (fa->polys);

            glDisable (GL_BLEND);

        }



        fa->draw_this_frame = 0;

    }

}



//gl_fullbright.h

#include "gl_model.h"



int FindFullbrightTexture (byte *pixels, int num_pix);

void DrawFullBrightTextures (msurface_t *first_surf, int num_surfs);

void ConvertPixels (byte *pixels, int num_pixels);

Step 2: Changes to gl_model.c
At the top, add


#include "gl_fullbright.h"

Find the Mod_LoadTextures function, and add the following variable to the list at the top:


char fbr_mask_name[64];

Then replace the following block of code:


if (!Q_strncmp(mt->name,"sky",3))

    R_InitSky (tx);

else

{

    texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;

    tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);

    texture_mode = GL_LINEAR;

}

with this:


if (!Q_strncmp(mt->name,"sky",3))

    R_InitSky (tx);

else

{

    texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;

    tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);

    texture_mode = GL_LINEAR;



    // check for fullbright pixels in the texture - only if it ain't liquid, etc also



    if ((tx->name[0] != '*') && (FindFullbrightTexture ((byte *)(tx+1), pixels)))

    {

        // convert any non fullbright pixel to fully transparent

        ConvertPixels ((byte *)(tx + 1), pixels);



        // get a new name for the fullbright mask to avoid cache mismatches

        sprintf (fbr_mask_name, "fullbright_mask_%s", mt->name);



        // load the fullbright pixels version of the texture

        tx->fullbright = GL_LoadTexture (fbr_mask_name, tx->width, tx->height, (byte *)(tx + 1), true, true);

    }

    else tx->fullbright = -1; // because 0 is a potentially valid texture number

}

Step 3 - changes to gl_model.h
Find the definition of the msurface_t structure, and add the following to it:


int draw_this_frame;

Now, find the definition of the texture_t structure, and add the following to it:


int fullbright;

Step 4 - changes to gl_rsurf.c (gl_texsort 1)
Find the R_DrawBrushModel function and add the following almost right at the end (just before glPopMatrix):


DrawFullBrightTextures (clmodel->surfaces, clmodel->numsurfaces);

Now find the R_DrawWorld function and add the following at the end (after the call to R_BlendLightmaps)


DrawFullBrightTextures (cl.worldmodel->surfaces, cl.worldmodel->numsurfaces);

The fullbright mask has to be drawn after the lightmaps because otherwise they would obscure it.

Now, go to the R_RenderBrushPoly function, and just above the comment for adding the poly to the proper lightmap chain, add this line:


fa->draw_this_frame = 1;

Step 5 - changes to gl_rsurf.c (gl_texsort 0)
Find the R_DrawSequentialPoly function - there are 2 versions of this, you can ignore the version immediately after the #if 0 - this is not used. Scroll down to the version after the #else and find the if (gl_mtexable) code block near the top - at the end of this block there is a return - delete it. Now scroll down to just after the else block but before the return, and add the following:


// draw fullbright mask if appropriate

if (t->fullbright == -1)

    return;



GL_DisableMultitexture ();

glEnable (GL_BLEND);

GL_Bind (t->fullbright);

DrawGLPoly (s->polys);

glDisable (GL_BLEND);



return;

Now scroll down a little further in this function to past the underwater warped with lightmap block (but just before the closing } for the function) and add the following:


// draw fullbright mask if appropriate

if (t->fullbright == -1)

    return;



GL_DisableMultitexture ();

glEnable (GL_BLEND);

GL_Bind (t->fullbright);

DrawGLWaterPoly (s->polys);

glDisable (GL_BLEND);



return;

Finally, declare prototypes for DrawGLPoly and DrawGLWaterPoly at the top of this file as follows:


void DrawGLPoly (glpoly_t *p);

void DrawGLWaterPoly (glpoly_t *p);

Compile and have fun =)


 
Not logged in
Sign up
Login:
Passwd: