summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/refresh/refresh.h2
-rw-r--r--src/client/view.c17
-rw-r--r--src/refresh/gl/gl.h2
-rw-r--r--src/refresh/sw/alias.c9
-rw-r--r--src/refresh/sw/bsp.c2
-rw-r--r--src/refresh/sw/light.c338
-rw-r--r--src/refresh/sw/main.c4
-rw-r--r--src/refresh/sw/surf.c8
-rw-r--r--src/refresh/sw/sw.h3
9 files changed, 206 insertions, 179 deletions
diff --git a/inc/refresh/refresh.h b/inc/refresh/refresh.h
index 6e79691..3edcc18 100644
--- a/inc/refresh/refresh.h
+++ b/inc/refresh/refresh.h
@@ -51,6 +51,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define RF_SHELL_MASK (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | \
RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)
+#define DLIGHT_CUTOFF 64
+
typedef struct entity_s {
qhandle_t model; // opaque type outside refresh
vec3_t angles;
diff --git a/src/client/view.c b/src/client/view.c
index ed5b840..808505e 100644
--- a/src/client/view.c
+++ b/src/client/view.c
@@ -123,16 +123,6 @@ void V_AddLight(vec3_t org, float intensity, float r, float g, float b)
return;
dl = &r_dlights[r_numdlights++];
VectorCopy(org, dl->origin);
-#if USE_REF == REF_SOFT
- // negative light in softwaref. only black allowed
- if (r < 0 || g < 0 || b < 0) {
- dl->intensity = -intensity;
- dl->color[0] = 1;
- dl->color[1] = 1;
- dl->color[2] = 1;
- return;
- }
-#endif
dl->intensity = intensity;
dl->color[0] = r;
dl->color[1] = g;
@@ -239,12 +229,15 @@ static void V_TestLights(void)
float f, r;
dlight_t *dl;
- if (cl_testlights->integer == 2) {
+ if (cl_testlights->integer != 1) {
dl = &r_dlights[0];
r_numdlights = 1;
VectorMA(cl.refdef.vieworg, 256, cl.v_forward, dl->origin);
- VectorSet(dl->color, 1, 1, 1);
+ if (cl_testlights->integer == -1)
+ VectorSet(dl->color, -1, -1, -1);
+ else
+ VectorSet(dl->color, 1, 1, 1);
dl->intensity = 256;
return;
}
diff --git a/src/refresh/gl/gl.h b/src/refresh/gl/gl.h
index 0ccc586..3064967 100644
--- a/src/refresh/gl/gl.h
+++ b/src/refresh/gl/gl.h
@@ -232,8 +232,6 @@ typedef struct maliasmesh_s {
* gl_surf.c
*
*/
-#define DLIGHT_CUTOFF 64
-
#define LIGHT_STYLE(surf, i) \
&glr.fd.lightstyles[gl_static.lightstylemap[(surf)->styles[i]]]
diff --git a/src/refresh/sw/alias.c b/src/refresh/sw/alias.c
index 0970f6d..dad1748 100644
--- a/src/refresh/sw/alias.c
+++ b/src/refresh/sw/alias.c
@@ -472,8 +472,6 @@ static void R_AliasSetupSkin(void)
/*
================
R_AliasSetupLighting
-
- FIXME: put lighting into tables
================
*/
static void R_AliasSetupLighting(void)
@@ -484,13 +482,11 @@ static void R_AliasSetupLighting(void)
// all components of light should be identical in software
if (currententity->flags & RF_FULLBRIGHT) {
- for (i = 0; i < 3; i++)
- light[i] = 1.0;
+ VectorSet(light, 1, 1, 1);
} else {
R_LightPoint(currententity->origin, light);
}
-
if (currententity->flags & RF_MINLIGHT) {
for (i = 0; i < 3; i++)
if (light[i] < 0.1)
@@ -511,6 +507,9 @@ static void R_AliasSetupLighting(void)
}
}
+ for (i = 0; i < 3; i++)
+ clamp(light[i], 0, 1);
+
j = LUMINANCE(light[0], light[1], light[2]) * 256;
r_ambientlight = 0;
diff --git a/src/refresh/sw/bsp.c b/src/refresh/sw/bsp.c
index d7430de..cde3410 100644
--- a/src/refresh/sw/bsp.c
+++ b/src/refresh/sw/bsp.c
@@ -29,7 +29,7 @@ vec3_t modelorg; // modelorg is the viewpoint reletive to
vec3_t r_entorigin; // the currently rendering entity in world
// coordinates
-static float entity_rotation[3][3];
+vec3_t entity_rotation[3];
int r_currentbkey;
diff --git a/src/refresh/sw/light.c b/src/refresh/sw/light.c
index 78f3556..20d494a 100644
--- a/src/refresh/sw/light.c
+++ b/src/refresh/sw/light.c
@@ -32,67 +32,69 @@ DYNAMIC LIGHTS
/*
=============
-R_MarkLights
+R_MarkLights_r
=============
*/
-static void R_MarkLights(dlight_t *light, int bit, mnode_t *node)
+static void R_MarkLights_r(mnode_t *node, dlight_t *light,
+ vec3_t transformed, int bit)
{
- cplane_t *splitplane;
float dist;
mface_t *surf;
int i;
- if (!node->plane)
- return;
-
- splitplane = node->plane;
- dist = DotProduct(light->origin, splitplane->normal) - splitplane->dist;
-
- i = light->intensity;
- if (i < 0)
- i = -i;
-
- if (dist > i) {
- R_MarkLights(light, bit, node->children[0]);
- return;
- }
- if (dist < -i) {
- R_MarkLights(light, bit, node->children[1]);
- return;
- }
+ while (node->plane) {
+ dist = PlaneDiffFast(transformed, node->plane);
+ if (dist > light->intensity - DLIGHT_CUTOFF) {
+ node = node->children[0];
+ continue;
+ }
+ if (dist < -light->intensity + DLIGHT_CUTOFF) {
+ node = node->children[1];
+ continue;
+ }
-// mark the polygons
- surf = node->firstface;
- for (i = 0; i < node->numfaces; i++, surf++) {
- if (surf->dlightframe != r_dlightframecount) {
- surf->dlightbits = 0;
- surf->dlightframe = r_dlightframecount;
+ // mark the polygons
+ surf = node->firstface;
+ for (i = 0; i < node->numfaces; i++, surf++) {
+ if (surf->dlightframe != r_dlightframecount) {
+ surf->dlightbits = 0;
+ surf->dlightframe = r_dlightframecount;
+ }
+ surf->dlightbits |= bit;
}
- surf->dlightbits |= bit;
- }
- R_MarkLights(light, bit, node->children[0]);
- R_MarkLights(light, bit, node->children[1]);
+ R_MarkLights_r(node->children[0], light, transformed, bit);
+ node = node->children[1];
+ }
}
-
/*
=============
-R_PushDlights
+R_MarkLights
=============
*/
-void R_PushDlights(mnode_t *headnode)
+void R_MarkLights(mnode_t *headnode)
{
- int i;
- dlight_t *l;
+ dlight_t *light;
+ vec3_t transformed;
+ int i;
r_dlightframecount = r_framecount;
- for (i = 0, l = r_newrefdef.dlights; i < r_newrefdef.num_dlights; i++, l++) {
- R_MarkLights(l, 1 << i, headnode);
+ for (i = 0, light = r_newrefdef.dlights; i < r_newrefdef.num_dlights; i++, light++) {
+ if (insubmodel) {
+ vec3_t temp;
+
+ VectorSubtract(light->origin, currententity->origin, temp);
+ transformed[0] = DotProduct(temp, entity_rotation[0]);
+ transformed[1] = DotProduct(temp, entity_rotation[1]);
+ transformed[2] = DotProduct(temp, entity_rotation[2]);
+ } else {
+ VectorCopy(light->origin, transformed);
+ }
+ R_MarkLights_r(headnode, light, transformed, 1 << i);
}
}
-
/*
=============================================================================
@@ -101,14 +103,17 @@ LIGHT SAMPLING
=============================================================================
*/
-static qboolean RecursiveLightPoint(vec3_t start, vec3_t color)
+static qboolean _R_LightPoint(vec3_t start, vec3_t color)
{
mface_t *surf;
- int smax, tmax, size;
- int ds, dt;
+ int s, t, maps;
byte *lightmap;
- float *scales;
- int maps;
+ byte *b1, *b2, *b3, *b4;
+ int fracu, fracv;
+ int w1, w2, w3, w4;
+ byte temp[3];
+ int smax, tmax, size;
+ float scale;
vec3_t end;
lightpoint_t lightpoint;
@@ -122,21 +127,39 @@ static qboolean RecursiveLightPoint(vec3_t start, vec3_t color)
if (!surf)
return qfalse;
- ds = lightpoint.s >> 4;
- dt = lightpoint.t >> 4;
+ fracu = lightpoint.s & 15;
+ fracv = lightpoint.t & 15;
+
+ // compute weights of lightmap blocks
+ w1 = (16 - fracu) * (16 - fracv);
+ w2 = fracu * (16 - fracv);
+ w3 = fracu * fracv;
+ w4 = (16 - fracu) * fracv;
+
+ s = lightpoint.s >> 4;
+ t = lightpoint.t >> 4;
smax = S_MAX(surf);
tmax = T_MAX(surf);
size = smax * tmax * LIGHTMAP_BYTES;
+ // add all the lightmaps with bilinear filtering
lightmap = surf->lightmap;
- lightmap += dt * smax * LIGHTMAP_BYTES + ds * LIGHTMAP_BYTES;
-
for (maps = 0; maps < surf->numstyles; maps++) {
- scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
- color[0] += lightmap[0] * scales[0] * (1.0f / 255);
- color[1] += lightmap[1] * scales[1] * (1.0f / 255);
- color[2] += lightmap[2] * scales[2] * (1.0f / 255);
+ b1 = &lightmap[LIGHTMAP_BYTES * ((t + 0) * smax + (s + 0))];
+ b2 = &lightmap[LIGHTMAP_BYTES * ((t + 0) * smax + (s + 1))];
+ b3 = &lightmap[LIGHTMAP_BYTES * ((t + 1) * smax + (s + 1))];
+ b4 = &lightmap[LIGHTMAP_BYTES * ((t + 1) * smax + (s + 0))];
+
+ temp[0] = (w1 * b1[0] + w2 * b2[0] + w3 * b3[0] + w4 * b4[0]) >> 8;
+ temp[1] = (w1 * b1[1] + w2 * b2[1] + w3 * b3[1] + w4 * b4[1]) >> 8;
+ temp[2] = (w1 * b1[2] + w2 * b2[2] + w3 * b3[2] + w4 * b4[2]) >> 8;
+
+ scale = r_newrefdef.lightstyles[surf->styles[maps]].white * (1.0f / 255);
+ color[0] += temp[0] * scale;
+ color[1] += temp[1] * scale;
+ color[2] += temp[2] * scale;
+
lightmap += size;
}
@@ -148,21 +171,20 @@ static qboolean RecursiveLightPoint(vec3_t start, vec3_t color)
R_LightPoint
===============
*/
-void R_LightPoint(vec3_t p, vec3_t color)
+void R_LightPoint(vec3_t point, vec3_t color)
{
int lnum;
dlight_t *dl;
- vec3_t dist;
float add;
- if (!r_worldmodel || !r_worldmodel->lightmap || !r_newrefdef.lightstyles) {
+ if (!r_worldmodel || !r_worldmodel->lightmap || r_fullbright->integer) {
VectorSet(color, 1, 1, 1);
return;
}
VectorClear(color);
- if (!RecursiveLightPoint(p, color))
+ if (!_R_LightPoint(point, color))
VectorSet(color, 1, 1, 1);
//
@@ -170,12 +192,9 @@ void R_LightPoint(vec3_t p, vec3_t color)
//
for (lnum = 0; lnum < r_newrefdef.num_dlights; lnum++) {
dl = &r_newrefdef.dlights[lnum];
- VectorSubtract(p,
- dl->origin,
- dist);
- add = dl->intensity - VectorLength(dist);
- add *= (1.0 / 256);
+ add = dl->intensity - DLIGHT_CUTOFF - Distance(point, dl->origin);
if (add > 0) {
+ add *= (1.0f / 255);
VectorMA(color, add, dl->color, color);
}
}
@@ -194,47 +213,45 @@ R_AddDynamicLights
*/
static void R_AddDynamicLights(void)
{
- mface_t *surf;
- int lnum;
- int sd, td;
- float dist, rad, minlight;
- vec3_t impact, local;
- int s, t;
- int i;
- int smax, tmax;
- mtexinfo_t *tex;
- dlight_t *dl;
- int negativeLight;
- blocklight_t *block;
+ mface_t *surf;
+ dlight_t *light;
+ mtexinfo_t *tex;
+ vec3_t transformed, impact;
+ int local[2];
+ vec_t dist, rad, minlight, scale, frac;
+ blocklight_t *block;
+ int i, smax, tmax, s, t, sd, td;
surf = r_drawsurf.surf;
smax = S_MAX(surf);
tmax = T_MAX(surf);
tex = surf->texinfo;
- for (lnum = 0; lnum < r_newrefdef.num_dlights; lnum++) {
- if (!(surf->dlightbits & (1 << lnum)))
- continue; // not lit by this light
+ for (i = 0; i < r_newrefdef.num_dlights; i++) {
+ if (!(surf->dlightbits & (1 << i)))
+ continue;
- dl = &r_newrefdef.dlights[lnum];
- rad = dl->intensity;
+ light = &r_newrefdef.dlights[i];
+
+ if (currententity && currententity != &r_worldentity) {
+ vec3_t temp;
- negativeLight = 0;
- if (rad < 0) {
- negativeLight = 1;
- rad = -rad;
+ VectorSubtract(light->origin, currententity->origin, temp);
+ transformed[0] = DotProduct(temp, entity_rotation[0]);
+ transformed[1] = DotProduct(temp, entity_rotation[1]);
+ transformed[2] = DotProduct(temp, entity_rotation[2]);
+ } else {
+ VectorCopy(light->origin, transformed);
}
- dist = PlaneDiffFast(dl->origin, surf->plane);
- rad -= fabs(dist);
- minlight = 32; // dl->minlight;
- if (rad < minlight)
+ dist = PlaneDiffFast(transformed, surf->plane);
+ rad = light->intensity - fabs(dist);
+ if (rad < DLIGHT_CUTOFF)
continue;
- minlight = rad - minlight;
+ minlight = rad - DLIGHT_CUTOFF * 0.8f;
+ scale = rad / minlight;
- for (i = 0; i < 3; i++) {
- impact[i] = dl->origin[i] - surf->plane->normal[i] * dist;
- }
+ VectorMA(transformed, -dist, surf->plane->normal, impact);
local[0] = DotProduct(impact, tex->axis[0]) + tex->offset[0];
local[1] = DotProduct(impact, tex->axis[1]) + tex->offset[1];
@@ -242,48 +259,27 @@ static void R_AddDynamicLights(void)
local[0] -= surf->texturemins[0];
local[1] -= surf->texturemins[1];
+ block = blocklights;
for (t = 0; t < tmax; t++) {
- td = local[1] - t * 16;
- if (td < 0)
- td = -td;
+ td = abs(local[1] - (t << 4));
for (s = 0; s < smax; s++) {
- sd = local[0] - s * 16;
- if (sd < 0)
- sd = -sd;
- /*if (sd > td)
- dist = sd + (td>>1);
+ sd = abs(local[0] - (s << 4));
+ if (sd > td)
+ dist = sd + (td >> 1);
else
- dist = td + (sd>>1);*/
- dist = sqrt(sd * sd + td * td);
- block = blocklights + t * smax * LIGHTMAP_BYTES + s * LIGHTMAP_BYTES;
- if (!negativeLight) {
- if (dist < minlight) {
- block[0] += (rad - dist) * dl->color[0] * 256;
- block[1] += (rad - dist) * dl->color[1] * 256;
- block[2] += (rad - dist) * dl->color[2] * 256;
- }
- } else {
- if (dist < minlight) {
- block[0] -= (rad - dist) * dl->color[0] * 256;
- block[1] -= (rad - dist) * dl->color[1] * 256;
- block[2] -= (rad - dist) * dl->color[2] * 256;
- }
- if (block[0] < minlight) {
- block[0] = minlight;
- }
- if (block[1] < minlight) {
- block[1] = minlight;
- }
- if (block[2] < minlight) {
- block[2] = minlight;
- }
+ dist = td + (sd >> 1);
+ if (dist < minlight) {
+ frac = (rad - dist * scale) * sw_modulate->value * 256;
+ block[0] += light->color[0] * frac;
+ block[1] += light->color[1] * frac;
+ block[2] += light->color[2] * frac;
}
+ block += LIGHTMAP_BYTES;
}
}
}
}
-
/*
===============
R_BuildLightMap
@@ -293,45 +289,45 @@ Combine and scale multiple lightmaps into the 8.8 format in blocklights
*/
void R_BuildLightMap(void)
{
- int smax, tmax;
- int i, size;
- byte *lightmap;
- int maps;
- mface_t *surf;
- blocklight_t *dst;
+ int i, maps, smax, tmax, size;
+ byte *lightmap;
+ mface_t *surf;
+ blocklight_t *block;
surf = r_drawsurf.surf;
-
smax = S_MAX(surf);
tmax = T_MAX(surf);
size = smax * tmax;
- if (size > MAX_BLOCKLIGHTS) {
- Com_Error(ERR_DROP, "R_BuildLightMap: surface blocklights size %i > %i", size, MAX_BLOCKLIGHTS);
- }
-// clear to no light
- memset(blocklights, 0, sizeof(blocklights));
+ if (size > MAX_BLOCKLIGHTS)
+ Com_Error(ERR_DROP, "R_BuildLightMap: surface blocklights size %i > %i", size, MAX_BLOCKLIGHTS);
- if (r_fullbright->integer || !r_worldmodel->lightmap) {
+ if (r_fullbright->integer || !surf->lightmap) {
+ block = blocklights;
+ for (i = 0; i < size; i++) {
+ block[0] = block[1] = block[2] = 0xffff;
+ block += LIGHTMAP_BYTES;
+ }
return;
}
+// clear to no light
+ memset(blocklights, 0, sizeof(blocklights[0]) * size * LIGHTMAP_BYTES);
+
// add all the lightmaps
lightmap = surf->lightmap;
- if (lightmap) {
- for (maps = 0; maps < surf->numstyles; maps++) {
- fixed8_t scale;
-
- dst = blocklights;
- scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
- for (i = 0; i < size; i++) {
- blocklights[i * LIGHTMAP_BYTES + 0] += lightmap[0] * scale;
- blocklights[i * LIGHTMAP_BYTES + 1] += lightmap[1] * scale;
- blocklights[i * LIGHTMAP_BYTES + 2] += lightmap[2] * scale;
-
- lightmap += LIGHTMAP_BYTES;
- dst += LIGHTMAP_BYTES;
- }
+ for (maps = 0; maps < surf->numstyles; maps++) {
+ fixed8_t scale;
+
+ block = blocklights;
+ scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
+ for (i = 0; i < size; i++) {
+ block[0] += lightmap[0] * scale;
+ block[1] += lightmap[1] * scale;
+ block[2] += lightmap[2] * scale;
+
+ lightmap += LIGHTMAP_BYTES;
+ block += LIGHTMAP_BYTES;
}
}
@@ -340,7 +336,45 @@ void R_BuildLightMap(void)
R_AddDynamicLights();
// bound
- for (i = 0; i < size * LIGHTMAP_BYTES; i++)
- clamp(blocklights[i], 255, 65535);
+ block = blocklights;
+ for (i = 0; i < size; i++) {
+ blocklight_t r, g, b, max;
+
+ r = block[0];
+ g = block[1];
+ b = block[2];
+
+ // catch negative lights
+ if (r < 255)
+ r = 255;
+ if (g < 255)
+ g = 255;
+ if (b < 255)
+ b = 255;
+
+ // determine the brightest of the three color components
+ max = g;
+ if (r > max)
+ max = r;
+ if (b > max)
+ max = b;
+
+ // rescale all the color components if the intensity of the greatest
+ // channel exceeds 1.0
+ if (max > 65535) {
+ float y;
+
+ y = 65535.0f / max;
+ r *= y;
+ g *= y;
+ b *= y;
+ }
+
+ block[0] = r;
+ block[1] = g;
+ block[2] = b;
+
+ block += LIGHTMAP_BYTES;
+ }
}
diff --git a/src/refresh/sw/main.c b/src/refresh/sw/main.c
index ea166e3..561721a 100644
--- a/src/refresh/sw/main.c
+++ b/src/refresh/sw/main.c
@@ -705,7 +705,7 @@ static void R_DrawBEntitiesOnList(void)
R_RotateBmodel();
// calculate dynamic lighting for bmodel
- R_PushDlights(model->headnode);
+ R_MarkLights(model->headnode);
if (topnode->plane) {
// not a leaf; has to be clipped to the world BSP
@@ -839,7 +839,7 @@ void R_RenderFrame(refdef_t *fd)
R_MarkLeaves(); // done here so we know if we're in water
if (r_worldmodel)
- R_PushDlights(r_worldmodel->nodes);
+ R_MarkLights(r_worldmodel->nodes);
R_EdgeDrawing();
diff --git a/src/refresh/sw/surf.c b/src/refresh/sw/surf.c
index a9200ec..653c28a 100644
--- a/src/refresh/sw/surf.c
+++ b/src/refresh/sw/surf.c
@@ -336,10 +336,10 @@ surfcache_t *D_CacheSurface(mface_t *surface, int miplevel)
// if the surface is animating or flashing, flush the cache
//
r_drawsurf.image = R_TextureAnimation(surface->texinfo);
- r_drawsurf.lightadj[0] = r_newrefdef.lightstyles[surface->styles[0]].white * 256;
- r_drawsurf.lightadj[1] = r_newrefdef.lightstyles[surface->styles[1]].white * 256;
- r_drawsurf.lightadj[2] = r_newrefdef.lightstyles[surface->styles[2]].white * 256;
- r_drawsurf.lightadj[3] = r_newrefdef.lightstyles[surface->styles[3]].white * 256;
+ r_drawsurf.lightadj[0] = r_newrefdef.lightstyles[surface->styles[0]].white * sw_modulate->value * 256;
+ r_drawsurf.lightadj[1] = r_newrefdef.lightstyles[surface->styles[1]].white * sw_modulate->value * 256;
+ r_drawsurf.lightadj[2] = r_newrefdef.lightstyles[surface->styles[2]].white * sw_modulate->value * 256;
+ r_drawsurf.lightadj[3] = r_newrefdef.lightstyles[surface->styles[3]].white * sw_modulate->value * 256;
//
// see if the cache holds apropriate data
diff --git a/src/refresh/sw/sw.h b/src/refresh/sw/sw.h
index c684794..52ac965 100644
--- a/src/refresh/sw/sw.h
+++ b/src/refresh/sw/sw.h
@@ -444,6 +444,7 @@ extern model_t *currentmodel;
extern entity_t *currententity;
extern vec3_t modelorg;
extern vec3_t r_entorigin;
+extern vec3_t entity_rotation[3];
extern float verticalFieldOfView;
extern float xOrigin, yOrigin;
@@ -475,7 +476,7 @@ void R_DrawSolidClippedSubmodelPolygons(mmodel_t *pmodel, mnode_t *topnode);
void R_AliasDrawModel(void);
void R_BeginEdgeFrame(void);
void R_ScanEdges(void);
-void R_PushDlights(mnode_t *headnode);
+void R_MarkLights(mnode_t *headnode);
void R_RotateBmodel(void);