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); At the top, add #include "gl_fullbright.h" char fbr_mask_name[64]; 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; } 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 } Find the definition of the msurface_t structure, and add the following to it: int draw_this_frame; int fullbright; Find the R_DrawBrushModel function and add the following almost right at the end (just before glPopMatrix): DrawFullBrightTextures (clmodel->surfaces, clmodel->numsurfaces); DrawFullBrightTextures (cl.worldmodel->surfaces, cl.worldmodel->numsurfaces); 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; 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; // 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; void DrawGLPoly (glpoly_t *p); void DrawGLWaterPoly (glpoly_t *p); |