]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
detail texturing added (although with just one generated texture applied to everything)
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 24 Aug 2002 07:14:15 +0000 (07:14 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 24 Aug 2002 07:14:15 +0000 (07:14 +0000)
detail texturing makes use of up to 3 texture units if you have combine
detail texturing added to effects options menu (r_detailtextures cvar)
surfvertex_t now has another set of texcoords, for detail texturing
Mod_BrushStartup and Mod_BrushShutdown functions added to alloc/free the detail texture
r_multitexture cvar renamed to r_textureunits, so you can limit number of texture units enabled for testing, rather than just as a yes/no kind of option
gl_combine is forced to 0 if r_textureunits is less than 2 (this is purely for consistency, not of any importance)
split up the wall rendering into two kinds - vertex lit with optional transparency, and opaque lightmapped with no support for transparency
R_Mesh_Draw_GetBuffer now takes a wantoverbrights parameter, if false it will not use the 4x overbright (even if combine is enabled), this is useful to improve the color precision of anything which does not need overbright
fixed crosshair brightness (it was unintentionally adjusting the alpha using m.colorscale just like the RGB portion of the color)
sprites only use overbright if they are lit (normal unlit sprites are rendered without overbright)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2282 d7cf8633-e32d-0410-b094-e92efae38249

16 files changed:
cl_particles.c
gl_backend.c
gl_backend.h
gl_models.c
gl_rmain.c
gl_rsurf.c
menu.c
model_brush.c
model_brush.h
model_shared.c
r_crosshairs.c
r_explosion.c
r_light.c
r_sky.c
r_sprites.c
render.h

index 90d0de161bcb4f3881911967513ed076582ac9a6..fd4bade23a6e36acde75aeab6cc26c9042d86ab8 100644 (file)
@@ -1291,7 +1291,7 @@ void R_DrawParticles (void)
                m.numtriangles = 2;
                m.numverts = 4;
                m.tex[0] = R_GetTexture(particlefonttexture);
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        m.index[0] = 0;
                        m.index[1] = 1;
index 0cc530dcae3c30c1aea3bd26d168ccbe7ab7c3d3..e97232342774a13138d7356cc33be87436f9a491 100644 (file)
@@ -746,7 +746,7 @@ void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, GLuint *in
                // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver
                // feed it manually
                qglBegin(GL_TRIANGLES);
-               if (r_multitexture.integer)
+               if (mesh_texture[1]) // if the mesh uses multiple textures
                {
                        // the minigl doesn't have this (because it does not have ARB_multitexture)
                        for (i = 0;i < indexcount;i++)
@@ -1240,7 +1240,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
 
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // (this is used for very high speed rendering, no copying)
-int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m)
+int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright)
 {
        // these are static because gcc runs out of virtual registers otherwise
        int i, j, overbright;
@@ -1343,7 +1343,7 @@ int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m)
        {
                if (m->tex[0])
                {
-                       overbright = gl_combine.integer;
+                       overbright = wantoverbright && gl_combine.integer;
                        if (overbright)
                                scaler *= 0.25f;
                }
@@ -1456,15 +1456,22 @@ void SCR_UpdateScreen (void)
 
        R_TimeReport("finish");
 
-       if (gl_combine.integer && !gl_combine_extension)
-               Cvar_SetValue("gl_combine", 0);
+       if (r_textureunits.integer > gl_textureunits)
+               Cvar_SetValueQuick(&r_textureunits, gl_textureunits);
+       if (r_textureunits.integer < 1)
+               Cvar_SetValueQuick(&r_textureunits, 1);
+
+       if (gl_combine.integer && (!gl_combine_extension || r_textureunits.integer < 2))
+               Cvar_SetValueQuick(&gl_combine, 0);
+
+       // lighting scale
+       overbrightscale = 1.0f / (float) (1 << v_overbrightbits.integer);
 
+       // lightmaps only
        lightscalebit = v_overbrightbits.integer;
-       if (gl_combine.integer && r_multitexture.integer)
+       if (gl_combine.integer && r_textureunits.integer > 1)
                lightscalebit += 2;
-
        lightscale = 1.0f / (float) (1 << lightscalebit);
-       overbrightscale = 1.0f / (float) (1 << v_overbrightbits.integer);
 
        R_TimeReport("setup");
 
index e7183ad0c0e31754e36556f7f10cceecb3697d41..01dc10602c7d973bed2e0ec96b97327fc952b278 100644 (file)
@@ -83,7 +83,7 @@ void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts);
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct
 // (this is used for very high speed rendering, no copying)
 // (only valid between R_Mesh_Start and R_Mesh_Finish)
-int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m);
+int R_Mesh_Draw_GetBuffer(rmeshbufferinfo_t *m, int wantoverbright);
 
 // saves a section of the rendered frame to a .tga file
 qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height);
index 02f9e34940cc18be7577ba771fa457fa66b91029..e5852f9bad3dcc83feecac18a75a93a266eab1de 100644 (file)
@@ -482,7 +482,7 @@ void R_DrawQ1Q2AliasModel (float fog)
                bufmesh.numverts = model->numverts;
                bufmesh.tex[0] = R_GetTexture(skinframe->merged);
 
-               R_Mesh_Draw_GetBuffer(&bufmesh);
+               R_Mesh_Draw_GetBuffer(&bufmesh, true);
 
                aliasvert = bufmesh.vertex;
                aliasvertcolor = bufmesh.color;
index a8c8d056ebae58df717882bba917afd7513f4163..226de362d8bcd9e07e3ee494e6431f2b20234a42 100644 (file)
@@ -67,7 +67,7 @@ cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
 cvar_t gl_fogend = {0, "gl_fogend","0"};
 
-cvar_t r_multitexture = {0, "r_multitexture", "1"};
+cvar_t r_textureunits = {0, "r_textureunits", "32"};
 
 /*
 ====================
@@ -240,7 +240,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable (&r_wateralpha);
        Cvar_RegisterVariable (&r_dynamic);
        Cvar_RegisterVariable (&r_fullbright);
-       Cvar_RegisterVariable (&r_multitexture);
+       Cvar_RegisterVariable (&r_textureunits);
        if (gamemode == GAME_NEHAHRA)
                Cvar_SetValue("r_fullbrights", 0);
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
@@ -505,8 +505,6 @@ static void R_SetupFrame (void)
                if (r_ambient.value != 0)
                        Cvar_Set ("r_ambient", "0");
        }
-       if (r_multitexture.integer && gl_textureunits < 2)
-               Cvar_SetValue("r_multitexture", 0);
 
        r_framecount++;
 
@@ -538,7 +536,7 @@ static void R_BlendView(void)
        m.depthdisable = true; // magic
        m.numtriangles = 1;
        m.numverts = 3;
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                m.index[0] = 0;
                m.index[1] = 1;
index 47597c2a6c8f3f0966695ba1a4ee8e0196371385..9fe860b5bbe22a69981d80c88e0ae3d0a5586b12 100644 (file)
@@ -34,6 +34,7 @@ cvar_t r_dlightmap = {CVAR_SAVE, "r_dlightmap", "1"};
 cvar_t r_drawportals = {0, "r_drawportals", "0"};
 cvar_t r_testvis = {0, "r_testvis", "0"};
 cvar_t r_floatbuildlightmap = {0, "r_floatbuildlightmap", "0"};
+cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"};
 
 static int dlightdivtable[32768];
 
@@ -657,7 +658,7 @@ static void RSurfShader_Sky(msurface_t *firstsurf)
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
-                       if (R_Mesh_Draw_GetBuffer(&m))
+                       if (R_Mesh_Draw_GetBuffer(&m, false))
                        {
                                cr = fogcolor[0] * m.colorscale;
                                cg = fogcolor[1] * m.colorscale;
@@ -768,7 +769,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
-                       if (R_Mesh_Draw_GetBuffer(&m))
+                       if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                                base[0] = base[1] = base[2] = 1.0f * m.colorscale;
                                memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
@@ -798,7 +799,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf)
                {
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
-                       if (R_Mesh_Draw_GetBuffer(&m))
+                       if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                                cl = m.colorscale;
                                memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
@@ -874,7 +875,7 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        VectorScale(fogcolor, m.colorscale, base);
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
@@ -909,11 +910,13 @@ static void RSurfShader_Water(msurface_t *firstsurf)
                        RSurfShader_Water_Pass_Fog(surf);
 }
 
-static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
 {
-       int i;
+       int i, size3;
        surfvertex_t *v;
-       float *outv, *outc, *outst, *outuv, cl, ca, diff[3];
+       float *outv, *outc, *outst, cl, ca, diff[3];
+       float base[3], scale, f;
+       qbyte *lm;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
@@ -938,96 +941,116 @@ static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf)
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       m.tex[1] = R_GetTexture(surf->lightmaptexture);
+
+       size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
+
+       base[0] = base[1] = base[2] = currentrenderentity->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
+
        ca = currentrenderentity->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, true))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (fogenabled)
+
+                       if (currentrenderentity->effects & EF_FULLBRIGHT)
                        {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
-                               }
-                               else
+                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                                {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
+                                       softwaretransform(v->v, outv);
+                                       outv[3] = 1;
+                                       VectorSubtract(outv, r_origin, diff);
+                                       outc[0] = outc[1] = outc[2] = 2.0f * cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
+                                       outc[3] = ca;
+                                       outst[0] = v->st[0];
+                                       outst[1] = v->st[1];
                                }
                        }
                        else
                        {
-                               if (softwaretransform_complexity)
+                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                                {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
+                                       softwaretransform(v->v, outv);
+                                       outv[3] = 1;
+                                       VectorCopy(base, outc);
+                                       outc[3] = ca;
+                                       outst[0] = v->st[0];
+                                       outst[1] = v->st[1];
                                }
-                               else
+
+                               if (surf->dlightframe == r_framecount)
+                                       RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
+
+                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
                                {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
+                                       if (surf->styles[0] != 255)
+                                       {
+                                               lm = surf->samples + v->lightmapoffset;
+                                               scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
+                                               VectorMA(outc, scale, lm, outc);
+                                               if (surf->styles[1] != 255)
+                                               {
+                                                       lm += size3;
+                                                       scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
+                                                       VectorMA(outc, scale, lm, outc);
+                                                       if (surf->styles[2] != 255)
+                                                       {
+                                                               lm += size3;
+                                                               scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
+                                                               VectorMA(outc, scale, lm, outc);
+                                                               if (surf->styles[3] != 255)
+                                                               {
+                                                                       lm += size3;
+                                                                       scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
+                                                                       VectorMA(outc, scale, lm, outc);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       if (fogenabled)
                                        {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
+                                               VectorSubtract(outv, r_origin, diff);
+                                               f = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
+                                               VectorScale(outc, f, outc);
                                        }
+                                       else
+                                               VectorScale(outc, cl, outc);
                                }
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseTexture(msurface_t *surf)
+static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca;
+       float *outv, *outc, *outst, cl, ca, diff[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = false;
-       m.blendfunc1 = GL_ONE;
-       m.blendfunc2 = GL_ZERO;
+       if (currentrenderentity->effects & EF_ADDITIVE)
+       {
+               m.transparent = true;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE;
+       }
+       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
+       {
+               m.transparent = true;
+               m.blendfunc1 = GL_SRC_ALPHA;
+               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+       }
+       else
+       {
+               m.transparent = false;
+               m.blendfunc1 = GL_ONE;
+               m.blendfunc2 = GL_ZERO;
+       }
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
@@ -1037,372 +1060,267 @@ static void RSurfShader_Wall_Pass_BaseTexture(msurface_t *surf)
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (softwaretransform_complexity)
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                        {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               if (fogenabled)
                                {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       outc[0] = outc[1] = outc[2] = cl;
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
+                                       VectorSubtract(outv, r_origin, diff);
+                                       outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
                                }
-                       }
-                       else
-                       {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       VectorCopy(v->v, outv);
-                                       outv[3] = 1;
+                               else
                                        outc[0] = outc[1] = outc[2] = cl;
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
+                               outc[3] = ca;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseLightmap(msurface_t *surf)
+static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outuv, cl, ca, diff[3];
+       float *outv, *outc, *outst, cl, ca, diff[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = false;
-       m.blendfunc1 = GL_ZERO;
-       m.blendfunc2 = GL_SRC_COLOR;
-       m.depthwrite = false;
-       m.depthdisable = false;
-       m.tex[0] = R_GetTexture(surf->lightmaptexture);
+       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       m.blendfunc1 = GL_SRC_ALPHA;
+       m.blendfunc2 = GL_ONE;
+       m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
        ca = currentrenderentity->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (fogenabled)
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                        {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
-                               }
-                               else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               if (softwaretransform_complexity)
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               if (fogenabled)
                                {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
+                                       VectorSubtract(outv, r_origin, diff);
+                                       outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
                                }
                                else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outuv[0] = v->uv[0];
-                                               outuv[1] = v->uv[1];
-                                       }
-                               }
+                                       outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = ca;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf)
+static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
 {
-       int i, size3;
+       int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
-       float base[3], scale, f;
-       qbyte *lm;
+       float *outv, *outc, *outst, cl, ca, diff[3], f;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE;
-       }
-       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       }
-       else
+       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       m.blendfunc1 = GL_SRC_ALPHA;
+       m.blendfunc2 = GL_ONE;
+       ca = currentrenderentity->alpha;
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
-               m.transparent = false;
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ZERO;
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+
+               if (R_Mesh_Draw_GetBuffer(&m, false))
+               {
+                       cl = m.colorscale;
+                       memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
+                       {
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               VectorSubtract(outv, r_origin, diff);
+                               f = cl * exp(fogdensity/DotProduct(diff, diff));
+                               VectorScale(fogcolor, f, outc);
+                               outc[3] = ca;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
+                       }
+               }
        }
+}
+
+static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(msurface_t *surf)
+{
+       int i;
+       surfvertex_t *v;
+       float *outv, *outc, *outst, *outuv, *outab, cl;
+       surfmesh_t *mesh;
+       rmeshbufferinfo_t m;
+       memset(&m, 0, sizeof(m));
+       m.transparent = false;
+       m.blendfunc1 = GL_ONE;
+       m.blendfunc2 = GL_ZERO;
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-
-       size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3;
-
-       base[0] = base[1] = base[2] = currentrenderentity->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
-
-       ca = currentrenderentity->alpha;
+       m.texrgbscale[0] = 1.0f;
+       m.tex[1] = R_GetTexture(surf->lightmaptexture);
+       m.texrgbscale[1] = 4.0f;
+       m.tex[2] = R_GetTexture(surf->currenttexture->detailtexture);
+       m.texrgbscale[2] = 2.0f;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-
-                       if (currentrenderentity->effects & EF_FULLBRIGHT)
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1], outab = m.texcoords[2];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2, outab += 2)
                        {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = 2.0f * cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
-                               else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = 2.0f * cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = 1;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
+                               outuv[0] = v->uv[0];
+                               outuv[1] = v->uv[1];
+                               outab[0] = v->ab[0];
+                               outab[1] = v->ab[1];
                        }
-                       else
-                       {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorCopy(base, outc);
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
-                               else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorCopy(base, outc);
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
-
-                               if (surf->dlightframe == r_framecount)
-                                       RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
+               }
+       }
+}
 
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
-                               {
-                                       if (surf->styles[0] != 255)
-                                       {
-                                               lm = surf->samples + v->lightmapoffset;
-                                               scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
-                                               VectorMA(outc, scale, lm, outc);
-                                               if (surf->styles[1] != 255)
-                                               {
-                                                       lm += size3;
-                                                       scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
-                                                       VectorMA(outc, scale, lm, outc);
-                                                       if (surf->styles[2] != 255)
-                                                       {
-                                                               lm += size3;
-                                                               scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
-                                                               VectorMA(outc, scale, lm, outc);
-                                                               if (surf->styles[3] != 255)
-                                                               {
-                                                                       lm += size3;
-                                                                       scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
-                                                                       VectorMA(outc, scale, lm, outc);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       if (fogenabled)
-                                       {
-                                               VectorSubtract(outv, r_origin, diff);
-                                               f = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               VectorScale(outc, f, outc);
-                                       }
-                                       else
-                                               VectorScale(outc, cl, outc);
-                               }
+static void RSurfShader_OpaqueWall_Pass_BaseMTex(msurface_t *surf)
+{
+       int i;
+       surfvertex_t *v;
+       float *outv, *outc, *outst, *outuv, cl;
+       surfmesh_t *mesh;
+       rmeshbufferinfo_t m;
+       memset(&m, 0, sizeof(m));
+       m.transparent = false;
+       m.blendfunc1 = GL_ONE;
+       m.blendfunc2 = GL_ZERO;
+       m.depthwrite = false;
+       m.depthdisable = false;
+       m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+       m.tex[1] = R_GetTexture(surf->lightmaptexture);
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+       {
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+
+               if (R_Mesh_Draw_GetBuffer(&m, true))
+               {
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0], outuv = m.texcoords[1];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2, outuv += 2)
+                       {
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = 1;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
+                               outuv[0] = v->uv[0];
+                               outuv[1] = v->uv[1];
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
+       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE;
-       }
-       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       }
-       else
-       {
-               m.transparent = false;
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ZERO;
-       }
+       m.transparent = false;
+       m.blendfunc1 = GL_ONE;
+       m.blendfunc2 = GL_ZERO;
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       ca = currentrenderentity->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
-                       cl = m.colorscale;
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (fogenabled)
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                        {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
-                               else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               VectorSubtract(outv, r_origin, diff);
-                                               outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = 1;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
                        }
-                       else
+               }
+       }
+}
+
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(msurface_t *surf)
+{
+       int i;
+       surfvertex_t *v;
+       float *outv, *outc, *outuv, cl;
+       surfmesh_t *mesh;
+       rmeshbufferinfo_t m;
+       memset(&m, 0, sizeof(m));
+       m.transparent = false;
+       m.blendfunc1 = GL_ZERO;
+       m.blendfunc2 = GL_SRC_COLOR;
+       m.depthwrite = false;
+       m.depthdisable = false;
+       m.tex[0] = R_GetTexture(surf->lightmaptexture);
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+       {
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+
+               if (R_Mesh_Draw_GetBuffer(&m, true))
+               {
+                       cl = (float) (1 << lightscalebit) * m.colorscale;
+                       memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outuv = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outuv += 2)
                        {
-                               if (softwaretransform_complexity)
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               softwaretransform(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
-                               else
-                               {
-                                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                                       {
-                                               VectorCopy(v->v, outv);
-                                               outv[3] = 1;
-                                               outc[0] = outc[1] = outc[2] = cl;
-                                               outc[3] = ca;
-                                               outst[0] = v->st[0];
-                                               outst[1] = v->st[1];
-                                       }
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = 1;
+                               outuv[0] = v->uv[0];
+                               outuv[1] = v->uv[1];
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Light(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3], f;
+       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
 
@@ -1412,28 +1330,12 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
                return;
 
        memset(&m, 0, sizeof(m));
-       if (currentrenderentity->effects & EF_ADDITIVE)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE;
-       }
-       else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)
-       {
-               m.transparent = true;
-               m.blendfunc1 = GL_SRC_ALPHA;
-               m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-       }
-       else
-       {
-               m.transparent = false;
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ZERO;
-       }
+       m.transparent = false;
+       m.blendfunc1 = GL_SRC_ALPHA;
+       m.blendfunc2 = GL_ONE;
        m.depthwrite = false;
        m.depthdisable = false;
        m.tex[0] = R_GetTexture(surf->currenttexture->texture);
-       ca = currentrenderentity->alpha;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                if (RSurf_LightCheck(surf->dlightbits, mesh))
@@ -1441,7 +1343,7 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
                        m.numtriangles = mesh->numtriangles;
                        m.numverts = mesh->numverts;
 
-                       if (R_Mesh_Draw_GetBuffer(&m))
+                       if (R_Mesh_Draw_GetBuffer(&m, true))
                        {
                                cl = m.colorscale;
                                memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
@@ -1450,21 +1352,12 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
                                        softwaretransform(v->v, outv);
                                        outv[3] = 1;
                                        VectorClear(outc);
-                                       outc[3] = ca;
+                                       outc[3] = 1;
                                        outst[0] = v->st[0];
                                        outst[1] = v->st[1];
                                }
                                RSurf_LightSeparate(surf->dlightbits, m.numverts, m.vertex, m.color);
-                               if (fogenabled)
-                               {
-                                       for (i = 0, outv = m.vertex, outc = m.color;i < m.numverts;i++, outv += 4, outc += 4)
-                                       {
-                                               VectorSubtract(outv, r_origin, diff);
-                                               f = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                               VectorScale(outc, f, outc);
-                                       }
-                               }
-                               else if (cl != 1)
+                               if (cl != 1)
                                        for (i = 0, outc = m.color;i < m.numverts;i++, outc += 4)
                                                VectorScale(outc, cl, outc);
                        }
@@ -1472,106 +1365,102 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf)
        }
 }
 
-static void RSurfShader_Wall_Pass_Glow(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Fog(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3];
+       float *outv, *outc, cl, diff[3], fcolor[3];
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
-       m.blendfunc2 = GL_ONE;
-       m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
-       ca = currentrenderentity->alpha;
+       m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        cl = m.colorscale;
+                       VectorScale(fogcolor, cl, fcolor);
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (fogenabled)
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color;i < m.numverts;i++, v++, outv += 4, outc += 4)
                        {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorSubtract(outv, r_origin, diff);
-                                       outc[0] = outc[1] = outc[2] = cl * (1 - exp(fogdensity/DotProduct(diff, diff)));
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               VectorCopy(fcolor, outc);
+                               VectorSubtract(outv, r_origin, diff);
+                               outc[3] = exp(fogdensity/DotProduct(diff, diff));
                        }
-                       else
+               }
+       }
+}
+
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(msurface_t *surf)
+{
+       int i;
+       surfvertex_t *v;
+       float *outv, *outc, *outst;
+       surfmesh_t *mesh;
+       rmeshbufferinfo_t m;
+       memset(&m, 0, sizeof(m));
+       m.transparent = false;
+       m.blendfunc1 = GL_DST_COLOR;
+       m.blendfunc2 = GL_SRC_COLOR;
+       m.depthwrite = false;
+       m.depthdisable = false;
+       m.tex[0] = R_GetTexture(surf->currenttexture->detailtexture);
+       for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+       {
+               m.numtriangles = mesh->numtriangles;
+               m.numverts = mesh->numverts;
+
+               if (R_Mesh_Draw_GetBuffer(&m, false))
+               {
+                       memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                        {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       outc[0] = outc[1] = outc[2] = cl;
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = outc[3] = 1;
+                               outst[0] = v->ab[0];
+                               outst[1] = v->ab[1];
                        }
                }
        }
 }
 
-static void RSurfShader_Wall_Pass_Fog(msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Glow(msurface_t *surf)
 {
        int i;
        surfvertex_t *v;
-       float *outv, *outc, *outst, cl, ca, diff[3], f;
+       float *outv, *outc, *outst, cl;
        surfmesh_t *mesh;
        rmeshbufferinfo_t m;
        memset(&m, 0, sizeof(m));
-       m.transparent = currentrenderentity->effects & EF_ADDITIVE || surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1;
+       m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE;
-       ca = currentrenderentity->alpha;
+       m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
        for (mesh = surf->mesh;mesh;mesh = mesh->chain)
        {
                m.numtriangles = mesh->numtriangles;
                m.numverts = mesh->numverts;
 
-               if (R_Mesh_Draw_GetBuffer(&m))
+               if (R_Mesh_Draw_GetBuffer(&m, false))
                {
                        cl = m.colorscale;
                        memcpy(m.index, mesh->index, m.numtriangles * sizeof(int[3]));
-                       if (softwaretransform_complexity)
-                       {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       softwaretransform(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorSubtract(outv, r_origin, diff);
-                                       f = cl * exp(fogdensity/DotProduct(diff, diff));
-                                       VectorScale(fogcolor, f, outc);
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
-                       }
-                       else
+                       for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
                        {
-                               for (i = 0, v = mesh->vertex, outv = m.vertex, outc = m.color, outst = m.texcoords[0];i < m.numverts;i++, v++, outv += 4, outc += 4, outst += 2)
-                               {
-                                       VectorCopy(v->v, outv);
-                                       outv[3] = 1;
-                                       VectorSubtract(outv, r_origin, diff);
-                                       VectorSubtract(outv, r_origin, diff);
-                                       f = cl * exp(fogdensity/DotProduct(diff, diff));
-                                       VectorScale(fogcolor, f, outc);
-                                       outc[3] = ca;
-                                       outst[0] = v->st[0];
-                                       outst[1] = v->st[1];
-                               }
+                               softwaretransform(v->v, outv);
+                               outv[3] = 1;
+                               outc[0] = outc[1] = outc[2] = cl;
+                               outc[3] = 1;
+                               outst[0] = v->st[0];
+                               outst[1] = v->st[1];
                        }
                }
        }
@@ -1612,7 +1501,7 @@ static void RSurfShader_Wall_Vertex(msurface_t *firstsurf)
 static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
 {
        msurface_t *surf;
-       if (r_vertexsurfaces.integer)
+       if (r_vertexsurfaces.integer || firstsurf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE)
        {
                for (surf = firstsurf;surf;surf = surf->chain)
                {
@@ -1626,91 +1515,53 @@ static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf)
                        for (surf = firstsurf;surf;surf = surf->chain)
                                RSurfShader_Wall_Pass_Fog(surf);
        }
-       else if (r_multitexture.integer)
+       else
        {
-               if (r_dlightmap.integer)
+               if (r_textureunits.integer >= 2)
                {
-                       for (surf = firstsurf;surf;surf = surf->chain)
+                       if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
                        {
-                               c_brush_polys++;
-                               RSurfShader_Wall_Pass_BaseMTex(surf);
+                               for (surf = firstsurf;surf;surf = surf->chain)
+                               {
+                                       c_brush_polys++;
+                                       RSurfShader_OpaqueWall_Pass_TripleTexCombine(surf);
+                               }
                        }
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->currenttexture->glowtexture)
-                                       RSurfShader_Wall_Pass_Glow(surf);
-                       if (fogenabled)
+                       else
+                       {
                                for (surf = firstsurf;surf;surf = surf->chain)
-                                       RSurfShader_Wall_Pass_Fog(surf);
+                               {
+                                       c_brush_polys++;
+                                       RSurfShader_OpaqueWall_Pass_BaseMTex(surf);
+                               }
+                               if (r_detailtextures.integer)
+                                       for (surf = firstsurf;surf;surf = surf->chain)
+                                               RSurfShader_OpaqueWall_Pass_BaseDetail(surf);
+                       }
                }
                else
                {
                        for (surf = firstsurf;surf;surf = surf->chain)
                        {
                                c_brush_polys++;
-                               RSurfShader_Wall_Pass_BaseMTex(surf);
+                               RSurfShader_OpaqueWall_Pass_BaseTexture(surf);
                        }
                        for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->dlightframe == r_framecount)
-                                       RSurfShader_Wall_Pass_Light(surf);
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->currenttexture->glowtexture)
-                                       RSurfShader_Wall_Pass_Glow(surf);
-                       if (fogenabled)
+                               RSurfShader_OpaqueWall_Pass_BaseLightmap(surf);
+                       if (r_detailtextures.integer)
                                for (surf = firstsurf;surf;surf = surf->chain)
-                                       RSurfShader_Wall_Pass_Fog(surf);
-               }
-       }
-       else if (firstsurf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE)
-       {
-               for (surf = firstsurf;surf;surf = surf->chain)
-               {
-                       c_brush_polys++;
-                       RSurfShader_Wall_Pass_BaseVertex(surf);
+                                       RSurfShader_OpaqueWall_Pass_BaseDetail(surf);
                }
+               if (!r_dlightmap.integer)
+                       for (surf = firstsurf;surf;surf = surf->chain)
+                               if (surf->dlightframe == r_framecount)
+                                       RSurfShader_OpaqueWall_Pass_Light(surf);
                for (surf = firstsurf;surf;surf = surf->chain)
                        if (surf->currenttexture->glowtexture)
-                               RSurfShader_Wall_Pass_Glow(surf);
+                               RSurfShader_OpaqueWall_Pass_Glow(surf);
                if (fogenabled)
                        for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_Wall_Pass_Fog(surf);
-       }
-       else
-       {
-               if (r_dlightmap.integer)
-               {
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                       {
-                               c_brush_polys++;
-                               RSurfShader_Wall_Pass_BaseTexture(surf);
-                       }
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_Wall_Pass_BaseLightmap(surf);
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->currenttexture->glowtexture)
-                                       RSurfShader_Wall_Pass_Glow(surf);
-                       if (fogenabled)
-                               for (surf = firstsurf;surf;surf = surf->chain)
-                                       RSurfShader_Wall_Pass_Fog(surf);
-               }
-               else
-               {
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                       {
-                               c_brush_polys++;
-                               RSurfShader_Wall_Pass_BaseTexture(surf);
-                       }
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               RSurfShader_Wall_Pass_BaseLightmap(surf);
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->dlightframe == r_framecount)
-                                       RSurfShader_Wall_Pass_Light(surf);
-                       for (surf = firstsurf;surf;surf = surf->chain)
-                               if (surf->currenttexture->glowtexture)
-                                       RSurfShader_Wall_Pass_Glow(surf);
-                       if (fogenabled)
-                               for (surf = firstsurf;surf;surf = surf->chain)
-                                       RSurfShader_Wall_Pass_Fog(surf);
-               }
+                               RSurfShader_OpaqueWall_Pass_Fog(surf);
        }
 }
 
@@ -2213,6 +2064,7 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_testvis);
        Cvar_RegisterVariable(&r_floatbuildlightmap);
+       Cvar_RegisterVariable(&r_detailtextures);
 
        R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
 }
diff --git a/menu.c b/menu.c
index cdf21317ce1c21013743cd661e7bf299eacf60c6..7ee7cc6b8411a293642994e0a2da8bc72e8b303c 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1481,7 +1481,7 @@ void M_Options_Key (int k)
        }
 }
 
-#define        OPTIONS_EFFECTS_ITEMS   11
+#define        OPTIONS_EFFECTS_ITEMS   12
 
 int options_effects_cursor;
 
@@ -1493,6 +1493,7 @@ void M_Menu_Options_Effects_f (void)
 }
 
 
+extern cvar_t r_detailtextures;
 extern cvar_t cl_particles;
 extern cvar_t cl_explosions;
 extern cvar_t cl_stainmaps;
@@ -1524,24 +1525,27 @@ void M_Menu_Options_Effects_AdjustSliders (int dir)
                Cvar_SetValueQuick (&cl_stainmaps, !cl_stainmaps.integer);
                break;
        case 4:
-               Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer);
+               Cvar_SetValueQuick (&r_detailtextures, !r_detailtextures.integer);
                break;
        case 5:
-               Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer);
+               Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer);
                break;
        case 6:
-               Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer);
+               Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer);
                break;
        case 7:
-               Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer);
+               Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer);
                break;
        case 8:
-               Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer);
+               Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer);
                break;
        case 9:
-               Cvar_SetValueQuick (&cl_particles_blood_size, bound(2, cl_particles_blood_size.value + dir * 1, 20));
+               Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer);
                break;
        case 10:
+               Cvar_SetValueQuick (&cl_particles_blood_size, bound(2, cl_particles_blood_size.value + dir * 1, 20));
+               break;
+       case 11:
                Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1));
                break;
        }
@@ -1561,6 +1565,7 @@ void M_Options_Effects_Draw (void)
        M_Print(16, y, "             Particles");M_DrawCheckbox(220, y, cl_particles.integer);y += 8;
        M_Print(16, y, "            Explosions");M_DrawCheckbox(220, y, cl_explosions.integer);y += 8;
        M_Print(16, y, "             Stainmaps");M_DrawCheckbox(220, y, cl_stainmaps.integer);y += 8;
+       M_Print(16, y, "      Detail Texturing");M_DrawCheckbox(220, y, r_detailtextures.integer);y += 8;
        M_Print(16, y, "        Bullet Impacts");M_DrawCheckbox(220, y, cl_particles_bulletimpacts.integer);y += 8;
        M_Print(16, y, "                 Smoke");M_DrawCheckbox(220, y, cl_particles_smoke.integer);y += 8;
        M_Print(16, y, "                Sparks");M_DrawCheckbox(220, y, cl_particles_sparks.integer);y += 8;
index 5b7e7dd5979a918c5470921634123cdbf2fda7cf..167f19d49f3004bf52b2b95a67207dc611fb6852 100644 (file)
@@ -33,6 +33,10 @@ cvar_t r_vertexsurfacesthreshold = {CVAR_SAVE, "r_vertexsurfacesthreshold", "0"}
 cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"};
 cvar_t r_sortsurfaces = {0, "r_sortsurfaces", "0"};
 
+#define NUM_DETAILTEXTURES 1
+static rtexture_t *detailtextures[NUM_DETAILTEXTURES];
+static rtexturepool_t *detailtexturepool;
+
 /*
 ===============
 Mod_BrushInit
@@ -51,6 +55,55 @@ void Mod_BrushInit (void)
        memset(mod_novis, 0xff, sizeof(mod_novis));
 }
 
+void Mod_BrushStartup (void)
+{
+       int i, x, y, light;
+       float vc[3], vx[3], vy[3], vn[3], lightdir[3];
+#define DETAILRESOLUTION 256
+       qbyte data[DETAILRESOLUTION][DETAILRESOLUTION][4], noise[DETAILRESOLUTION][DETAILRESOLUTION];
+       detailtexturepool = R_AllocTexturePool();
+       lightdir[0] = 0.5;
+       lightdir[1] = 1;
+       lightdir[2] = -0.25;
+       VectorNormalize(lightdir);
+       for (i = 0;i < NUM_DETAILTEXTURES;i++)
+       {
+               fractalnoise(&noise[0][0], DETAILRESOLUTION, DETAILRESOLUTION >> 4);
+               for (y = 0;y < DETAILRESOLUTION;y++)
+               {
+                       for (x = 0;x < DETAILRESOLUTION;x++)
+                       {
+                               vc[0] = x;
+                               vc[1] = y;
+                               vc[2] = noise[y][x] * (1.0f / 32.0f);
+                               vx[0] = x + 1;
+                               vx[1] = y;
+                               vx[2] = noise[y][(x + 1) % DETAILRESOLUTION] * (1.0f / 32.0f);
+                               vy[0] = x;
+                               vy[1] = y + 1;
+                               vy[2] = noise[(y + 1) % DETAILRESOLUTION][x] * (1.0f / 32.0f);
+                               VectorSubtract(vx, vc, vx);
+                               VectorSubtract(vy, vc, vy);
+                               CrossProduct(vx, vy, vn);
+                               VectorNormalize(vn);
+                               light = 128 - DotProduct(vn, lightdir) * 128;
+                               light = bound(0, light, 255);
+                               data[y][x][0] = data[y][x][1] = data[y][x][2] = light;
+                               data[y][x][3] = 255;
+                       }
+               }
+               detailtextures[i] = R_LoadTexture(detailtexturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
+       }
+}
+
+void Mod_BrushShutdown (void)
+{
+       int i;
+       for (i = 0;i < NUM_DETAILTEXTURES;i++)
+               R_FreeTexture(detailtextures[i]);
+       R_FreeTexturePool(&detailtexturepool);
+}
+
 /*
 ===============
 Mod_PointInLeaf
@@ -353,6 +406,8 @@ static void Mod_LoadTextures (lump_t *l)
                        if (!R_TextureHasAlpha(tx->texture))
                                tx->flags |= SURF_CLIPSOLID;
                }
+
+               tx->detailtexture = detailtextures[i % NUM_DETAILTEXTURES];
        }
 
        // sequence the animations
@@ -1064,6 +1119,9 @@ void Mod_GenerateVertexLitMesh (msurface_t *surf)
                s = DotProduct (out->v, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
                t = DotProduct (out->v, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
 
+               out->ab[0] = s * (1.0f / 16.0f);
+               out->ab[1] = t * (1.0f / 16.0f);
+
                out->st[0] = s / surf->texinfo->texture->width;
                out->st[1] = t / surf->texinfo->texture->height;
 
@@ -1129,6 +1187,9 @@ void Mod_GenerateLightmappedMesh (msurface_t *surf)
                s = DotProduct (out->v, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
                t = DotProduct (out->v, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
 
+               out->ab[0] = s * (1.0f / 16.0f);
+               out->ab[1] = t * (1.0f / 16.0f);
+
                out->st[0] = s / surf->texinfo->texture->width;
                out->st[1] = t / surf->texinfo->texture->height;
 
@@ -1151,7 +1212,7 @@ void Mod_GenerateLightmappedMesh (msurface_t *surf)
 void Mod_GenerateVertexMesh (msurface_t *surf)
 {
        int                             i, *index;
-       float                   *in;
+       float                   *in, s, t;
        surfvertex_t    *out;
        surfmesh_t              *mesh;
 
@@ -1176,8 +1237,12 @@ void Mod_GenerateVertexMesh (msurface_t *surf)
        for (i = 0, in = surf->poly_verts, out = mesh->vertex;i < mesh->numverts;i++, in += 3, out++)
        {
                VectorCopy (in, out->v);
-               out->st[0] = (DotProduct (out->v, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) / surf->texinfo->texture->width;
-               out->st[1] = (DotProduct (out->v, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) / surf->texinfo->texture->height;
+               s = (DotProduct (out->v, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
+               t = (DotProduct (out->v, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
+               out->st[0] = s / surf->texinfo->texture->width;
+               out->st[1] = t / surf->texinfo->texture->height;
+               out->ab[0] = s * (1.0f / 16.0f);
+               out->ab[1] = t * (1.0f / 16.0f);
        }
 }
 
index 30296c1b7114dc4adefec7d6c1120b16f7e8a313..05d810587e93b427459b0ffcb8523b64b8e963af 100644 (file)
@@ -70,6 +70,8 @@ typedef struct texture_s
        rtexture_t *glowtexture;
        // alpha texture (used for fogging), NULL if opaque
        rtexture_t *fogtexture;
+       // detail texture (usually not used if transparent)
+       rtexture_t *detailtexture;
 
        // total frames in sequence and alternate sequence
        int anim_total[2];
@@ -116,6 +118,8 @@ typedef struct surfvertex_s
        float st[2];
        // lightmap coordinates
        float uv[2];
+       // detail texture coordinates
+       float ab[2];
 }
 surfvertex_t;
 
index 01e1e46b79964e58a68bf5d3258d8f69eb9acdd1..adbe9348adaaa8f4360df748a39f8ccb58beb301 100644 (file)
@@ -66,6 +66,9 @@ void Mod_SetupNoTexture(void)
        r_notexture = R_LoadTexture(r_notexturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP);
 }
 
+extern void Mod_BrushStartup (void);
+extern void Mod_BrushShutdown (void);
+
 static void mod_start(void)
 {
        int i;
@@ -74,6 +77,7 @@ static void mod_start(void)
                        Mod_UnloadModel(&mod_known[i]);
 
        Mod_SetupNoTexture();
+       Mod_BrushStartup();
 }
 
 static void mod_shutdown(void)
@@ -84,6 +88,7 @@ static void mod_shutdown(void)
                        Mod_UnloadModel(&mod_known[i]);
 
        R_FreeTexturePool(&r_notexturepool);
+       Mod_BrushShutdown();
 }
 
 static void mod_newmap(void)
index 7bb5778977abd9bf022aad5c2f338e2485ce61d1..158734b0f9dab39e783b21de3a55a9fea8c3d0f4 100644 (file)
@@ -173,7 +173,7 @@ void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, floa
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = R_GetTexture(texture);
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                m.index[0] = 0;
                m.index[1] = 1;
@@ -184,7 +184,7 @@ void R_DrawCrosshairSprite(rtexture_t *texture, vec3_t origin, vec_t scale, floa
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = cr * m.colorscale;
                m.color[1] = m.color[5] = m.color[9] = m.color[13] = cg * m.colorscale;
                m.color[2] = m.color[6] = m.color[10] = m.color[14] = cb * m.colorscale;
-               m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca * m.colorscale;
+               m.color[3] = m.color[7] = m.color[11] = m.color[15] = ca;
                m.texcoords[0][0] = 0;
                m.texcoords[0][1] = 0;
                m.texcoords[0][2] = 0;
index e679ec8ccc16e334973aefe126b0b0d8d6fd3415..3f8daa4b8007d554510bc0367321687af6f4dc57 100644 (file)
@@ -186,7 +186,7 @@ void R_DrawExplosion(explosion_t *e)
        m.numtriangles = EXPLOSIONTRIS;
        m.numverts = EXPLOSIONVERTS;
        m.tex[0] = R_GetTexture(explosiontexture);
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, explosiontris, m.numtriangles * sizeof(int[3]));
                for (i = 0, v = m.vertex;i < m.numverts;i++, v += 4)
index 8d4be018d63016cad244bd1abb2f50db3f598e48..da977bf092ce4146d4c984ca5dfd5eab9c8be9ee 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -154,7 +154,7 @@ void R_DrawCoronas(void)
                {
                        // trace to a point just barely closer to the eye
                        VectorSubtract(rd->origin, vpn, diff);
-                       if (CL_TraceLine(r_origin, diff, NULL, NULL, 0, true) == 1 && R_Mesh_Draw_GetBuffer(&m))
+                       if (CL_TraceLine(r_origin, diff, NULL, NULL, 0, true) == 1 && R_Mesh_Draw_GetBuffer(&m, false))
                        {
                                scale = m.colorscale * (1.0f / 131072.0f);
                                if (fogenabled)
diff --git a/r_sky.c b/r_sky.c
index 3e9d9bf58945eed13182d45f2b1d768a4e3dca75..497d7f719b58dd5fd9b5c8127d0afd4a443d94fb 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -171,7 +171,7 @@ static void R_SkyBox(void)
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = R_GetTexture(skyboxside[3]); // front
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -184,7 +184,7 @@ static void R_SkyBox(void)
                R_SkyBoxPolyVec(3, 0, 0,  1,  1,  1);
        }
        m.tex[0] = R_GetTexture(skyboxside[1]); // back
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -197,7 +197,7 @@ static void R_SkyBox(void)
                R_SkyBoxPolyVec(3, 0, 0, -1, -1,  1);
        }
        m.tex[0] = R_GetTexture(skyboxside[0]); // right
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -210,7 +210,7 @@ static void R_SkyBox(void)
                R_SkyBoxPolyVec(3, 0, 0, -1,  1,  1);
        }
        m.tex[0] = R_GetTexture(skyboxside[2]); // left
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -223,7 +223,7 @@ static void R_SkyBox(void)
                R_SkyBoxPolyVec(3, 0, 0,  1, -1,  1);
        }
        m.tex[0] = R_GetTexture(skyboxside[4]); // up
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -236,7 +236,7 @@ static void R_SkyBox(void)
                R_SkyBoxPolyVec(3, 0, 0, -1, -1,  1);
        }
        m.tex[0] = R_GetTexture(skyboxside[5]); // down
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skyboxindex, sizeof(int[6]));
                m.color[0] = m.color[4] = m.color[8] = m.color[12] = m.colorscale;
@@ -341,7 +341,7 @@ static void R_SkySphere(void)
        m.numtriangles = skygridx*skygridy*2;
        m.numverts = skygridx1*skygridy1;
        m.tex[0] = R_GetTexture(solidskytexture);
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skysphereindices, m.numtriangles * sizeof(int[3]));
                skyspherearrays(m.vertex, m.texcoords[0], m.color, skysphere, speedscale, m.colorscale);
@@ -349,7 +349,7 @@ static void R_SkySphere(void)
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
        m.tex[0] = R_GetTexture(alphaskytexture);
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, false))
        {
                memcpy(m.index, skysphereindices, m.numtriangles * sizeof(int[3]));
                skyspherearrays(m.vertex, m.texcoords[0], m.color, skysphere, speedscale2, m.colorscale);
index 6e732ec24182388153e5b604999bf526f2e51ad8..f6ca3a4af50966426919b520599f6d961109f9cd 100644 (file)
@@ -92,7 +92,7 @@ static void GL_DrawSpriteImage (int fog, mspriteframe_t *frame, int texture, vec
        m.numtriangles = 2;
        m.numverts = 4;
        m.tex[0] = texture;
-       if (R_Mesh_Draw_GetBuffer(&m))
+       if (R_Mesh_Draw_GetBuffer(&m, !(currentrenderentity->model->flags & EF_FULLBRIGHT || currentrenderentity->effects & EF_FULLBRIGHT)))
        {
                m.index[0] = 0;
                m.index[1] = 1;
index cecb01c0d7c61d5f9d8d146c17bda30282e76046..16c158bc2f6e60221ccb0385eba5b5147cd65bf7 100644 (file)
--- a/render.h
+++ b/render.h
@@ -65,6 +65,9 @@ extern float *aliasvertcolor;
 // vis stuff
 extern cvar_t r_novis;
 
+// detail texture stuff
+extern cvar_t r_detailtextures;
+
 #define        TOP_RANGE               16                      // soldier uniform colors
 #define        BOTTOM_RANGE    96
 
@@ -156,7 +159,7 @@ void R_DrawSpriteModel (void);
 extern cvar_t r_render;
 #include "image.h"
 
-extern cvar_t r_multitexture;
+extern cvar_t r_textureunits;
 extern cvar_t gl_dither;
 
 // FIXME: this should live in the backend only