Merge pull request #804 from 0lvin/softcolorlight

WIP: Add color light to soft render
This commit is contained in:
Yamagi 2022-04-03 17:43:38 +02:00 committed by GitHub
commit d827636c73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 631 additions and 397 deletions

View file

@ -424,6 +424,7 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
custom gun field of view is used. Defaults to `8`, which is more or
less optimal for the default gun field of view of 80.
* **sw_colorlight**: enable experimental color lighting.
## cvar operations

View file

@ -77,6 +77,7 @@ typedef unsigned char pixel_t;
typedef int shift20_t;
typedef int zvalue_t;
typedef unsigned int light_t;
typedef int light3_t[3];
// xyz-prescale to 16.16 fixed-point
#define SHIFT16XYZ 16
@ -92,10 +93,15 @@ typedef enum
rserr_unknown
} rserr_t;
/* 64 light grades available */
#define LIGHTMASK 0x3F00
extern viddef_t vid;
extern pixel_t *vid_buffer; // invisible buffer
extern pixel_t *vid_colormap; // 256 * VID_GRADES size
extern pixel_t *vid_alphamap; // 256 * 256 translucency map
extern byte *vid_lightmap; // 64 light grades for 256 colors
extern light_t vid_lightthreshold; // full light distance maximum
extern char shift_size; // shift size in fixed-point
typedef struct
@ -200,15 +206,18 @@ typedef struct
** if you change this structure be sure to change the #defines
** listed after it!
*/
typedef struct finalvert_s {
typedef struct compactvert_s {
int u, v, s, t;
int l;
light3_t l; // full color light
zvalue_t zi;
} compactvert_t;
typedef struct finalvert_s {
compactvert_t cv; // reuse compacted type
int flags;
float xyz[3]; // eye space
} finalvert_t;
typedef struct
{
pixel_t *pskin;
@ -228,12 +237,6 @@ typedef struct
int surfheight; // in mipmapped texels
} drawsurf_t;
typedef struct {
int ambientlight;
int shadelight;
float *plightvec;
} alight_t;
// clipped bmodel edges
typedef struct bedge_s
{
@ -432,6 +435,7 @@ extern cvar_t *r_lefthand;
extern cvar_t *r_gunfov;
extern cvar_t *r_farsee;
extern cvar_t *r_lightmap;
extern cvar_t *r_colorlight;
extern cvar_t *r_drawworld;
extern cvar_t *r_lerpmodels;
extern cvar_t *r_lightlevel;
@ -502,7 +506,8 @@ extern edge_t **removeedges;
typedef struct {
int u, v, count;
pixel_t *ptex;
int sfrac, tfrac, light;
int sfrac, tfrac;
light3_t light;
zvalue_t zi;
} spanpackage_t;
extern spanpackage_t *triangle_spans, *triangles_max;
@ -583,12 +588,14 @@ void RE_Draw_FadeScreen (void);
void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
extern byte d_8to24table[256 * 4];
void R_InitImages(void);
void R_ShutdownImages(void);
image_t *R_FindImage(char *name, imagetype_t type);
byte *Get_BestImageSize(const image_t *image, int *req_width, int *req_height);
void R_FreeUnusedImages(void);
qboolean R_ImageHasFreeSpace(void);
pixel_t R_ApplyLight(pixel_t pix, const light3_t light);
void R_InitSkyBox(model_t *loadmodel);
void R_IMFlatShadedQuad( const vec3_t a, const vec3_t b, const vec3_t c, const vec3_t d, int color, float alpha );

View file

@ -95,7 +95,7 @@ typedef struct msurface_s
// lighting info
byte styles[MAXLIGHTMAPS];
byte *samples; // [numstyles*surfsize]
byte *samples; // [numstyles*surfsize*3]
struct msurface_s *nextalphasurface;
} msurface_t;

View file

@ -34,6 +34,7 @@ static void
R_Alias_clip_z (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out)
{
float scale;
int i;
scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
(pfv1->xyz[2] - pfv0->xyz[2]);
@ -42,39 +43,49 @@ R_Alias_clip_z (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *o
out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
out->xyz[2] = ALIAS_Z_CLIP_PLANE;
out->s = pfv0->s + (pfv1->s - pfv0->s) * scale;
out->t = pfv0->t + (pfv1->t - pfv0->t) * scale;
out->l = pfv0->l + (pfv1->l - pfv0->l) * scale;
out->cv.s = pfv0->cv.s + (pfv1->cv.s - pfv0->cv.s) * scale;
out->cv.t = pfv0->cv.t + (pfv1->cv.t - pfv0->cv.t) * scale;
for(i=0; i<3; i++)
out->cv.l[i] = pfv0->cv.l[i] + (pfv1->cv.l[i] - pfv0->cv.l[i]) * scale;
R_AliasProjectAndClipTestFinalVert (out);
}
static void
R_Alias_clip_scale (const finalvert_t *pfv0, const finalvert_t *pfv1, float scale, finalvert_t *out)
{
int i;
out->cv.u = pfv1->cv.u + ( pfv0->cv.u - pfv1->cv.u ) * scale + 0.5;
out->cv.v = pfv1->cv.v + ( pfv0->cv.v - pfv1->cv.v ) * scale + 0.5;
out->cv.s = pfv1->cv.s + ( pfv0->cv.s - pfv1->cv.s ) * scale + 0.5;
out->cv.t = pfv1->cv.t + ( pfv0->cv.t - pfv1->cv.t ) * scale + 0.5;
for(i=0; i<3; i++)
out->cv.l[i] = pfv1->cv.l[i] + ( pfv0->cv.l[i] - pfv1->cv.l[i] ) * scale + 0.5;
out->cv.zi = pfv1->cv.zi + ( pfv0->cv.zi - pfv1->cv.zi) * scale + 0.5;
}
static void
R_Alias_clip_left (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out)
{
float scale;
if (pfv0->v >= pfv1->v )
if (pfv0->cv.v >= pfv1->cv.v )
{
scale = (float)(r_refdef.aliasvrect.x - pfv0->u) /
(pfv1->u - pfv0->u);
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrect.x - pfv0->cv.u) /
(pfv1->cv.u - pfv0->cv.u);
R_Alias_clip_scale (pfv1, pfv0, scale, out);
}
else
{
scale = (float)(r_refdef.aliasvrect.x - pfv1->u) /
(pfv0->u - pfv1->u);
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrect.x - pfv1->cv.u) /
(pfv0->cv.u - pfv1->cv.u);
R_Alias_clip_scale (pfv0, pfv1, scale, out);
}
}
@ -83,27 +94,19 @@ R_Alias_clip_right (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_
{
float scale;
if ( pfv0->v >= pfv1->v )
if ( pfv0->cv.v >= pfv1->cv.v )
{
scale = (float)(r_refdef.aliasvrectright - pfv0->u ) /
(pfv1->u - pfv0->u );
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrectright - pfv0->cv.u ) /
(pfv1->cv.u - pfv0->cv.u );
R_Alias_clip_scale (pfv1, pfv0, scale, out);
}
else
{
scale = (float)(r_refdef.aliasvrectright - pfv1->u ) /
(pfv0->u - pfv1->u );
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrectright - pfv1->cv.u ) /
(pfv0->cv.u - pfv1->cv.u );
R_Alias_clip_scale (pfv0, pfv1, scale, out);
}
}
@ -112,27 +115,19 @@ R_Alias_clip_top (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t
{
float scale;
if (pfv0->v >= pfv1->v)
if (pfv0->cv.v >= pfv1->cv.v)
{
scale = (float)(r_refdef.aliasvrect.y - pfv0->v) /
(pfv1->v - pfv0->v);
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrect.y - pfv0->cv.v) /
(pfv1->cv.v - pfv0->cv.v);
R_Alias_clip_scale (pfv1, pfv0, scale, out);
}
else
{
scale = (float)(r_refdef.aliasvrect.y - pfv1->v) /
(pfv0->v - pfv1->v);
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
scale = (float)(r_refdef.aliasvrect.y - pfv1->cv.v) /
(pfv0->cv.v - pfv1->cv.v);
R_Alias_clip_scale (pfv0, pfv1, scale, out);
}
}
@ -142,29 +137,19 @@ R_Alias_clip_bottom (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert
{
float scale;
if (pfv0->v >= pfv1->v)
if (pfv0->cv.v >= pfv1->cv.v)
{
scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) /
(pfv1->v - pfv0->v);
scale = (float)(r_refdef.aliasvrectbottom - pfv0->cv.v) /
(pfv1->cv.v - pfv0->cv.v);
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
R_Alias_clip_scale (pfv1, pfv0, scale, out);
}
else
{
scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) /
(pfv0->v - pfv1->v);
scale = (float)(r_refdef.aliasvrectbottom - pfv1->cv.v) /
(pfv0->cv.v - pfv1->cv.v);
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
R_Alias_clip_scale (pfv0, pfv1, scale, out);
}
}
@ -193,13 +178,13 @@ R_AliasClip (const finalvert_t *in, finalvert_t *out, int flag, int count,
{
clip (&in[j], &in[i], &out[k]);
out[k].flags = 0;
if (out[k].u < r_refdef.aliasvrect.x)
if (out[k].cv.u < r_refdef.aliasvrect.x)
out[k].flags |= ALIAS_LEFT_CLIP;
if (out[k].v < r_refdef.aliasvrect.y)
if (out[k].cv.v < r_refdef.aliasvrect.y)
out[k].flags |= ALIAS_TOP_CLIP;
if (out[k].u > r_refdef.aliasvrectright)
if (out[k].cv.u > r_refdef.aliasvrectright)
out[k].flags |= ALIAS_RIGHT_CLIP;
if (out[k].v > r_refdef.aliasvrectbottom)
if (out[k].cv.v > r_refdef.aliasvrectbottom)
out[k].flags |= ALIAS_BOTTOM_CLIP;
k++;
}
@ -292,15 +277,15 @@ R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index0, co
for (i=0 ; i<k ; i++)
{
if (fv[pingpong][i].u < r_refdef.aliasvrect.x)
fv[pingpong][i].u = r_refdef.aliasvrect.x;
else if (fv[pingpong][i].u > r_refdef.aliasvrectright)
fv[pingpong][i].u = r_refdef.aliasvrectright;
if (fv[pingpong][i].cv.u < r_refdef.aliasvrect.x)
fv[pingpong][i].cv.u = r_refdef.aliasvrect.x;
else if (fv[pingpong][i].cv.u > r_refdef.aliasvrectright)
fv[pingpong][i].cv.u = r_refdef.aliasvrectright;
if (fv[pingpong][i].v < r_refdef.aliasvrect.y)
fv[pingpong][i].v = r_refdef.aliasvrect.y;
else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom)
fv[pingpong][i].v = r_refdef.aliasvrectbottom;
if (fv[pingpong][i].cv.v < r_refdef.aliasvrect.y)
fv[pingpong][i].cv.v = r_refdef.aliasvrect.y;
else if (fv[pingpong][i].cv.v > r_refdef.aliasvrectbottom)
fv[pingpong][i].cv.v = r_refdef.aliasvrectbottom;
fv[pingpong][i].flags = 0;
}

View file

@ -35,9 +35,9 @@ affinetridesc_t r_affinetridesc;
static vec3_t r_plightvec;
static vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move;
static int r_ambientlight;
static light3_t r_ambientlight;
int r_aliasblendcolor;
static float r_shadelight;
static vec3_t r_shadelight;
static daliasframe_t *r_thisframe, *r_lastframe;
@ -257,14 +257,14 @@ R_AliasPreparePoints (const entity_t *currententity, finalvert_t *verts, const f
continue; // completely clipped
// insert s/t coordinates
pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
{
@ -289,14 +289,14 @@ R_AliasPreparePoints (const entity_t *currententity, finalvert_t *verts, const f
continue; // completely clipped
// insert s/t coordinates
pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
{
@ -399,7 +399,6 @@ R_AliasTransformFinalVerts(const entity_t *currententity, int numpoints, finalve
for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ )
{
int temp;
float lightcos;
const float *plightnormal;
vec3_t lerped_vert;
@ -426,19 +425,29 @@ R_AliasTransformFinalVerts(const entity_t *currententity, int numpoints, finalve
// lighting
lightcos = DotProduct (plightnormal, r_plightvec);
temp = r_ambientlight;
if (lightcos < 0)
{
temp += (int)(r_shadelight * lightcos);
int j;
for(j=0; j<3; j++)
{
int temp;
temp = r_ambientlight[j];
temp += (r_shadelight[j] * lightcos);
// clamp; because we limited the minimum ambient and shading light, we
// don't have to clamp low light, just bright
if (temp < 0)
temp = 0;
}
fv->l = temp;
fv->cv.l[j] = temp;
}
}
else
memcpy(fv->cv.l, r_ambientlight, sizeof(light3_t));
if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE )
{
@ -469,18 +478,18 @@ R_AliasProjectAndClipTestFinalVert( finalvert_t *fv )
z = fv->xyz[2];
zi = 1.0 / z;
fv->zi = zi * s_ziscale;
fv->cv.zi = zi * s_ziscale;
fv->u = (x * aliasxscale * zi) + aliasxcenter;
fv->v = (y * aliasyscale * zi) + aliasycenter;
fv->cv.u = (x * aliasxscale * zi) + aliasxcenter;
fv->cv.v = (y * aliasyscale * zi) + aliasycenter;
if (fv->u < r_refdef.aliasvrect.x)
if (fv->cv.u < r_refdef.aliasvrect.x)
fv->flags |= ALIAS_LEFT_CLIP;
if (fv->v < r_refdef.aliasvrect.y)
if (fv->cv.v < r_refdef.aliasvrect.y)
fv->flags |= ALIAS_TOP_CLIP;
if (fv->u > r_refdef.aliasvrectright)
if (fv->cv.u > r_refdef.aliasvrectright)
fv->flags |= ALIAS_RIGHT_CLIP;
if (fv->v > r_refdef.aliasvrectbottom)
if (fv->cv.v > r_refdef.aliasvrectbottom)
fv->flags |= ALIAS_BOTTOM_CLIP;
}
@ -534,10 +543,9 @@ R_AliasSetupLighting
static void
R_AliasSetupLighting(entity_t *currententity)
{
alight_t lighting;
float lightvec[3] = {-1, 0, 0};
const vec3_t lightvec = {-1, 0, 0};
vec3_t light;
int i, j;
int i;
// all components of light should be identical in software
if ( currententity->flags & RF_FULLBRIGHT )
@ -578,39 +586,45 @@ R_AliasSetupLighting(entity_t *currententity)
}
}
j = (light[0] + light[1] + light[2]) * 0.3333 * 255;
if(r_colorlight->value < 2)
{
float temp = (light[0] + light[1] + light[2]) / 3.0;
lighting.ambientlight = j;
lighting.shadelight = j;
light[0] = light[1] = light[2] = temp;
}
lighting.plightvec = lightvec;
for(i=0; i<3; i++)
{
int j;
j = light[i] * 255;
r_ambientlight[i] = j;
r_shadelight[i] = j;
// clamp lighting so it doesn't overbright as much
if (lighting.ambientlight > 128)
lighting.ambientlight = 128;
if (lighting.ambientlight + lighting.shadelight > 192)
lighting.shadelight = 192 - lighting.ambientlight;
if (r_ambientlight[i] > 128)
r_ambientlight[i] = 128;
if (r_ambientlight[i] + r_shadelight[i] > 192)
r_shadelight[i] = 192 - r_ambientlight[i];
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
// to clamp off the bottom
r_ambientlight = lighting.ambientlight;
if (r_ambientlight[i] < LIGHT_MIN)
r_ambientlight[i] = LIGHT_MIN;
if (r_ambientlight < LIGHT_MIN)
r_ambientlight = LIGHT_MIN;
r_ambientlight[i] = (255 - r_ambientlight[i]) << VID_CBITS;
r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
if (r_shadelight[i] < 0)
r_shadelight[i] = 0;
r_shadelight = lighting.shadelight;
if (r_shadelight < 0)
r_shadelight = 0;
r_shadelight *= VID_GRADES;
r_shadelight[i] *= VID_GRADES;
}
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct( lighting.plightvec, s_alias_forward );
r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right );
r_plightvec[2] = DotProduct( lighting.plightvec, s_alias_up );
r_plightvec[0] = DotProduct( lightvec, s_alias_forward );
r_plightvec[1] = -DotProduct( lightvec, s_alias_right );
r_plightvec[2] = DotProduct( lightvec, s_alias_up );
}

View file

@ -215,11 +215,12 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real
size_t data_size, imagetype_t type)
{
image_t *image;
size_t i, size, full_size;
size_t size, full_size;
size = width * height;
if (!pic || data_size <= 0 || width <= 0 || height <= 0 || size <= 0)
/* data_size/size are unsigned */
if (!pic || data_size == 0 || width <= 0 || height <= 0 || size == 0)
return NULL;
image = R_FindFreeImage();
@ -246,6 +247,8 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real
image->transparent = false;
if (type != it_wall)
{
size_t i;
for (i=0 ; i<size ; i++)
{
if (pic[i] == 255)
@ -305,7 +308,8 @@ R_LoadWal (char *name, imagetype_t type)
height = LittleLong (mt->height);
ofs = LittleLong(mt->offsets[0]);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
/* width/height are unsigned */
if ((ofs <= 0) || (width == 0) || (height == 0) ||
((file_size - ofs) / width < height))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name);
@ -323,7 +327,54 @@ R_LoadWal (char *name, imagetype_t type)
return image;
}
static unsigned char *d_16to8table = NULL; // 16 to 8 bit conversion table
static byte *d_16to8table = NULL; // 16 to 8 bit conversion table
/*
* Apply color light to texture pixel
*
* TODO: -22% fps lost
*/
pixel_t
R_ApplyLight(pixel_t pix, const light3_t light)
{
byte b_r, b_g, b_b;
int i_c;
light3_t light_masked;
light_masked[0] = light[0] & LIGHTMASK;
light_masked[1] = light[1] & LIGHTMASK;
light_masked[2] = light[2] & LIGHTMASK;
/* same light or colorlight == 0 */
if (light_masked[0] == light_masked[1] && light_masked[0] == light_masked[2])
return vid_colormap[pix + light_masked[0]];
/* full light, code could skip light processing */
if ((light_masked[0] | light_masked[1] | light_masked[2]) <= vid_lightthreshold)
return pix;
/* get color component for each component */
b_r = d_8to24table[pix * 4 + 0];
b_g = d_8to24table[pix * 4 + 1];
b_b = d_8to24table[pix * 4 + 2];
/* scale by light */
b_r = vid_lightmap[light_masked[0] + b_r];
b_g = vid_lightmap[light_masked[1] + b_g];
b_b = vid_lightmap[light_masked[2] + b_b];
/*
* convert back to indexed color (value reshifted >> 2)
* look to R_Convert32To8bit
*/
b_r = ( b_r >> 1 ); // & 31;
b_g = ( b_g >> 0 ); // & 63;
b_b = ( b_b >> 1 ); // & 31;
i_c = b_r | ( b_g << 5 ) | ( b_b << 11 );
return d_16to8table[i_c & 0xFFFF];
}
static void
R_Convert32To8bit(const unsigned char* pic_in, pixel_t* pic_out, size_t size)
@ -677,7 +728,7 @@ R_FindImage(char *name, imagetype_t type)
}
/* just return white image if show lighmap only */
if (type == it_wall && r_lightmap->value)
if ((type == it_wall || type == it_skin) && r_lightmap->value)
{
return r_whitetexture_mip;
}

View file

@ -57,6 +57,7 @@ R_MarkLights (dlight_t *light, int bit, mnode_t *node, int r_dlightframecount)
R_MarkLights (light, bit, node->children[0], r_dlightframecount);
return;
}
if (dist < -i) // (dist < -light->intensity)
{
R_MarkLights (light, bit, node->children[1], r_dlightframecount);
@ -107,12 +108,8 @@ LIGHT SAMPLING
=============================================================================
*/
static vec3_t pointcolor;
static vec3_t lightspot;
static int
RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end, vec3_t pointcolor)
{
float front, back, frac;
qboolean side;
@ -122,10 +119,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
int s, t, ds, dt;
int i;
mtexinfo_t *tex;
byte *lightmap;
float *scales;
int maps;
float samp;
int r;
if (node->contents != -1)
@ -140,7 +134,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
side = front < 0;
if ( (back < 0) == side)
return RecursiveLightPoint (node->children[side], start, end);
return RecursiveLightPoint (node->children[side], start, end, pointcolor);
frac = front / (front-back);
mid[0] = start[0] + (end[0] - start[0])*frac;
@ -150,16 +144,16 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
mid[plane->type] = plane->dist;
// go down front side
r = RecursiveLightPoint (node->children[side], start, mid);
r = RecursiveLightPoint (node->children[side], start, mid, pointcolor);
if (r >= 0)
return r; // hit something
// check for impact on this node
VectorCopy (mid, lightspot);
surf = r_worldmodel->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++)
{
byte *lightmap;
if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY))
continue; // no lightmaps
@ -185,15 +179,27 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
lightmap = surf->samples;
VectorCopy (vec3_origin, pointcolor);
lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
lightmap += 3 * (dt * ((surf->extents[0] >> 4) + 1) + ds);
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
samp = *lightmap * r_modulate->value * (1.0/255); // adjust for gl scale
scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
VectorMA (pointcolor, samp, scales, pointcolor);
lightmap += ((surf->extents[0]>>4)+1) *
const float *rgb;
int j;
rgb = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
/* Apply light level to models */
for (j = 0; j < 3; j++)
{
float scale;
scale = rgb[j] * r_modulate->value;
pointcolor[j] += lightmap[j] * scale * (1.0 / 255);
}
lightmap += 3 * ((surf->extents[0] >> 4) + 1) *
((surf->extents[1] >> 4) + 1);
}
@ -201,7 +207,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
}
// go down back side
return RecursiveLightPoint (node->children[!side], mid, end);
return RecursiveLightPoint (node->children[!side], mid, end, pointcolor);
}
/*
@ -217,6 +223,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color)
int lnum;
dlight_t *dl;
vec3_t dist;
vec3_t pointcolor;
if (!r_worldmodel->lightdata)
{
@ -228,7 +235,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color)
end[1] = p[1];
end[2] = p[2] - 2048;
r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
r = RecursiveLightPoint (r_worldmodel->nodes, p, end, pointcolor);
if (r == -1)
{
@ -274,22 +281,15 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
{
msurface_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;
surf = drawsurf->surf;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
tex = surf->texinfo;
if (blocklight_max <= blocklights + smax*tmax)
if (blocklight_max <= blocklights + smax*tmax*3)
{
r_outoflights = true;
return;
@ -297,13 +297,31 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
for (lnum=0; lnum < r_newrefdef.num_dlights; lnum++)
{
vec3_t impact, local, color;
float dist, rad, minlight;
int t;
int i;
dlight_t *dl;
int negativeLight;
light_t *plightdest = blocklights;
if (!(surf->dlightbits & (1<<lnum)))
continue; // not lit by this light
dl = &r_newrefdef.dlights[lnum];
rad = dl->intensity;
if(r_colorlight->value == 0)
{
for(i=0; i<3; i++)
color[i] = 256;
}
else
{
for(i=0; i<3; i++)
color[i] = 256 * dl->color[i];
}
//=====
negativeLight = 0;
if(rad < 0)
@ -335,11 +353,15 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
for (t = 0 ; t<tmax ; t++)
{
int s, td;
td = local[1] - t*16;
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
int sd;
sd = local[0] - s*16;
if (sd < 0)
sd = -sd;
@ -348,16 +370,19 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
else
dist = td + (sd>>1);
for (i=0; i<3; i++)
{
//====
if(!negativeLight)
{
if (dist < minlight)
*plightdest += (rad - dist)*256;
*plightdest += (rad - dist) * color[i];
}
else
{
if (dist < minlight)
*plightdest -= (rad - dist)*256;
*plightdest -= (rad - dist) * color[i];
if(*plightdest < minlight)
*plightdest = minlight;
}
@ -367,6 +392,7 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
}
}
}
}
/*
===============
@ -379,7 +405,7 @@ void
R_BuildLightMap (drawsurf_t* drawsurf)
{
int smax, tmax;
int i, size;
int size;
byte *lightmap;
msurface_t *surf;
@ -387,22 +413,22 @@ R_BuildLightMap (drawsurf_t* drawsurf)
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
size = smax*tmax;
size = smax*tmax*3;
if (blocklight_max <= blocklights + size)
{
r_outoflights = true;
return;
}
if (r_fullbright->value || !r_worldmodel->lightdata)
{
memset(blocklights, 0, size * sizeof(light_t));
return;
}
// clear to no light
memset(blocklights, 0, size * sizeof(light_t));
if (r_fullbright->value || !r_worldmodel->lightdata)
{
return;
}
// add all the lightmaps
lightmap = surf->samples;
if (lightmap)
@ -413,11 +439,48 @@ R_BuildLightMap (drawsurf_t* drawsurf)
maps++)
{
unsigned scale;
light_t *curr_light, *max_light;
curr_light = blocklights;
max_light = blocklights + size;
scale = drawsurf->lightadj[maps]; // 8.8 fraction
for (i=0 ; i<size ; i++)
blocklights[i] += lightmap[i] * scale;
lightmap += size; // skip to next lightmap
if(r_colorlight->value == 0)
{
do
{
light_t light;
light = lightmap[0];
if (light < lightmap[1])
light = lightmap[1];
if (light < lightmap[2])
light = lightmap[2];
light *= scale;
*curr_light += light;
curr_light++;
*curr_light += light;
curr_light++;
*curr_light += light;
curr_light++;
lightmap += 3; /* skip to next lightmap */
}
while(curr_light < max_light);
}
else
{
do
{
*curr_light += *lightmap * scale;
curr_light++;
lightmap ++; /* skip to next lightmap */
}
while(curr_light < max_light);
}
}
}
@ -426,11 +489,18 @@ R_BuildLightMap (drawsurf_t* drawsurf)
R_AddDynamicLights (drawsurf);
// bound, invert, and shift
for (i=0 ; i<size ; i++)
{
light_t *curr_light, *max_light;
curr_light = blocklights;
max_light = blocklights + size;
do
{
int t;
t = (int)blocklights[i];
t = (int)*curr_light;
if (t < 0)
t = 0;
t = (255*256 - t) >> (8 - VID_CBITS);
@ -438,6 +508,9 @@ R_BuildLightMap (drawsurf_t* drawsurf)
if (t < (1 << 6))
t = (1 << 6);
blocklights[i] = t;
*curr_light = t;
curr_light++;
}
while(curr_light < max_light);
}
}

View file

@ -40,6 +40,8 @@ static int swap_current = 0;
espan_t *vid_polygon_spans = NULL;
pixel_t *vid_colormap = NULL;
pixel_t *vid_alphamap = NULL;
byte *vid_lightmap = NULL;
light_t vid_lightthreshold = 0;
static int vid_minu, vid_minv, vid_maxu, vid_maxv;
static int vid_zminu, vid_zminv, vid_zmaxu, vid_zmaxv;
@ -51,7 +53,7 @@ static qboolean palette_changed;
refimport_t ri;
static unsigned d_8to24table[256];
byte d_8to24table[256 * 4];
char skyname[MAX_QPATH];
vec3_t skyaxis;
@ -135,6 +137,7 @@ cvar_t *r_lefthand;
cvar_t *r_gunfov;
cvar_t *r_farsee;
cvar_t *r_lightmap;
cvar_t *r_colorlight;
static cvar_t *sw_aliasstats;
cvar_t *sw_clearcolor;
cvar_t *sw_drawflat;
@ -396,6 +399,7 @@ R_RegisterVariables (void)
r_gunfov = ri.Cvar_Get( "r_gunfov", "80", CVAR_ARCHIVE );
r_farsee = ri.Cvar_Get("r_farsee", "0", CVAR_LATCH | CVAR_ARCHIVE);
r_lightmap = ri.Cvar_Get("r_lightmap", "0", 0);
r_colorlight = ri.Cvar_Get("sw_colorlight", "0", CVAR_ARCHIVE);
r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
@ -510,6 +514,14 @@ RE_Shutdown (void)
free (vid_colormap);
vid_colormap = NULL;
}
/* free lightmap */
if (vid_lightmap)
{
free (vid_lightmap);
vid_lightmap = NULL;
}
R_UnRegister ();
Mod_FreeAll ();
R_ShutdownImages ();
@ -1230,7 +1242,7 @@ R_CalcPalette (void)
if (modified)
{ // set back to default
modified = false;
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
R_GammaCorrectAndSetPalette( d_8to24table );
return;
}
return;
@ -1246,7 +1258,7 @@ R_CalcPalette (void)
one_minus_alpha = (1.0 - alpha);
in = (byte *)d_8to24table;
in = d_8to24table;
out = palette[0];
for (i=0 ; i<256 ; i++, in+=4, out+=4)
{
@ -1439,7 +1451,7 @@ R_InitGraphics( int width, int height )
R_InitCaches();
R_GammaCorrectAndSetPalette((const unsigned char *)d_8to24table);
R_GammaCorrectAndSetPalette(d_8to24table);
}
static rserr_t SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen);
@ -1466,7 +1478,7 @@ RE_BeginFrame( float camera_separation )
if ( vid_gamma->modified || sw_overbrightbits->modified )
{
Draw_BuildGammaTable();
R_GammaCorrectAndSetPalette((const unsigned char * )d_8to24table);
R_GammaCorrectAndSetPalette(d_8to24table);
// we need redraw everything
VID_WholeDamageBuffer();
// and backbuffer should be zeroed
@ -1602,7 +1614,7 @@ RE_SetPalette(const unsigned char *palette)
}
else
{
R_GammaCorrectAndSetPalette((const unsigned char *)d_8to24table);
R_GammaCorrectAndSetPalette(d_8to24table);
}
}
@ -1752,14 +1764,16 @@ Draw_GetPalette (void)
{
byte *pal, *out;
int i;
int white = 0;
// get the palette and colormap
/* get the palette and colormap */
LoadPCX ("pics/colormap.pcx", &vid_colormap, &pal, NULL, NULL);
if (!vid_colormap)
ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
vid_alphamap = vid_colormap + 64*256;
out = (byte *)d_8to24table;
out = d_8to24table;
for (i=0 ; i<256 ; i++, out+=4)
{
int r, g, b;
@ -1771,9 +1785,34 @@ Draw_GetPalette (void)
out[0] = r;
out[1] = g;
out[2] = b;
if (r == 255 && g == 255 && b == 255)
white = i;
}
free (pal);
R_Printf(PRINT_ALL,"white color in palete: %d\n", white);
/* generate lightmap */
vid_lightmap = malloc(64 * 256 * sizeof(byte));
for (i=0; i < 64; i++)
{
int j, scale;
scale = (
d_8to24table[vid_colormap[i * 256 + white] * 4 + 0] +
d_8to24table[vid_colormap[i * 256 + white] * 4 + 1] +
d_8to24table[vid_colormap[i * 256 + white] * 4 + 2]
) / 3;
/* full light distance maximum */
if (scale == 255)
vid_lightthreshold = i * 256;
for(j=0; j < 256; j++)
vid_lightmap[i * 256 + j] = ((j * scale / 255) >> 2) & 63;
}
}
/*
@ -2409,7 +2448,7 @@ SWimp_CreateRender(int width, int height)
memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette));
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
R_GammaCorrectAndSetPalette( d_8to24table );
}
// this is only here so the functions in q_shared.c and q_shwin.c can link

View file

@ -257,8 +257,7 @@ by taking the brightest component
static void
Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, size;
pixel_t *in;
int size;
if (!l->filelen)
{
@ -266,18 +265,9 @@ Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l)
return;
}
size = l->filelen/3;
size = l->filelen;
loadmodel->lightdata = Hunk_Alloc(size);
in = mod_base + l->fileofs;
for (i=0 ; i<size ; i++, in+=3)
{
if (in[0] > in[1] && in[0] > in[2])
loadmodel->lightdata[i] = in[0];
else if (in[1] > in[0] && in[1] > in[2])
loadmodel->lightdata[i] = in[1];
else
loadmodel->lightdata[i] = in[2];
}
memcpy(loadmodel->lightdata, mod_base + l->fileofs, size);
}
@ -665,9 +655,13 @@ Mod_LoadFaces (model_t *loadmodel, byte *mod_base, lump_t *l)
out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
{
out->samples = NULL;
}
else
out->samples = loadmodel->lightdata + i/3;
{
out->samples = loadmodel->lightdata + i;
}
// set the drawing flags flag
@ -1012,8 +1006,9 @@ Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen)
// lighting is a special case, because we keep only 1 byte out of 3
// (=> no colored lighting in soft renderer by default)
{
int size = header->lumps[LUMP_LIGHTING].filelen/3;
int size = header->lumps[LUMP_LIGHTING].filelen;
size = (size + 31) & ~31;
/* save color data */
hunkSize += size;
}

View file

@ -26,41 +26,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
typedef struct {
int isflattop;
int numleftedges;
int *pleftedgevert0;
int *pleftedgevert1;
int *pleftedgevert2;
compactvert_t *pleftedgevert0;
compactvert_t *pleftedgevert1;
compactvert_t *pleftedgevert2;
int numrightedges;
int *prightedgevert0;
int *prightedgevert1;
int *prightedgevert2;
compactvert_t *prightedgevert0;
compactvert_t *prightedgevert1;
compactvert_t *prightedgevert2;
} edgetable;
static int ubasestep, errorterm, erroradjustup, erroradjustdown;
static int r_p0[6], r_p1[6], r_p2[6];
static compactvert_t r_p0, r_p1, r_p2;
static int d_xdenom;
static edgetable *pedgetable;
static edgetable edgetables[12] = {
{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2},
{0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},
{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0},
{0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},
{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1},
{0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},
{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
{0, 1, &r_p0, &r_p2, NULL, 2, &r_p0, &r_p1, &r_p2},
{0, 2, &r_p1, &r_p0, &r_p2, 1, &r_p1, &r_p2, NULL},
{1, 1, &r_p0, &r_p2, NULL, 1, &r_p1, &r_p2, NULL},
{0, 1, &r_p1, &r_p0, NULL, 2, &r_p1, &r_p2, &r_p0},
{0, 2, &r_p0, &r_p2, &r_p1, 1, &r_p0, &r_p1, NULL},
{0, 1, &r_p2, &r_p1, NULL, 1, &r_p2, &r_p0, NULL},
{0, 1, &r_p2, &r_p1, NULL, 2, &r_p2, &r_p0, &r_p1},
{0, 2, &r_p2, &r_p1, &r_p0, 1, &r_p2, &r_p0, NULL},
{0, 1, &r_p1, &r_p0, NULL, 1, &r_p1, &r_p2, NULL},
{1, 1, &r_p2, &r_p1, NULL, 1, &r_p0, &r_p1, NULL},
{1, 1, &r_p1, &r_p0, NULL, 1, &r_p2, &r_p0, NULL},
{0, 1, &r_p0, &r_p2, NULL, 1, &r_p0, &r_p1, NULL},
};
// FIXME: some of these can become statics
static int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
static int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
static int a_sstepxfrac, a_tstepxfrac, a_ststepxwhole;
static int r_sstepx, r_tstepx, r_sstepy, r_tstepy;
static light3_t r_lstepx, r_lstepy;
static zvalue_t r_zistepx, r_zistepy;
static int d_aspancount;
@ -68,11 +69,12 @@ static spanpackage_t *d_pedgespanpackage;
spanpackage_t *triangle_spans, *triangles_max;
static int d_sfrac, d_tfrac, d_light;
static int d_sfrac, d_tfrac;
static light3_t d_light;
static zvalue_t d_zi;
static int d_ptexextrastep, d_sfracextrastep;
static int d_tfracextrastep, d_lightextrastep;
static int d_lightbasestep, d_ptexbasestep;
static int d_tfracextrastep, d_ptexbasestep;
static light3_t d_lightbasestep, d_lightextrastep;
static int d_sfracbasestep, d_tfracbasestep;
static zvalue_t d_ziextrastep, d_zibasestep;
@ -169,14 +171,14 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv
( a->v[0] - b->v[0] ) * ( a->v[1] - c->v[1] );
*/
dv0_ab = a->u - b->u;
dv1_ab = a->v - b->v;
dv0_ab = a->cv.u - b->cv.u;
dv1_ab = a->cv.v - b->cv.v;
if ( !( dv0_ab | dv1_ab ) )
return;
dv0_ac = a->u - c->u;
dv1_ac = a->v - c->v;
dv0_ac = a->cv.u - c->cv.u;
dv1_ac = a->cv.v - c->cv.v;
if ( !( dv0_ac | dv1_ac ) )
return;
@ -185,26 +187,9 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv
if ( d_xdenom < 0 )
{
r_p0[0] = a->u; // u
r_p0[1] = a->v; // v
r_p0[2] = a->s; // s
r_p0[3] = a->t; // t
r_p0[4] = a->l; // light
r_p0[5] = a->zi; // iz
r_p1[0] = b->u;
r_p1[1] = b->v;
r_p1[2] = b->s;
r_p1[3] = b->t;
r_p1[4] = b->l;
r_p1[5] = b->zi;
r_p2[0] = c->u;
r_p2[1] = c->v;
r_p2[2] = c->s;
r_p2[3] = c->t;
r_p2[4] = c->l;
r_p2[5] = c->zi;
memcpy(&r_p0, &a->cv, sizeof(compactvert_t));
memcpy(&r_p1, &b->cv, sizeof(compactvert_t));
memcpy(&r_p2, &c->cv, sizeof(compactvert_t));
R_PolysetSetEdgeTable ();
R_RasterizeAliasPolySmooth(currententity);
@ -213,7 +198,7 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv
static void
R_PushEdgesSpan(int u, int v, int count,
pixel_t* d_ptex, int d_sfrac, int d_tfrac, int d_light, zvalue_t d_zi)
pixel_t* d_ptex, int d_sfrac, int d_tfrac, light3_t d_light, zvalue_t d_zi)
{
if (d_pedgespanpackage >= triangles_max)
{
@ -231,7 +216,7 @@ R_PushEdgesSpan(int u, int v, int count,
d_pedgespanpackage->tfrac = d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage->light = d_light;
memcpy(d_pedgespanpackage->light, d_light, sizeof(light3_t));
d_pedgespanpackage->zi = d_zi;
d_pedgespanpackage++;
@ -257,6 +242,8 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v)
errorterm += erroradjustup;
if (errorterm >= 0)
{
int i;
// addtional step for compensate error
u ++;
d_aspancount ++;
@ -272,12 +259,17 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v)
d_ptex += r_affinetridesc.skinwidth;
d_tfrac &= 0xFFFF;
}
d_light += d_lightextrastep;
for(i=0; i<3; i++)
d_light[i] += d_lightextrastep[i];
d_zi += d_ziextrastep;
errorterm -= erroradjustdown;
}
else
{
int i;
d_ptex += d_ptexbasestep;
d_sfrac += d_sfracbasestep;
d_ptex += d_sfrac >> SHIFT16XYZ;
@ -288,7 +280,10 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v)
d_ptex += r_affinetridesc.skinwidth;
d_tfrac &= 0xFFFF;
}
d_light += d_lightbasestep;
for(i=0; i<3; i++)
d_light[i] += d_lightbasestep[i];
d_zi += d_zibasestep;
}
} while (--height);
@ -371,11 +366,12 @@ R_PolysetCalcGradients (int skinwidth)
{
float xstepdenominv, ystepdenominv, t0, t1;
float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
int i;
p00_minus_p20 = r_p0[0] - r_p2[0];
p01_minus_p21 = r_p0[1] - r_p2[1];
p10_minus_p20 = r_p1[0] - r_p2[0];
p11_minus_p21 = r_p1[1] - r_p2[1];
p00_minus_p20 = r_p0.u - r_p2.u;
p01_minus_p21 = r_p0.v - r_p2.v;
p10_minus_p20 = r_p1.u - r_p2.u;
p11_minus_p21 = r_p1.v - r_p2.v;
xstepdenominv = 1.0 / (float)d_xdenom;
@ -384,29 +380,32 @@ R_PolysetCalcGradients (int skinwidth)
// ceil () for light so positive steps are exaggerated, negative steps
// diminished, pushing us away from underflow toward overflow. Underflow is
// very visible, overflow is very unlikely, because of ambient lighting
t0 = r_p0[4] - r_p2[4];
t1 = r_p1[4] - r_p2[4];
r_lstepx = (int)
for (i=0; i<3; i++)
{
t0 = r_p0.l[i] - r_p2.l[i];
t1 = r_p1.l[i] - r_p2.l[i];
r_lstepx[i] = (int)
ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
r_lstepy = (int)
r_lstepy[i] = (int)
ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
}
t0 = r_p0[2] - r_p2[2];
t1 = r_p1[2] - r_p2[2];
t0 = r_p0.s - r_p2.s;
t1 = r_p1.s - r_p2.s;
r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
ystepdenominv);
t0 = r_p0[3] - r_p2[3];
t1 = r_p1[3] - r_p2[3];
t0 = r_p0.t - r_p2.t;
t1 = r_p1.t - r_p2.t;
r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
ystepdenominv);
t0 = r_p0[5] - r_p2[5];
t1 = r_p1[5] - r_p2[5];
t0 = r_p0.zi - r_p2.zi;
t1 = r_p1.zi - r_p2.zi;
r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
@ -432,7 +431,7 @@ R_PolysetDrawSpans8_33(const entity_t *currententity, spanpackage_t *pspanpackag
pixel_t *lpdest;
pixel_t *lptex;
int lsfrac, ltfrac;
int llight;
light3_t llight;
zvalue_t lzi;
zvalue_t *lpz;
@ -461,21 +460,24 @@ R_PolysetDrawSpans8_33(const entity_t *currententity, spanpackage_t *pspanpackag
lptex = pspanpackage->ptex;
lsfrac = pspanpackage->sfrac;
ltfrac = pspanpackage->tfrac;
llight = pspanpackage->light;
memcpy(llight, pspanpackage->light, sizeof(light3_t));
lzi = pspanpackage->zi;
do
{
int i;
if ((lzi >> SHIFT16XYZ) >= *lpz)
{
int temp = vid_colormap[*lptex + ( llight & 0xFF00 )];
int temp = R_ApplyLight(*lptex, llight);
*lpdest = vid_alphamap[temp + *lpdest*256];
}
lpdest++;
lzi += r_zistepx;
lpz++;
llight += r_lstepx;
for(i=0; i<3; i++)
llight[i] += r_lstepx[i];
lptex += a_ststepxwhole;
lsfrac += a_sstepxfrac;
lptex += lsfrac >> SHIFT16XYZ;
@ -546,7 +548,7 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
pixel_t *lpdest;
pixel_t *lptex;
int lsfrac, ltfrac;
int llight;
light3_t llight;
zvalue_t lzi;
zvalue_t *lpz;
@ -576,14 +578,16 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
lptex = pspanpackage->ptex;
lsfrac = pspanpackage->sfrac;
ltfrac = pspanpackage->tfrac;
llight = pspanpackage->light;
memcpy(llight, pspanpackage->light, sizeof(light3_t));
lzi = pspanpackage->zi;
do
{
int i;
if ((lzi >> SHIFT16XYZ) >= *lpz)
{
int temp = vid_colormap[*lptex + ( llight & 0xFF00 )];
int temp = R_ApplyLight(*lptex, llight);
*lpdest = vid_alphamap[temp*256 + *lpdest];
*lpz = lzi >> SHIFT16XYZ;
@ -592,7 +596,8 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag
lpdest++;
lzi += r_zistepx;
lpz++;
llight += r_lstepx;
for(i=0; i<3; i++)
llight[i] += r_lstepx[i];
lptex += a_ststepxwhole;
lsfrac += a_sstepxfrac;
lptex += lsfrac >> SHIFT16XYZ;
@ -700,7 +705,7 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp
int lsfrac, ltfrac;
pixel_t *lpdest;
pixel_t *lptex;
int llight;
light3_t llight;
zvalue_t lzi;
zvalue_t *lpz;
int pos_shift = (pspanpackage->v * vid_buffer_width) + pspanpackage->u;
@ -712,28 +717,28 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp
lptex = pspanpackage->ptex;
lsfrac = pspanpackage->sfrac;
ltfrac = pspanpackage->tfrac;
llight = pspanpackage->light;
memcpy(llight, pspanpackage->light, sizeof(light3_t));
lzi = pspanpackage->zi;
do
{
int i;
if ((lzi >> SHIFT16XYZ) >= *lpz)
{
int color_value;
if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
color_value = irtable[*lptex];
*lpdest = vid_colormap[irtable[*lptex]];
else
color_value = *lptex + (llight & 0xFF00);
*lpdest = R_ApplyLight(*lptex, llight);
*lpdest = vid_colormap[color_value];
*lpz = lzi >> SHIFT16XYZ;
zdamaged = true;
}
lpdest++;
lzi += r_zistepx;
lpz++;
llight += r_lstepx;
for(i=0; i<3; i++)
llight[i] += r_lstepx[i];
lptex += a_ststepxwhole;
lsfrac += a_sstepxfrac;
lptex += lsfrac >> SHIFT16XYZ;
@ -769,8 +774,9 @@ static void
R_RasterizeAliasPolySmooth(const entity_t *currententity)
{
int initialleftheight, initialrightheight;
int *plefttop, *prighttop, *pleftbottom, *prightbottom;
int working_lstepx, originalcount;
compactvert_t *plefttop, *prighttop, *pleftbottom, *prightbottom;
light3_t working_lstepx;
int originalcount;
int u, v;
pixel_t *d_ptex;
@ -780,8 +786,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
pleftbottom = pedgetable->pleftedgevert1;
prightbottom = pedgetable->prightedgevert1;
initialleftheight = pleftbottom[1] - plefttop[1];
initialrightheight = prightbottom[1] - prighttop[1];
initialleftheight = pleftbottom->v - plefttop->v;
initialrightheight = prightbottom->v - prighttop->v;
//
// set the s, t, and light gradients, which are consistent across the triangle
@ -797,18 +803,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
//
d_pedgespanpackage = triangle_spans;
u = plefttop[0];
v = plefttop[1];
d_aspancount = plefttop[0] - prighttop[0];
u = plefttop->u;
v = plefttop->v;
d_aspancount = plefttop->u - prighttop->u;
d_ptex = r_affinetridesc.pskin + (plefttop[2] >> SHIFT16XYZ) +
(plefttop[3] >> SHIFT16XYZ) * r_affinetridesc.skinwidth;
d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) +
(plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth;
{
d_sfrac = plefttop[2] & 0xFFFF;
d_tfrac = plefttop[3] & 0xFFFF;
d_sfrac = plefttop->s & 0xFFFF;
d_tfrac = plefttop->t & 0xFFFF;
}
d_light = plefttop[4];
d_zi = plefttop[5];
memcpy(d_light, plefttop->l, sizeof(light3_t));
d_zi = plefttop->zi;
if (initialleftheight == 1)
{
@ -817,8 +823,10 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
}
else
{
R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
pleftbottom[0], pleftbottom[1]);
int i;
R_PolysetSetUpForLineScan(plefttop->u, plefttop->v,
pleftbottom->u, pleftbottom->v);
// TODO: can reuse partial expressions here
@ -826,9 +834,12 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
// underflow (sort of turning the floor () we did in the gradient calcs into
// ceil (), but plus a little bit)
if (ubasestep < 0)
working_lstepx = r_lstepx - 1;
{
for(i=0; i<3; i++)
working_lstepx[i] = r_lstepx[i] - 1;
}
else
working_lstepx = r_lstepx;
memcpy(working_lstepx, r_lstepx, sizeof(light3_t));
d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) +
((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) *
@ -837,7 +848,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
for(i=0; i<3; i++)
d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep;
d_zibasestep = r_zistepy + r_zistepx * ubasestep;
d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) +
@ -847,7 +860,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
d_sfracextrastep = (r_sstepy + r_sstepx*(ubasestep + 1)) & 0xFFFF;
d_tfracextrastep = (r_tstepy + r_tstepx*(ubasestep + 1)) & 0xFFFF;
d_lightextrastep = d_lightbasestep + working_lstepx;
for(i=0; i<3; i++)
d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i];
d_ziextrastep = d_zibasestep + r_zistepx;
R_PolysetScanLeftEdge_C(initialleftheight, d_ptex, u, v);
@ -863,18 +878,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
plefttop = pleftbottom;
pleftbottom = pedgetable->pleftedgevert2;
height = pleftbottom[1] - plefttop[1];
height = pleftbottom->v - plefttop->v;
// TODO: make this a function; modularize this function in general
u = plefttop[0];
v = plefttop[1];
d_aspancount = plefttop[0] - prighttop[0];
d_ptex = r_affinetridesc.pskin + (plefttop[2] >> SHIFT16XYZ) +
(plefttop[3] >> SHIFT16XYZ) * r_affinetridesc.skinwidth;
u = plefttop->u;
v = plefttop->v;
d_aspancount = plefttop->u - prighttop->u;
d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) +
(plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth;
d_sfrac = 0;
d_tfrac = 0;
d_light = plefttop[4];
d_zi = plefttop[5];
memcpy(d_light, plefttop->l, sizeof(light3_t));
d_zi = plefttop->zi;
if (height == 1)
{
@ -883,13 +898,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
}
else
{
R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
pleftbottom[0], pleftbottom[1]);
int i;
R_PolysetSetUpForLineScan(plefttop->u, plefttop->v,
pleftbottom->u, pleftbottom->v);
if (ubasestep < 0)
working_lstepx = r_lstepx - 1;
{
for(i=0; i<3; i++)
working_lstepx[i] = r_lstepx[i] - 1;
}
else
working_lstepx = r_lstepx;
memcpy(working_lstepx, r_lstepx, sizeof(light3_t));
d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) +
((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) *
@ -898,7 +918,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
for(i=0; i<3; i++)
d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep;
d_zibasestep = r_zistepy + r_zistepx * ubasestep;
d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) +
@ -908,7 +930,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
d_sfracextrastep = (r_sstepy+r_sstepx*(ubasestep + 1)) & 0xFFFF;
d_tfracextrastep = (r_tstepy+r_tstepx*(ubasestep + 1)) & 0xFFFF;
d_lightextrastep = d_lightbasestep + working_lstepx;
for(i=0; i<3; i++)
d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i];
d_ziextrastep = d_zibasestep + r_zistepx;
R_PolysetScanLeftEdge_C(height, d_ptex, u, v);
@ -917,8 +940,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
// scan out the top (and possibly only) part of the right edge, updating the
// count field
R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
prightbottom[0], prightbottom[1]);
R_PolysetSetUpForLineScan(prighttop->u, prighttop->v,
prightbottom->u, prightbottom->v);
d_aspancount = 0;
if ((triangle_spans + initialrightheight) >= triangles_max)
{
@ -939,15 +962,15 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity)
pstart = triangle_spans + initialrightheight;
pstart->count = originalcount;
d_aspancount = prightbottom[0] - prighttop[0];
d_aspancount = prightbottom->u - prighttop->u;
prighttop = prightbottom;
prightbottom = pedgetable->prightedgevert2;
height = prightbottom[1] - prighttop[1];
height = prightbottom->v - prighttop->v;
R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
prightbottom[0], prightbottom[1]);
R_PolysetSetUpForLineScan(prighttop->u, prighttop->v,
prightbottom->u, prightbottom->v);
if ((triangle_spans + initialrightheight + height) >= triangles_max)
{
@ -978,11 +1001,11 @@ R_PolysetSetEdgeTable (void)
// determine which edges are right & left, and the order in which
// to rasterize them
//
if (r_p0[1] >= r_p1[1])
if (r_p0.v >= r_p1.v)
{
if (r_p0[1] == r_p1[1])
if (r_p0.v == r_p1.v)
{
if (r_p0[1] < r_p2[1])
if (r_p0.v < r_p2.v)
pedgetable = &edgetables[2];
else
pedgetable = &edgetables[5];
@ -995,7 +1018,7 @@ R_PolysetSetEdgeTable (void)
}
}
if (r_p0[1] == r_p2[1])
if (r_p0.v == r_p2.v)
{
if (edgetableindex)
pedgetable = &edgetables[8];
@ -1004,7 +1027,7 @@ R_PolysetSetEdgeTable (void)
return;
}
else if (r_p1[1] == r_p2[1])
else if (r_p1.v == r_p2.v)
{
if (edgetableindex)
pedgetable = &edgetables[10];
@ -1014,10 +1037,10 @@ R_PolysetSetEdgeTable (void)
return;
}
if (r_p0[1] > r_p2[1])
if (r_p0.v > r_p2.v)
edgetableindex += 2;
if (r_p1[1] > r_p2[1])
if (r_p1.v > r_p2.v)
edgetableindex += 4;
pedgetable = &edgetables[edgetableindex];

View file

@ -64,6 +64,24 @@ R_TextureAnimation (const entity_t *currententity, mtexinfo_t *tex)
return tex->image;
}
/*
* Light apply is not required
*/
static qboolean
R_SameLight(size_t size, const light3_t lightstep, const light3_t light)
{
int i;
if (((light[0] | light[1] | light[2]) & LIGHTMASK) > vid_lightthreshold)
return false;
for (i=0; i<3; i++)
{
if (((size * lightstep[i] + light[i]) & LIGHTMASK) > vid_lightthreshold)
return false;
}
return true;
}
/*
================
@ -73,8 +91,8 @@ R_DrawSurfaceBlock8_anymip
static void
R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes)
{
int v, i, b, lightstep, lighttemp, light, size;
unsigned char pix, *psource, *prowdest;
int v, i, size;
unsigned char *psource, *prowdest;
size = 1 << level;
psource = pbasesource;
@ -82,34 +100,62 @@ R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes)
for (v=0 ; v<r_numvblocks ; v++)
{
int lightleft, lightright;
int lightleftstep, lightrightstep;
light3_t lightleft, lightright;
light3_t lightleftstep, lightrightstep;
// FIXME: use delta rather than both right and left, like ASM?
lightleft = r_lightptr[0];
lightright = r_lightptr[1];
r_lightptr += r_lightwidth;
lightleftstep = (r_lightptr[0] - lightleft) >> level;
lightrightstep = (r_lightptr[1] - lightright) >> level;
memcpy(lightleft, r_lightptr, sizeof(light3_t));
memcpy(lightright, r_lightptr + 3, sizeof(light3_t));
r_lightptr += r_lightwidth * 3;
for(i=0; i<3; i++)
{
lightleftstep[i] = (r_lightptr[i] - lightleft[i]) >> level;
lightrightstep[i] = (r_lightptr[i + 3] - lightright[i]) >> level;
}
for (i=0 ; i<size ; i++)
{
lighttemp = lightleft - lightright;
lightstep = lighttemp >> level;
light3_t lightstep, light;
int j;
light = lightright;
for(j=0; j<3; j++)
{
int lighttemp;
lighttemp = lightleft[j] - lightright[j];
lightstep[j] = lighttemp >> level;
}
memcpy(light, lightright, sizeof(light3_t));
if (R_SameLight(size, lightstep, light))
{
/* just copy without light apply */
memcpy(prowdest, psource, size * sizeof(pixel_t));
}
else
{
int b;
for (b=(size-1); b>=0; b--)
{
pixel_t pix;
pix = psource[b];
prowdest[b] = ((unsigned char *)vid_colormap)
[(light & 0xFF00) + pix];
light += lightstep;
prowdest[b] = R_ApplyLight(pix, light);
for(j=0; j<3; j++)
light[j] += lightstep[j];
}
}
psource += sourcetstep;
lightright += lightrightstep;
lightleft += lightleftstep;
for(j=0; j<3; j++)
{
lightright[j] += lightrightstep[j];
lightleft[j] += lightleftstep[j];
}
prowdest += surfrowbytes;
}
@ -176,7 +222,7 @@ R_DrawSurface (drawsurf_t *drawsurf)
for (u=0 ; u<r_numhblocks; u++)
{
r_lightptr = blocklights + u;
r_lightptr = blocklights + u * 3;
if (r_lightptr >= blocklight_max)
{

View file

@ -148,7 +148,7 @@ typedef unsigned char byte;
#ifdef _MSC_VER
#define PRINTF_ATTR(FMT, VARGS)
#else // at least GCC/mingw and clang support this
#define PRINTF_ATTR(FMT, VARGS) __attribute__((format(printf, FMT , VARGS )));
#define PRINTF_ATTR(FMT, VARGS) __attribute__((format(printf, FMT , VARGS )))
#endif
/* per-level limits */