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 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. less optimal for the default gun field of view of 80.
* **sw_colorlight**: enable experimental color lighting.
## cvar operations ## cvar operations

View file

@ -77,6 +77,7 @@ typedef unsigned char pixel_t;
typedef int shift20_t; typedef int shift20_t;
typedef int zvalue_t; typedef int zvalue_t;
typedef unsigned int light_t; typedef unsigned int light_t;
typedef int light3_t[3];
// xyz-prescale to 16.16 fixed-point // xyz-prescale to 16.16 fixed-point
#define SHIFT16XYZ 16 #define SHIFT16XYZ 16
@ -92,10 +93,15 @@ typedef enum
rserr_unknown rserr_unknown
} rserr_t; } rserr_t;
/* 64 light grades available */
#define LIGHTMASK 0x3F00
extern viddef_t vid; extern viddef_t vid;
extern pixel_t *vid_buffer; // invisible buffer extern pixel_t *vid_buffer; // invisible buffer
extern pixel_t *vid_colormap; // 256 * VID_GRADES size extern pixel_t *vid_colormap; // 256 * VID_GRADES size
extern pixel_t *vid_alphamap; // 256 * 256 translucency map 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 extern char shift_size; // shift size in fixed-point
typedef struct typedef struct
@ -200,14 +206,17 @@ typedef struct
** if you change this structure be sure to change the #defines ** if you change this structure be sure to change the #defines
** listed after it! ** listed after it!
*/ */
typedef struct finalvert_s { typedef struct compactvert_s {
int u, v, s, t; int u, v, s, t;
int l; light3_t l; // full color light
zvalue_t zi; zvalue_t zi;
int flags; } compactvert_t;
float xyz[3]; // eye space
} finalvert_t;
typedef struct finalvert_s {
compactvert_t cv; // reuse compacted type
int flags;
float xyz[3]; // eye space
} finalvert_t;
typedef struct typedef struct
{ {
@ -228,12 +237,6 @@ typedef struct
int surfheight; // in mipmapped texels int surfheight; // in mipmapped texels
} drawsurf_t; } drawsurf_t;
typedef struct {
int ambientlight;
int shadelight;
float *plightvec;
} alight_t;
// clipped bmodel edges // clipped bmodel edges
typedef struct bedge_s typedef struct bedge_s
{ {
@ -432,6 +435,7 @@ extern cvar_t *r_lefthand;
extern cvar_t *r_gunfov; extern cvar_t *r_gunfov;
extern cvar_t *r_farsee; extern cvar_t *r_farsee;
extern cvar_t *r_lightmap; extern cvar_t *r_lightmap;
extern cvar_t *r_colorlight;
extern cvar_t *r_drawworld; extern cvar_t *r_drawworld;
extern cvar_t *r_lerpmodels; extern cvar_t *r_lerpmodels;
extern cvar_t *r_lightlevel; extern cvar_t *r_lightlevel;
@ -502,7 +506,8 @@ extern edge_t **removeedges;
typedef struct { typedef struct {
int u, v, count; int u, v, count;
pixel_t *ptex; pixel_t *ptex;
int sfrac, tfrac, light; int sfrac, tfrac;
light3_t light;
zvalue_t zi; zvalue_t zi;
} spanpackage_t; } spanpackage_t;
extern spanpackage_t *triangle_spans, *triangles_max; 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); void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
extern byte d_8to24table[256 * 4];
void R_InitImages(void); void R_InitImages(void);
void R_ShutdownImages(void); void R_ShutdownImages(void);
image_t *R_FindImage(char *name, imagetype_t type); image_t *R_FindImage(char *name, imagetype_t type);
byte *Get_BestImageSize(const image_t *image, int *req_width, int *req_height); byte *Get_BestImageSize(const image_t *image, int *req_width, int *req_height);
void R_FreeUnusedImages(void); void R_FreeUnusedImages(void);
qboolean R_ImageHasFreeSpace(void); qboolean R_ImageHasFreeSpace(void);
pixel_t R_ApplyLight(pixel_t pix, const light3_t light);
void R_InitSkyBox(model_t *loadmodel); 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 ); 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 // lighting info
byte styles[MAXLIGHTMAPS]; byte styles[MAXLIGHTMAPS];
byte *samples; // [numstyles*surfsize] byte *samples; // [numstyles*surfsize*3]
struct msurface_s *nextalphasurface; struct msurface_s *nextalphasurface;
} msurface_t; } 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) R_Alias_clip_z (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out)
{ {
float scale; float scale;
int i;
scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) / scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
(pfv1->xyz[2] - 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[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
out->xyz[2] = ALIAS_Z_CLIP_PLANE; out->xyz[2] = ALIAS_Z_CLIP_PLANE;
out->s = pfv0->s + (pfv1->s - pfv0->s) * scale; out->cv.s = pfv0->cv.s + (pfv1->cv.s - pfv0->cv.s) * scale;
out->t = pfv0->t + (pfv1->t - pfv0->t) * scale; out->cv.t = pfv0->cv.t + (pfv1->cv.t - pfv0->cv.t) * scale;
out->l = pfv0->l + (pfv1->l - pfv0->l) * 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); 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 static void
R_Alias_clip_left (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out) R_Alias_clip_left (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out)
{ {
float scale; float scale;
if (pfv0->v >= pfv1->v ) if (pfv0->cv.v >= pfv1->cv.v )
{ {
scale = (float)(r_refdef.aliasvrect.x - pfv0->u) / scale = (float)(r_refdef.aliasvrect.x - pfv0->cv.u) /
(pfv1->u - pfv0->u); (pfv1->cv.u - pfv0->cv.u);
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; R_Alias_clip_scale (pfv1, pfv0, scale, out);
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;
} }
else else
{ {
scale = (float)(r_refdef.aliasvrect.x - pfv1->u) / scale = (float)(r_refdef.aliasvrect.x - pfv1->cv.u) /
(pfv0->u - pfv1->u); (pfv0->cv.u - pfv1->cv.u);
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; R_Alias_clip_scale (pfv0, pfv1, scale, out);
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;
} }
} }
@ -83,27 +94,19 @@ R_Alias_clip_right (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_
{ {
float scale; float scale;
if ( pfv0->v >= pfv1->v ) if ( pfv0->cv.v >= pfv1->cv.v )
{ {
scale = (float)(r_refdef.aliasvrectright - pfv0->u ) / scale = (float)(r_refdef.aliasvrectright - pfv0->cv.u ) /
(pfv1->u - pfv0->u ); (pfv1->cv.u - pfv0->cv.u );
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; R_Alias_clip_scale (pfv1, pfv0, scale, out);
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;
} }
else else
{ {
scale = (float)(r_refdef.aliasvrectright - pfv1->u ) / scale = (float)(r_refdef.aliasvrectright - pfv1->cv.u ) /
(pfv0->u - pfv1->u ); (pfv0->cv.u - pfv1->cv.u );
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; R_Alias_clip_scale (pfv0, pfv1, scale, out);
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;
} }
} }
@ -112,27 +115,19 @@ R_Alias_clip_top (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t
{ {
float scale; float scale;
if (pfv0->v >= pfv1->v) if (pfv0->cv.v >= pfv1->cv.v)
{ {
scale = (float)(r_refdef.aliasvrect.y - pfv0->v) / scale = (float)(r_refdef.aliasvrect.y - pfv0->cv.v) /
(pfv1->v - pfv0->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; R_Alias_clip_scale (pfv1, pfv0, scale, out);
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;
} }
else else
{ {
scale = (float)(r_refdef.aliasvrect.y - pfv1->v) / scale = (float)(r_refdef.aliasvrect.y - pfv1->cv.v) /
(pfv0->v - pfv1->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; R_Alias_clip_scale (pfv0, pfv1, scale, out);
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;
} }
} }
@ -142,29 +137,19 @@ R_Alias_clip_bottom (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert
{ {
float scale; float scale;
if (pfv0->v >= pfv1->v) if (pfv0->cv.v >= pfv1->cv.v)
{ {
scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) / scale = (float)(r_refdef.aliasvrectbottom - pfv0->cv.v) /
(pfv1->v - pfv0->v); (pfv1->cv.v - pfv0->cv.v);
out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; R_Alias_clip_scale (pfv1, pfv0, scale, out);
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;
} }
else else
{ {
scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) / scale = (float)(r_refdef.aliasvrectbottom - pfv1->cv.v) /
(pfv0->v - pfv1->v); (pfv0->cv.v - pfv1->cv.v);
out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; R_Alias_clip_scale (pfv0, pfv1, scale, out);
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;
} }
} }
@ -193,13 +178,13 @@ R_AliasClip (const finalvert_t *in, finalvert_t *out, int flag, int count,
{ {
clip (&in[j], &in[i], &out[k]); clip (&in[j], &in[i], &out[k]);
out[k].flags = 0; 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; 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; 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; 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; out[k].flags |= ALIAS_BOTTOM_CLIP;
k++; k++;
} }
@ -225,7 +210,7 @@ R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index0, co
{ {
int i, k, pingpong; int i, k, pingpong;
unsigned clipflags; unsigned clipflags;
finalvert_t fv[2][8]; finalvert_t fv[2][8];
// copy vertexes and fix seam texture coordinates // copy vertexes and fix seam texture coordinates
fv[0][0] = *index0; fv[0][0] = *index0;
@ -292,15 +277,15 @@ R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index0, co
for (i=0 ; i<k ; i++) for (i=0 ; i<k ; i++)
{ {
if (fv[pingpong][i].u < r_refdef.aliasvrect.x) if (fv[pingpong][i].cv.u < r_refdef.aliasvrect.x)
fv[pingpong][i].u = r_refdef.aliasvrect.x; fv[pingpong][i].cv.u = r_refdef.aliasvrect.x;
else if (fv[pingpong][i].u > r_refdef.aliasvrectright) else if (fv[pingpong][i].cv.u > r_refdef.aliasvrectright)
fv[pingpong][i].u = r_refdef.aliasvrectright; fv[pingpong][i].cv.u = r_refdef.aliasvrectright;
if (fv[pingpong][i].v < r_refdef.aliasvrect.y) if (fv[pingpong][i].cv.v < r_refdef.aliasvrect.y)
fv[pingpong][i].v = r_refdef.aliasvrect.y; fv[pingpong][i].cv.v = r_refdef.aliasvrect.y;
else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom) else if (fv[pingpong][i].cv.v > r_refdef.aliasvrectbottom)
fv[pingpong][i].v = r_refdef.aliasvrectbottom; fv[pingpong][i].cv.v = r_refdef.aliasvrectbottom;
fv[pingpong][i].flags = 0; fv[pingpong][i].flags = 0;
} }

View file

@ -35,9 +35,9 @@ affinetridesc_t r_affinetridesc;
static vec3_t r_plightvec; static vec3_t r_plightvec;
static vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move; static vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move;
static int r_ambientlight; static light3_t r_ambientlight;
int r_aliasblendcolor; int r_aliasblendcolor;
static float r_shadelight; static vec3_t r_shadelight;
static daliasframe_t *r_thisframe, *r_lastframe; 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 continue; // completely clipped
// insert s/t coordinates // insert s/t coordinates
pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) 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 continue; // completely clipped
// insert s/t coordinates // insert s/t coordinates
pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ;
pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ;
pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ;
pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ;
pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ;
pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ;
if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) 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++ ) for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ )
{ {
int temp;
float lightcos; float lightcos;
const float *plightnormal; const float *plightnormal;
vec3_t lerped_vert; vec3_t lerped_vert;
@ -426,19 +425,29 @@ R_AliasTransformFinalVerts(const entity_t *currententity, int numpoints, finalve
// lighting // lighting
lightcos = DotProduct (plightnormal, r_plightvec); lightcos = DotProduct (plightnormal, r_plightvec);
temp = r_ambientlight;
if (lightcos < 0) if (lightcos < 0)
{ {
temp += (int)(r_shadelight * lightcos); int j;
// clamp; because we limited the minimum ambient and shading light, we for(j=0; j<3; j++)
// don't have to clamp low light, just bright {
if (temp < 0) int temp;
temp = 0;
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->cv.l[j] = temp;
}
} }
else
fv->l = temp; memcpy(fv->cv.l, r_ambientlight, sizeof(light3_t));
if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE )
{ {
@ -469,18 +478,18 @@ R_AliasProjectAndClipTestFinalVert( finalvert_t *fv )
z = fv->xyz[2]; z = fv->xyz[2];
zi = 1.0 / z; zi = 1.0 / z;
fv->zi = zi * s_ziscale; fv->cv.zi = zi * s_ziscale;
fv->u = (x * aliasxscale * zi) + aliasxcenter; fv->cv.u = (x * aliasxscale * zi) + aliasxcenter;
fv->v = (y * aliasyscale * zi) + aliasycenter; 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; 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; fv->flags |= ALIAS_TOP_CLIP;
if (fv->u > r_refdef.aliasvrectright) if (fv->cv.u > r_refdef.aliasvrectright)
fv->flags |= ALIAS_RIGHT_CLIP; fv->flags |= ALIAS_RIGHT_CLIP;
if (fv->v > r_refdef.aliasvrectbottom) if (fv->cv.v > r_refdef.aliasvrectbottom)
fv->flags |= ALIAS_BOTTOM_CLIP; fv->flags |= ALIAS_BOTTOM_CLIP;
} }
@ -534,10 +543,9 @@ R_AliasSetupLighting
static void static void
R_AliasSetupLighting(entity_t *currententity) R_AliasSetupLighting(entity_t *currententity)
{ {
alight_t lighting; const vec3_t lightvec = {-1, 0, 0};
float lightvec[3] = {-1, 0, 0};
vec3_t light; vec3_t light;
int i, j; int i;
// all components of light should be identical in software // all components of light should be identical in software
if ( currententity->flags & RF_FULLBRIGHT ) 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; light[0] = light[1] = light[2] = temp;
lighting.shadelight = j; }
lighting.plightvec = lightvec; for(i=0; i<3; i++)
{
int j;
// clamp lighting so it doesn't overbright as much j = light[i] * 255;
if (lighting.ambientlight > 128)
lighting.ambientlight = 128;
if (lighting.ambientlight + lighting.shadelight > 192)
lighting.shadelight = 192 - lighting.ambientlight;
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have r_ambientlight[i] = j;
// to clamp off the bottom r_shadelight[i] = j;
r_ambientlight = lighting.ambientlight;
if (r_ambientlight < LIGHT_MIN) // clamp lighting so it doesn't overbright as much
r_ambientlight = LIGHT_MIN; if (r_ambientlight[i] > 128)
r_ambientlight[i] = 128;
if (r_ambientlight[i] + r_shadelight[i] > 192)
r_shadelight[i] = 192 - r_ambientlight[i];
r_ambientlight = (255 - r_ambientlight) << VID_CBITS; // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
// to clamp off the bottom
if (r_ambientlight[i] < LIGHT_MIN)
r_ambientlight[i] = LIGHT_MIN;
r_shadelight = lighting.shadelight; r_ambientlight[i] = (255 - r_ambientlight[i]) << VID_CBITS;
if (r_shadelight < 0) if (r_shadelight[i] < 0)
r_shadelight = 0; r_shadelight[i] = 0;
r_shadelight *= VID_GRADES; r_shadelight[i] *= VID_GRADES;
}
// rotate the lighting vector into the model's frame of reference // rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct( lighting.plightvec, s_alias_forward ); r_plightvec[0] = DotProduct( lightvec, s_alias_forward );
r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right ); r_plightvec[1] = -DotProduct( lightvec, s_alias_right );
r_plightvec[2] = DotProduct( lighting.plightvec, s_alias_up ); 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) size_t data_size, imagetype_t type)
{ {
image_t *image; image_t *image;
size_t i, size, full_size; size_t size, full_size;
size = width * height; 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; return NULL;
image = R_FindFreeImage(); image = R_FindFreeImage();
@ -246,6 +247,8 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real
image->transparent = false; image->transparent = false;
if (type != it_wall) if (type != it_wall)
{ {
size_t i;
for (i=0 ; i<size ; i++) for (i=0 ; i<size ; i++)
{ {
if (pic[i] == 255) if (pic[i] == 255)
@ -305,7 +308,8 @@ R_LoadWal (char *name, imagetype_t type)
height = LittleLong (mt->height); height = LittleLong (mt->height);
ofs = LittleLong(mt->offsets[0]); 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)) ((file_size - ofs) / width < height))
{ {
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name); 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; 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 static void
R_Convert32To8bit(const unsigned char* pic_in, pixel_t* pic_out, size_t size) 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 */ /* 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; return r_whitetexture_mip;
} }

View file

@ -49,7 +49,7 @@ R_MarkLights (dlight_t *light, int bit, mnode_t *node, int r_dlightframecount)
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
i = light->intensity; i = light->intensity;
if( i< 0) if (i < 0)
i = -i; i = -i;
if (dist > i) // (dist > light->intensity) if (dist > i) // (dist > light->intensity)
@ -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); R_MarkLights (light, bit, node->children[0], r_dlightframecount);
return; return;
} }
if (dist < -i) // (dist < -light->intensity) if (dist < -i) // (dist < -light->intensity)
{ {
R_MarkLights (light, bit, node->children[1], r_dlightframecount); 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 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; float front, back, frac;
qboolean side; qboolean side;
@ -122,10 +119,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
int s, t, ds, dt; int s, t, ds, dt;
int i; int i;
mtexinfo_t *tex; mtexinfo_t *tex;
byte *lightmap;
float *scales;
int maps; int maps;
float samp;
int r; int r;
if (node->contents != -1) if (node->contents != -1)
@ -140,7 +134,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
side = front < 0; side = front < 0;
if ( (back < 0) == side) if ( (back < 0) == side)
return RecursiveLightPoint (node->children[side], start, end); return RecursiveLightPoint (node->children[side], start, end, pointcolor);
frac = front / (front-back); frac = front / (front-back);
mid[0] = start[0] + (end[0] - start[0])*frac; 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; mid[plane->type] = plane->dist;
// go down front side // go down front side
r = RecursiveLightPoint (node->children[side], start, mid); r = RecursiveLightPoint (node->children[side], start, mid, pointcolor);
if (r >= 0) if (r >= 0)
return r; // hit something return r; // hit something
// check for impact on this node // check for impact on this node
VectorCopy (mid, lightspot);
surf = r_worldmodel->surfaces + node->firstsurface; surf = r_worldmodel->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++) for (i=0 ; i<node->numsurfaces ; i++, surf++)
{ {
byte *lightmap;
if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY)) if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY))
continue; // no lightmaps continue; // no lightmaps
@ -185,23 +179,35 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
lightmap = surf->samples; lightmap = surf->samples;
VectorCopy (vec3_origin, pointcolor); 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 ; for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
maps++) maps++)
{ {
samp = *lightmap * r_modulate->value * (1.0/255); // adjust for gl scale const float *rgb;
scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb; int j;
VectorMA (pointcolor, samp, scales, pointcolor);
lightmap += ((surf->extents[0]>>4)+1) * rgb = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
((surf->extents[1]>>4)+1);
/* 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);
} }
return 1; return 1;
} }
// go down back side // 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; int lnum;
dlight_t *dl; dlight_t *dl;
vec3_t dist; vec3_t dist;
vec3_t pointcolor;
if (!r_worldmodel->lightdata) 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[1] = p[1];
end[2] = p[2] - 2048; end[2] = p[2] - 2048;
r = RecursiveLightPoint (r_worldmodel->nodes, p, end); r = RecursiveLightPoint (r_worldmodel->nodes, p, end, pointcolor);
if (r == -1) if (r == -1)
{ {
@ -274,36 +281,47 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
{ {
msurface_t *surf; msurface_t *surf;
int lnum; int lnum;
int sd, td;
float dist, rad, minlight;
vec3_t impact, local;
int s, t;
int i;
int smax, tmax; int smax, tmax;
mtexinfo_t *tex; mtexinfo_t *tex;
dlight_t *dl;
int negativeLight;
surf = drawsurf->surf; surf = drawsurf->surf;
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>4)+1;
tex = surf->texinfo; tex = surf->texinfo;
if (blocklight_max <= blocklights + smax*tmax) if (blocklight_max <= blocklights + smax*tmax*3)
{ {
r_outoflights = true; r_outoflights = true;
return; return;
} }
for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++) 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; light_t *plightdest = blocklights;
if (!(surf->dlightbits & (1<<lnum))) if (!(surf->dlightbits & (1<<lnum)))
continue; // not lit by this light continue; // not lit by this light
dl = &r_newrefdef.dlights[lnum]; dl = &r_newrefdef.dlights[lnum];
rad = dl->intensity; 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; negativeLight = 0;
if(rad < 0) if(rad < 0)
@ -335,11 +353,15 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
int s, td;
td = local[1] - t*16; td = local[1] - t*16;
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
int sd;
sd = local[0] - s*16; sd = local[0] - s*16;
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
@ -348,21 +370,25 @@ R_AddDynamicLights (drawsurf_t* drawsurf)
else else
dist = td + (sd>>1); dist = td + (sd>>1);
//==== for (i=0; i<3; i++)
if(!negativeLight)
{ {
if (dist < minlight) //====
*plightdest += (rad - dist)*256; if(!negativeLight)
{
if (dist < minlight)
*plightdest += (rad - dist) * color[i];
}
else
{
if (dist < minlight)
*plightdest -= (rad - dist) * color[i];
if(*plightdest < minlight)
*plightdest = minlight;
}
//====
plightdest ++;
} }
else
{
if (dist < minlight)
*plightdest -= (rad - dist)*256;
if(*plightdest < minlight)
*plightdest = minlight;
}
//====
plightdest ++;
} }
} }
} }
@ -379,7 +405,7 @@ void
R_BuildLightMap (drawsurf_t* drawsurf) R_BuildLightMap (drawsurf_t* drawsurf)
{ {
int smax, tmax; int smax, tmax;
int i, size; int size;
byte *lightmap; byte *lightmap;
msurface_t *surf; msurface_t *surf;
@ -387,22 +413,22 @@ R_BuildLightMap (drawsurf_t* drawsurf)
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>4)+1;
size = smax*tmax; size = smax*tmax*3;
if (blocklight_max <= blocklights + size) if (blocklight_max <= blocklights + size)
{ {
r_outoflights = true; r_outoflights = true;
return; return;
} }
if (r_fullbright->value || !r_worldmodel->lightdata)
{
memset(blocklights, 0, size * sizeof(light_t));
return;
}
// clear to no light // clear to no light
memset(blocklights, 0, size * sizeof(light_t)); memset(blocklights, 0, size * sizeof(light_t));
if (r_fullbright->value || !r_worldmodel->lightdata)
{
return;
}
// add all the lightmaps // add all the lightmaps
lightmap = surf->samples; lightmap = surf->samples;
if (lightmap) if (lightmap)
@ -413,11 +439,48 @@ R_BuildLightMap (drawsurf_t* drawsurf)
maps++) maps++)
{ {
unsigned scale; unsigned scale;
light_t *curr_light, *max_light;
curr_light = blocklights;
max_light = blocklights + size;
scale = drawsurf->lightadj[maps]; // 8.8 fraction scale = drawsurf->lightadj[maps]; // 8.8 fraction
for (i=0 ; i<size ; i++)
blocklights[i] += lightmap[i] * scale; if(r_colorlight->value == 0)
lightmap += size; // skip to next lightmap {
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,18 +489,28 @@ R_BuildLightMap (drawsurf_t* drawsurf)
R_AddDynamicLights (drawsurf); R_AddDynamicLights (drawsurf);
// bound, invert, and shift // bound, invert, and shift
for (i=0 ; i<size ; i++)
{ {
int t; light_t *curr_light, *max_light;
t = (int)blocklights[i]; curr_light = blocklights;
if (t < 0) max_light = blocklights + size;
t = 0;
t = (255*256 - t) >> (8 - VID_CBITS);
if (t < (1 << 6)) do
t = (1 << 6); {
int t;
blocklights[i] = t; t = (int)*curr_light;
if (t < 0)
t = 0;
t = (255*256 - t) >> (8 - VID_CBITS);
if (t < (1 << 6))
t = (1 << 6);
*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; espan_t *vid_polygon_spans = NULL;
pixel_t *vid_colormap = NULL; pixel_t *vid_colormap = NULL;
pixel_t *vid_alphamap = 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_minu, vid_minv, vid_maxu, vid_maxv;
static int vid_zminu, vid_zminv, vid_zmaxu, vid_zmaxv; static int vid_zminu, vid_zminv, vid_zmaxu, vid_zmaxv;
@ -51,7 +53,7 @@ static qboolean palette_changed;
refimport_t ri; refimport_t ri;
static unsigned d_8to24table[256]; byte d_8to24table[256 * 4];
char skyname[MAX_QPATH]; char skyname[MAX_QPATH];
vec3_t skyaxis; vec3_t skyaxis;
@ -135,6 +137,7 @@ cvar_t *r_lefthand;
cvar_t *r_gunfov; cvar_t *r_gunfov;
cvar_t *r_farsee; cvar_t *r_farsee;
cvar_t *r_lightmap; cvar_t *r_lightmap;
cvar_t *r_colorlight;
static cvar_t *sw_aliasstats; static cvar_t *sw_aliasstats;
cvar_t *sw_clearcolor; cvar_t *sw_clearcolor;
cvar_t *sw_drawflat; cvar_t *sw_drawflat;
@ -396,6 +399,7 @@ R_RegisterVariables (void)
r_gunfov = ri.Cvar_Get( "r_gunfov", "80", CVAR_ARCHIVE ); r_gunfov = ri.Cvar_Get( "r_gunfov", "80", CVAR_ARCHIVE );
r_farsee = ri.Cvar_Get("r_farsee", "0", CVAR_LATCH | CVAR_ARCHIVE); r_farsee = ri.Cvar_Get("r_farsee", "0", CVAR_LATCH | CVAR_ARCHIVE);
r_lightmap = ri.Cvar_Get("r_lightmap", "0", 0); 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_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0); r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0); r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
@ -510,6 +514,14 @@ RE_Shutdown (void)
free (vid_colormap); free (vid_colormap);
vid_colormap = NULL; vid_colormap = NULL;
} }
/* free lightmap */
if (vid_lightmap)
{
free (vid_lightmap);
vid_lightmap = NULL;
}
R_UnRegister (); R_UnRegister ();
Mod_FreeAll (); Mod_FreeAll ();
R_ShutdownImages (); R_ShutdownImages ();
@ -1230,7 +1242,7 @@ R_CalcPalette (void)
if (modified) if (modified)
{ // set back to default { // set back to default
modified = false; modified = false;
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); R_GammaCorrectAndSetPalette( d_8to24table );
return; return;
} }
return; return;
@ -1246,7 +1258,7 @@ R_CalcPalette (void)
one_minus_alpha = (1.0 - alpha); one_minus_alpha = (1.0 - alpha);
in = (byte *)d_8to24table; in = d_8to24table;
out = palette[0]; out = palette[0];
for (i=0 ; i<256 ; i++, in+=4, out+=4) for (i=0 ; i<256 ; i++, in+=4, out+=4)
{ {
@ -1439,7 +1451,7 @@ R_InitGraphics( int width, int height )
R_InitCaches(); 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); 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 ) if ( vid_gamma->modified || sw_overbrightbits->modified )
{ {
Draw_BuildGammaTable(); Draw_BuildGammaTable();
R_GammaCorrectAndSetPalette((const unsigned char * )d_8to24table); R_GammaCorrectAndSetPalette(d_8to24table);
// we need redraw everything // we need redraw everything
VID_WholeDamageBuffer(); VID_WholeDamageBuffer();
// and backbuffer should be zeroed // and backbuffer should be zeroed
@ -1602,7 +1614,7 @@ RE_SetPalette(const unsigned char *palette)
} }
else else
{ {
R_GammaCorrectAndSetPalette((const unsigned char *)d_8to24table); R_GammaCorrectAndSetPalette(d_8to24table);
} }
} }
@ -1752,14 +1764,16 @@ Draw_GetPalette (void)
{ {
byte *pal, *out; byte *pal, *out;
int i; int i;
int white = 0;
// get the palette and colormap
/* get the palette and colormap */
LoadPCX ("pics/colormap.pcx", &vid_colormap, &pal, NULL, NULL); LoadPCX ("pics/colormap.pcx", &vid_colormap, &pal, NULL, NULL);
if (!vid_colormap) if (!vid_colormap)
ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx"); ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
vid_alphamap = vid_colormap + 64*256; vid_alphamap = vid_colormap + 64*256;
out = (byte *)d_8to24table; out = d_8to24table;
for (i=0 ; i<256 ; i++, out+=4) for (i=0 ; i<256 ; i++, out+=4)
{ {
int r, g, b; int r, g, b;
@ -1771,9 +1785,34 @@ Draw_GetPalette (void)
out[0] = r; out[0] = r;
out[1] = g; out[1] = g;
out[2] = b; out[2] = b;
if (r == 255 && g == 255 && b == 255)
white = i;
} }
free (pal); 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)); 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 // 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 static void
Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l) Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l)
{ {
int i, size; int size;
pixel_t *in;
if (!l->filelen) if (!l->filelen)
{ {
@ -266,18 +265,9 @@ Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l)
return; return;
} }
size = l->filelen/3; size = l->filelen;
loadmodel->lightdata = Hunk_Alloc(size); loadmodel->lightdata = Hunk_Alloc(size);
in = mod_base + l->fileofs; memcpy(loadmodel->lightdata, mod_base + l->fileofs, size);
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];
}
} }
@ -665,9 +655,13 @@ Mod_LoadFaces (model_t *loadmodel, byte *mod_base, lump_t *l)
out->styles[i] = in->styles[i]; out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs); i = LittleLong(in->lightofs);
if (i == -1) if (i == -1)
{
out->samples = NULL; out->samples = NULL;
}
else else
out->samples = loadmodel->lightdata + i/3; {
out->samples = loadmodel->lightdata + i;
}
// set the drawing flags flag // 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 // lighting is a special case, because we keep only 1 byte out of 3
// (=> no colored lighting in soft renderer by default) // (=> 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; size = (size + 31) & ~31;
/* save color data */
hunkSize += size; hunkSize += size;
} }

View file

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

View file

@ -64,6 +64,24 @@ R_TextureAnimation (const entity_t *currententity, mtexinfo_t *tex)
return tex->image; 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 static void
R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes) R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes)
{ {
int v, i, b, lightstep, lighttemp, light, size; int v, i, size;
unsigned char pix, *psource, *prowdest; unsigned char *psource, *prowdest;
size = 1 << level; size = 1 << level;
psource = pbasesource; psource = pbasesource;
@ -82,34 +100,62 @@ R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes)
for (v=0 ; v<r_numvblocks ; v++) for (v=0 ; v<r_numvblocks ; v++)
{ {
int lightleft, lightright; light3_t lightleft, lightright;
int lightleftstep, lightrightstep; light3_t lightleftstep, lightrightstep;
// FIXME: use delta rather than both right and left, like ASM? // FIXME: use delta rather than both right and left, like ASM?
lightleft = r_lightptr[0]; memcpy(lightleft, r_lightptr, sizeof(light3_t));
lightright = r_lightptr[1]; memcpy(lightright, r_lightptr + 3, sizeof(light3_t));
r_lightptr += r_lightwidth; r_lightptr += r_lightwidth * 3;
lightleftstep = (r_lightptr[0] - lightleft) >> level; for(i=0; i<3; i++)
lightrightstep = (r_lightptr[1] - lightright) >> level; {
lightleftstep[i] = (r_lightptr[i] - lightleft[i]) >> level;
lightrightstep[i] = (r_lightptr[i + 3] - lightright[i]) >> level;
}
for (i=0 ; i<size ; i++) for (i=0 ; i<size ; i++)
{ {
lighttemp = lightleft - lightright; light3_t lightstep, light;
lightstep = lighttemp >> level; int j;
light = lightright; for(j=0; j<3; j++)
for (b=(size-1); b>=0; b--)
{ {
pix = psource[b]; int lighttemp;
prowdest[b] = ((unsigned char *)vid_colormap)
[(light & 0xFF00) + pix]; lighttemp = lightleft[j] - lightright[j];
light += lightstep; 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] = R_ApplyLight(pix, light);
for(j=0; j<3; j++)
light[j] += lightstep[j];
}
} }
psource += sourcetstep; psource += sourcetstep;
lightright += lightrightstep;
lightleft += lightleftstep; for(j=0; j<3; j++)
{
lightright[j] += lightrightstep[j];
lightleft[j] += lightleftstep[j];
}
prowdest += surfrowbytes; prowdest += surfrowbytes;
} }
@ -176,7 +222,7 @@ R_DrawSurface (drawsurf_t *drawsurf)
for (u=0 ; u<r_numhblocks; u++) for (u=0 ; u<r_numhblocks; u++)
{ {
r_lightptr = blocklights + u; r_lightptr = blocklights + u * 3;
if (r_lightptr >= blocklight_max) if (r_lightptr >= blocklight_max)
{ {

View file

@ -65,7 +65,7 @@ typedef unsigned char byte;
// must be used as prefix (YQ2_ATTR_NORETURN void bla();)! // must be used as prefix (YQ2_ATTR_NORETURN void bla();)!
#define YQ2_ATTR_NORETURN __attribute__ ((noreturn)) #define YQ2_ATTR_NORETURN __attribute__ ((noreturn))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
// Note: We prefer VS2019 16.8 or newer in C11 mode (/std:c11), // Note: We prefer VS2019 16.8 or newer in C11 mode (/std:c11),
// then the __STDC_VERSION__ >= 201112L case above is used // then the __STDC_VERSION__ >= 201112L case above is used
#define YQ2_ALIGNAS_SIZE(SIZE) __declspec(align(SIZE)) #define YQ2_ALIGNAS_SIZE(SIZE) __declspec(align(SIZE))
@ -148,7 +148,7 @@ typedef unsigned char byte;
#ifdef _MSC_VER #ifdef _MSC_VER
#define PRINTF_ATTR(FMT, VARGS) #define PRINTF_ATTR(FMT, VARGS)
#else // at least GCC/mingw and clang support this #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 #endif
/* per-level limits */ /* per-level limits */