added r_refdef.rtlightstylevalue which is a float version of the normal
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Dec 2007 11:57:09 +0000 (11:57 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Dec 2007 11:57:09 +0000 (11:57 +0000)
lightstylevalue array, but this one is always interpolated (lightstyle
interpolation does not harm rtworld performance)
cleaned up Q1BSP LightPoint code

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

cl_main.c
client.h
gl_rmain.c
model_brush.c
r_shadow.c

index 87b6948..9e1c7fb 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -761,12 +761,11 @@ void CL_RelinkLightFlashes(void)
        f = cl.time * 10;
        i = (int)floor(f);
        frac = f - i;
-       if (!r_lerplightstyles.integer)
-               frac = 1;
        for (j = 0;j < cl.max_lightstyle;j++)
        {
                if (!cl.lightstyle || !cl.lightstyle[j].length)
                {
+                       r_refdef.rtlightstylevalue[j] = 1;
                        r_refdef.lightstylevalue[j] = 256;
                        continue;
                }
@@ -774,7 +773,13 @@ void CL_RelinkLightFlashes(void)
                l = (i-1) % cl.lightstyle[j].length;
                k = cl.lightstyle[j].map[k] - 'a';
                l = cl.lightstyle[j].map[l] - 'a';
-               r_refdef.lightstylevalue[j] = (unsigned short)(((k*frac)+(l*(1-frac)))*22);
+               // rtlightstylevalue is always interpolated because it has no bad
+               // consequences for performance
+               // lightstylevalue is subject to a cvar for performance reasons;
+               // skipping lightmap updates on most rendered frames substantially
+               // improves framerates (but makes light fades look bad)
+               r_refdef.rtlightstylevalue[j] = ((k*frac)+(l*(1-frac)))*(22/256.0f);
+               r_refdef.lightstylevalue[j] = r_lerplightstyles.integer ? (unsigned short)(((k*frac)+(l*(1-frac)))*22) : k*22;
        }
 }
 
index 2628dce..adced35 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1383,9 +1383,11 @@ typedef struct r_refdef_s
        rtlight_t lights[MAX_DLIGHTS];
        int numlights;
 
+       // intensities for light styles right now, controls rtlights
+       float rtlightstylevalue[256];   // float fraction of base light value
        // 8.8bit fixed point intensities for light styles
-       // controls intensity of dynamic lights and lightmap layers
-       unsigned short  lightstylevalue[256];   // 8.8 fraction of base light value
+       // controls intensity lightmap layers
+       unsigned short lightstylevalue[256];    // 8.8 fraction of base light value
 
        vec3_t fogcolor;
        vec_t fogrange;
index 04c2bbd..35c63ab 100644 (file)
@@ -4227,7 +4227,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // applied to the color
                                        // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright)
                                        if (ent->model->type == mod_brushq3)
-                                               colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
+                                               colorscale *= r_refdef.rtlightstylevalue[0];
                                        colorscale *= r_refdef.lightmapintensity;
                                        R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
                                        if (r_ambient.value >= (1.0f/64.0f))
@@ -6265,7 +6265,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep
        RSurf_ActiveWorldEntity();
 
        // update light styles on this submodel
-       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
+       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
        {
                model_brush_lightstyleinfo_t *style;
                for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
@@ -6354,7 +6354,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr
                RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader && !depthonly);
 
        // update light styles
-       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
+       if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
        {
                model_brush_lightstyleinfo_t *style;
                for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
index 3a9c14c..a0bbc6f 100644 (file)
@@ -1125,8 +1125,14 @@ loc0:
                // check for impact on this node
                if (node->numsurfaces)
                {
-                       int i, ds, dt;
+                       int i, dsi, dti, lmwidth, lmheight;
+                       float ds, dt;
                        msurface_t *surface;
+                       unsigned char *lightmap;
+                       int maps, line3, size3;
+                       float dsfrac;
+                       float dtfrac;
+                       float scale, w, w00, w01, w10, w11;
 
                        surface = model->data_surfaces + node->firstsurface;
                        for (i = 0;i < node->numsurfaces;i++, surface++)
@@ -1134,66 +1140,46 @@ loc0:
                                if (!(surface->texture->basematerialflags & MATERIALFLAG_WALL) || !surface->lightmapinfo->samples)
                                        continue;       // no lightmaps
 
-                               ds = (int) (x * surface->lightmapinfo->texinfo->vecs[0][0] + y * surface->lightmapinfo->texinfo->vecs[0][1] + mid * surface->lightmapinfo->texinfo->vecs[0][2] + surface->lightmapinfo->texinfo->vecs[0][3]) - surface->lightmapinfo->texturemins[0];
-                               dt = (int) (x * surface->lightmapinfo->texinfo->vecs[1][0] + y * surface->lightmapinfo->texinfo->vecs[1][1] + mid * surface->lightmapinfo->texinfo->vecs[1][2] + surface->lightmapinfo->texinfo->vecs[1][3]) - surface->lightmapinfo->texturemins[1];
+                               // location we want to sample in the lightmap
+                               ds = ((x * surface->lightmapinfo->texinfo->vecs[0][0] + y * surface->lightmapinfo->texinfo->vecs[0][1] + mid * surface->lightmapinfo->texinfo->vecs[0][2] + surface->lightmapinfo->texinfo->vecs[0][3]) - surface->lightmapinfo->texturemins[0]) * 0.0625f;
+                               dt = ((x * surface->lightmapinfo->texinfo->vecs[1][0] + y * surface->lightmapinfo->texinfo->vecs[1][1] + mid * surface->lightmapinfo->texinfo->vecs[1][2] + surface->lightmapinfo->texinfo->vecs[1][3]) - surface->lightmapinfo->texturemins[1]) * 0.0625f;
 
-                               if (ds >= 0 && ds < surface->lightmapinfo->extents[0] && dt >= 0 && dt < surface->lightmapinfo->extents[1])
+                               // check the bounds
+                               dsi = (int)ds;
+                               dti = (int)dt;
+                               lmwidth = ((surface->lightmapinfo->extents[0]>>4)+1);
+                               lmheight = ((surface->lightmapinfo->extents[1]>>4)+1);
+
+                               // is it in bounds?
+                               if (dsi >= 0 && dsi < lmwidth-1 && dti >= 0 && dti < lmheight-1)
                                {
-                                       unsigned char *lightmap;
-                                       int lmwidth, lmheight, maps, line3, size3, dsfrac = ds & 15, dtfrac = dt & 15, scale = 0, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0;
-                                       lmwidth = ((surface->lightmapinfo->extents[0]>>4)+1);
-                                       lmheight = ((surface->lightmapinfo->extents[1]>>4)+1);
+                                       // calculate bilinear interpolation factors
+                                       // and also multiply by fixedpoint conversion factors
+                                       dsfrac = ds - dsi;
+                                       dtfrac = dt - dti;
+                                       w00 = (1 - dsfrac) * (1 - dtfrac) * (1.0f / 32768.0f);
+                                       w01 = (    dsfrac) * (1 - dtfrac) * (1.0f / 32768.0f);
+                                       w10 = (1 - dsfrac) * (    dtfrac) * (1.0f / 32768.0f);
+                                       w11 = (    dsfrac) * (    dtfrac) * (1.0f / 32768.0f);
+
+                                       // values for pointer math
                                        line3 = lmwidth * 3; // LordHavoc: *3 for colored lighting
                                        size3 = lmwidth * lmheight * 3; // LordHavoc: *3 for colored lighting
 
-                                       lightmap = surface->lightmapinfo->samples + ((dt>>4) * lmwidth + (ds>>4))*3; // LordHavoc: *3 for colored lighting
+                                       // look up the pixel
+                                       lightmap = surface->lightmapinfo->samples + dti * line3 + dsi*3; // LordHavoc: *3 for colored lighting
 
+                                       // bilinear filter each lightmap style, and sum them
                                        for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++)
                                        {
                                                scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]];
-                                               r00 += lightmap[      0] * scale;g00 += lightmap[      1] * scale;b00 += lightmap[      2] * scale;
-                                               r01 += lightmap[      3] * scale;g01 += lightmap[      4] * scale;b01 += lightmap[      5] * scale;
-                                               r10 += lightmap[line3+0] * scale;g10 += lightmap[line3+1] * scale;b10 += lightmap[line3+2] * scale;
-                                               r11 += lightmap[line3+3] * scale;g11 += lightmap[line3+4] * scale;b11 += lightmap[line3+5] * scale;
+                                               w = w00 * scale;VectorMA(ambientcolor, w, lightmap            , ambientcolor);
+                                               w = w01 * scale;VectorMA(ambientcolor, w, lightmap + 3        , ambientcolor);
+                                               w = w10 * scale;VectorMA(ambientcolor, w, lightmap + line3    , ambientcolor);
+                                               w = w11 * scale;VectorMA(ambientcolor, w, lightmap + line3 + 3, ambientcolor);
                                                lightmap += size3;
                                        }
 
-/*
-LordHavoc: here's the readable version of the interpolation
-code, not quite as easy for the compiler to optimize...
-
-dsfrac is the X position in the lightmap pixel, * 16
-dtfrac is the Y position in the lightmap pixel, * 16
-r00 is top left corner, r01 is top right corner
-r10 is bottom left corner, r11 is bottom right corner
-g and b are the same layout.
-r0 and r1 are the top and bottom intermediate results
-
-first we interpolate the top two points, to get the top
-edge sample
-
-       r0 = (((r01-r00) * dsfrac) >> 4) + r00;
-       g0 = (((g01-g00) * dsfrac) >> 4) + g00;
-       b0 = (((b01-b00) * dsfrac) >> 4) + b00;
-
-then we interpolate the bottom two points, to get the
-bottom edge sample
-
-       r1 = (((r11-r10) * dsfrac) >> 4) + r10;
-       g1 = (((g11-g10) * dsfrac) >> 4) + g10;
-       b1 = (((b11-b10) * dsfrac) >> 4) + b10;
-
-then we interpolate the top and bottom samples to get the
-middle sample (the one which was requested)
-
-       r = (((r1-r0) * dtfrac) >> 4) + r0;
-       g = (((g1-g0) * dtfrac) >> 4) + g0;
-       b = (((b1-b0) * dtfrac) >> 4) + b0;
-*/
-
-                                       ambientcolor[0] += (float) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00)) * (1.0f / 32768.0f);
-                                       ambientcolor[1] += (float) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00)) * (1.0f / 32768.0f);
-                                       ambientcolor[2] += (float) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00)) * (1.0f / 32768.0f);
                                        return true; // success
                                }
                        }
@@ -5206,7 +5192,7 @@ static void Mod_Q3BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientc
        q3dlightgrid_t *a, *s;
 
        // scale lighting by lightstyle[0] so that darkmode in dpmod works properly
-       stylescale = r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
+       stylescale = r_refdef.rtlightstylevalue[0];
 
        if (!model->brushq3.num_lightgrid)
        {
index 9d103b0..c520ac5 100644 (file)
@@ -2836,7 +2836,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        rtlight->currentcubemap = rtlight->cubemapname[0] ? R_Shadow_Cubemap(rtlight->cubemapname) : r_texture_whitecube;
 
        // look up the light style value at this time
-       f = (rtlight->style >= 0 ? r_refdef.lightstylevalue[rtlight->style] : 128) * (1.0f / 256.0f) * r_shadow_lightintensityscale.value;
+       f = (rtlight->style >= 0 ? r_refdef.rtlightstylevalue[rtlight->style] : 1) * r_shadow_lightintensityscale.value;
        VectorScale(rtlight->color, f, rtlight->currentcolor);
        /*
        if (rtlight->selected)