ref: a53e14793a11a6af0b83bdbd94772c47ee41e44b
parent: f64250f9c3b1376064cd214c36064044c98b117e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jan 8 13:06:59 EST 2024
deglobalize surf drawing and lighting
--- a/d_edge.c
+++ b/d_edge.c
@@ -3,8 +3,7 @@
float scale_for_mip;
// FIXME: should go away
-extern void R_RotateBmodel (entity_t *entity, view_t *v);
-extern void R_TransformFrustum (view_t *v);
+void R_RotateBmodel(entity_t *entity, view_t *v);
static int
D_MipLevelForScale(float scale)
@@ -86,6 +85,7 @@
{
vec3_t local_modelorg, transformed_modelorg, world_transformed_modelorg;
surfcache_t *pcurrentcache;
+ drawsurf_t ds = {0};
msurface_t *pface;
int miplevel;
entity_t *e;
@@ -115,8 +115,6 @@
if(alpha < 1)
alpha = 255;
- blend = (s->flags & SURF_FENCE) || (r_drawflags & DRAW_BLEND);
-
t.z.stepu = s->d_zistepu;
t.z.stepv = s->d_zistepv;
t.z.origin = s->d_ziorigin;
@@ -142,12 +140,15 @@
if(s->flags & SURF_FENCE)
miplevel = max(miplevel-1, 0);
- pcurrentcache = D_CacheSurface(s->entity, pface, miplevel);
+ pcurrentcache = D_CacheSurface(s->entity, pface, &ds, miplevel);
t.p = pcurrentcache->pixels;
t.w = pcurrentcache->width;
D_CalcGradients(miplevel, pface, transformed_modelorg, &v, &t);
+ blend = (s->flags & SURF_FENCE) || (r_drawflags & DRAW_BLEND);
D_DrawSpans(s->spans, &t, alpha,
- (alpha == 255 && s->flags & SURF_FENCE) ? SPAN_FENCE : (blend ? SPAN_BLEND : SPAN_SOLID)
+ (alpha == 255 && (s->flags & SURF_FENCE))
+ ? SPAN_FENCE
+ : (blend ? SPAN_BLEND : SPAN_SOLID)
);
}
--- a/d_iface.h
+++ b/d_iface.h
@@ -115,21 +115,18 @@
typedef struct
{
- pixel_t *surfdat; // destination for generated surface
- int rowbytes; // destination logical width in bytes
- msurface_t *surf; // description for surface to generate
- fixed8_t lightadj[MAXLIGHTMAPS];
- // adjust for lightmap levels for dynamic lighting
+ msurface_t *m; // description for surface to generate
texture_t *texture; // corrected for animating textures
- int surfmip; // mipmapped ratio of surface texels / world pixels
- int surfwidth; // in mipmapped texels
- int surfheight; // in mipmapped texels
-} drawsurf_t;
+ pixel_t *dat; // destination for generated surface
+ int mip; // mipmapped ratio of surface texels / world pixels
+ int width; // in mipmapped texels
+ int height; // in mipmapped texels
+ unsigned blocklights[3][18*18];
+ fixed8_t lightadj[MAXLIGHTMAPS];
+}drawsurf_t;
-extern drawsurf_t r_drawsurf;
+void R_DrawSurface (entity_t *e, drawsurf_t *surf);
-void R_DrawSurface (entity_t *e);
-
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
#define TURB_TEX_SIZE 64 // base turbulent texture size
@@ -141,7 +138,6 @@
extern float skyspeed;
extern float skytime;
-extern int c_surf;
extern vrect_t scr_vrect;
extern pixel_t *r_warpbuffer;
--- a/d_local.h
+++ b/d_local.h
@@ -83,7 +83,7 @@
void D_DrawSkyScans8 (espan_t *pspan);
-surfcache_t *D_CacheSurface (entity_t *e, msurface_t *surface, int miplevel);
+surfcache_t *D_CacheSurface(entity_t *e, msurface_t *ms, drawsurf_t *ds, int miplevel);
extern int *d_pscantable;
extern int d_scantable[MAXHEIGHT];
--- a/d_surf.c
+++ b/d_surf.c
@@ -180,63 +180,56 @@
D_CacheSurface
================
*/
-surfcache_t *D_CacheSurface (entity_t *e, msurface_t *surface, int miplevel)
+surfcache_t *
+D_CacheSurface(entity_t *e, msurface_t *ms, drawsurf_t *ds, int miplevel)
{
- surfcache_t *cache;
+ surfcache_t *cache;
// if the surface is animating or flashing, flush the cache
- r_drawsurf.texture = R_TextureAnimation(e, surface->texinfo->texture);
- r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
- r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
- r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
- r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
+ ds->texture = R_TextureAnimation(e, ms->texinfo->texture);
+ ds->lightadj[0] = d_lightstylevalue[ms->styles[0]];
+ ds->lightadj[1] = d_lightstylevalue[ms->styles[1]];
+ ds->lightadj[2] = d_lightstylevalue[ms->styles[2]];
+ ds->lightadj[3] = d_lightstylevalue[ms->styles[3]];
// see if the cache holds apropriate data
- cache = surface->cachespots[miplevel];
+ cache = ms->cachespots[miplevel];
if(e == cl_entities || e->model->name[0] == '*')
- if (cache && !cache->dlight && surface->dlightframe != r_framecount
- && cache->texture == r_drawsurf.texture
- && cache->lightadj[0] == r_drawsurf.lightadj[0]
- && cache->lightadj[1] == r_drawsurf.lightadj[1]
- && cache->lightadj[2] == r_drawsurf.lightadj[2]
- && cache->lightadj[3] == r_drawsurf.lightadj[3] )
+ if(cache && !cache->dlight && ms->dlightframe != r_framecount
+ && cache->texture == ds->texture
+ && cache->lightadj[0] == ds->lightadj[0]
+ && cache->lightadj[1] == ds->lightadj[1]
+ && cache->lightadj[2] == ds->lightadj[2]
+ && cache->lightadj[3] == ds->lightadj[3] )
return cache;
// determine shape of surface
surfscale = 1.0 / (1<<miplevel);
- r_drawsurf.surfmip = miplevel;
- r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
- r_drawsurf.rowbytes = r_drawsurf.surfwidth;
- r_drawsurf.surfheight = surface->extents[1] >> miplevel;
+ ds->mip = miplevel;
+ ds->width = ms->extents[0] >> miplevel;
+ ds->height = ms->extents[1] >> miplevel;
// allocate memory if needed
- if (!cache) // if a texture just animated, don't reallocate it
- {
- cache = D_SCAlloc (r_drawsurf.surfwidth,
- r_drawsurf.surfwidth * r_drawsurf.surfheight * sizeof(pixel_t));
- surface->cachespots[miplevel] = cache;
- cache->owner = &surface->cachespots[miplevel];
+ if(cache == nil){ // if a texture just animated, don't reallocate it
+ cache = D_SCAlloc(ds->width, ds->width * ds->height * sizeof(pixel_t));
+ ms->cachespots[miplevel] = cache;
+ cache->owner = &ms->cachespots[miplevel];
cache->mipscale = surfscale;
}
- cache->dlight = surface->dlightframe == r_framecount;
-
- r_drawsurf.surfdat = cache->pixels;
-
- cache->texture = r_drawsurf.texture;
- cache->lightadj[0] = r_drawsurf.lightadj[0];
- cache->lightadj[1] = r_drawsurf.lightadj[1];
- cache->lightadj[2] = r_drawsurf.lightadj[2];
- cache->lightadj[3] = r_drawsurf.lightadj[3];
-
// draw and light the surface texture
- r_drawsurf.surf = surface;
+ cache->dlight = ms->dlightframe == r_framecount;
+ ds->dat = cache->pixels;
+ cache->texture = ds->texture;
+ cache->lightadj[0] = ds->lightadj[0];
+ cache->lightadj[1] = ds->lightadj[1];
+ cache->lightadj[2] = ds->lightadj[2];
+ cache->lightadj[3] = ds->lightadj[3];
+ ds->m = ms;
+ R_DrawSurface(e, ds);
- c_surf++;
- R_DrawSurface(e);
-
- return surface->cachespots[miplevel];
+ return ms->cachespots[miplevel];
}
--- a/r_local.h
+++ b/r_local.h
@@ -188,7 +188,6 @@
extern int r_frustum_indexes[4*6];
extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
-extern bool r_surfsonstack;
extern bool r_dowarpold, r_viewchanged;
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
--- a/r_main.c
+++ b/r_main.c
@@ -16,9 +16,7 @@
mvertex_t *r_pcurrentvertbase;
-int c_surf;
int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
-bool r_surfsonstack;
int r_clipflags;
pixel_t *r_warpbuffer;
--- a/r_surf.c
+++ b/r_surf.c
@@ -1,24 +1,14 @@
#include "quakedef.h"
-drawsurf_t r_drawsurf;
-
-static int sourcetstep;
-static int surfrowbytes; // used by ASM files
-static int r_stepback;
-static pixel_t *r_source, *r_sourcemax;
-static pixel_t *pbasesource;
-static void *prowdestbase;
-
-static unsigned blocklights[3][18*18];
-
/*
===============
R_AddDynamicLights
===============
*/
-void R_AddDynamicLights (entity_t *e)
+static void
+R_AddDynamicLights(entity_t *e, drawsurf_t *ds)
{
- msurface_t *surf;
+ msurface_t *ms;
int lnum;
int sd, td;
float dist, rad, minlight;
@@ -28,55 +18,49 @@
int smax, tmax;
mtexinfo_t *tex;
- surf = r_drawsurf.surf;
- smax = (surf->extents[0]>>4)+1;
- tmax = (surf->extents[1]>>4)+1;
- tex = surf->texinfo;
+ ms = ds->m;
+ smax = (ms->extents[0]>>4)+1;
+ tmax = (ms->extents[1]>>4)+1;
+ tex = ms->texinfo;
- for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
- {
- if ( !(surf->dlightbits & (1<<lnum) ) )
- continue; // not lit by this light
+ for(lnum = 0; lnum < MAX_DLIGHTS; lnum++){
+ if((ms->dlightbits & (1<<lnum)) == 0)
+ continue; // not lit by this light
rad = cl_dlights[lnum].radius;
VectorSubtract(cl_dlights[lnum].origin, e->origin, entorigin);
- dist = DotProduct (entorigin, surf->plane->normal) - surf->plane->dist;
+ dist = DotProduct(entorigin, ms->plane->normal) - ms->plane->dist;
rad -= fabs(dist);
minlight = cl_dlights[lnum].minlight;
- if (rad < minlight)
+ if(rad < minlight)
continue;
minlight = rad - minlight;
- for (i=0 ; i<3 ; i++)
- {
- impact[i] = entorigin[i] -
- surf->plane->normal[i]*dist;
- }
+ for(i = 0; i < 3; i++)
+ impact[i] = entorigin[i] - ms->plane->normal[i]*dist;
- local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
- local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
+ local[0] = DotProduct(impact, tex->vecs[0]) + tex->vecs[0][3];
+ local[1] = DotProduct(impact, tex->vecs[1]) + tex->vecs[1][3];
- local[0] -= surf->texturemins[0];
- local[1] -= surf->texturemins[1];
+ local[0] -= ms->texturemins[0];
+ local[1] -= ms->texturemins[1];
- for (t = 0 ; t<tmax ; t++)
- {
+ for(t = 0; t < tmax; t++){
td = local[1] - t*16;
- if (td < 0)
+ if(td < 0)
td = -td;
- for (s=0 ; s<smax ; s++)
- {
+ for(s = 0; s < smax ; s++){
sd = local[0] - s*16;
- if (sd < 0)
+ if(sd < 0)
sd = -sd;
- if (sd > td)
+ if(sd > td)
dist = sd + (td>>1);
else
dist = td + (sd>>1);
- if (dist < minlight){
- blocklights[0][t*smax + s] += (rad - dist)*256;
- blocklights[1][t*smax + s] += (rad - dist)*256;
- blocklights[2][t*smax + s] += (rad - dist)*256;
+ if(dist < minlight){
+ ds->blocklights[0][t*smax + s] += (rad - dist)*256;
+ ds->blocklights[1][t*smax + s] += (rad - dist)*256;
+ ds->blocklights[2][t*smax + s] += (rad - dist)*256;
}
}
}
@@ -90,7 +74,8 @@
Combine and scale multiple lightmaps into the 8.8 format in blocklights
===============
*/
-void R_BuildLightMap (entity_t *e)
+static void
+R_BuildLightMap(entity_t *e, drawsurf_t *ds)
{
int smax, tmax;
int t;
@@ -98,55 +83,51 @@
byte *lightmap;
unsigned scale;
int maps;
- msurface_t *surf;
+ msurface_t *ms;
- surf = r_drawsurf.surf;
-
- smax = (surf->extents[0]>>4)+1;
- tmax = (surf->extents[1]>>4)+1;
+ ms = ds->m;
+ smax = (ms->extents[0]>>4)+1;
+ tmax = (ms->extents[1]>>4)+1;
size = smax*tmax;
- lightmap = surf->samples;
+ lightmap = ms->samples;
- if (r_fullbright.value || !cl.worldmodel->lightdata)
- {
- memset(blocklights, 0, sizeof(blocklights));
+ if(r_fullbright.value || !cl.worldmodel->lightdata){
+ memset(ds->blocklights, 0, sizeof(ds->blocklights));
return;
}
// clear to ambient
- for (i=0 ; i<size ; i++){
- blocklights[0][i] = r_refdef.ambientlight[0]<<8;
- blocklights[1][i] = r_refdef.ambientlight[1]<<8;
- blocklights[2][i] = r_refdef.ambientlight[2]<<8;
+ for(i = 0; i < size; i++){
+ ds->blocklights[0][i] = r_refdef.ambientlight[0]<<8;
+ ds->blocklights[1][i] = r_refdef.ambientlight[1]<<8;
+ ds->blocklights[2][i] = r_refdef.ambientlight[2]<<8;
}
// add all the lightmaps
- if (lightmap)
- for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
- maps++)
- {
- scale = r_drawsurf.lightadj[maps]; // 8.8 fraction
- for (i=0 ; i<size ; i++){
- blocklights[0][i] += lightmap[i*3+0] * scale;
- blocklights[1][i] += lightmap[i*3+1] * scale;
- blocklights[2][i] += lightmap[i*3+2] * scale;
+ if(lightmap){
+ for(maps = 0; maps < MAXLIGHTMAPS && ms->styles[maps] != 255; maps++){
+ scale = ds->lightadj[maps]; // 8.8 fraction
+ for(i = 0; i < size; i++){
+ ds->blocklights[0][i] += lightmap[i*3+0] * scale;
+ ds->blocklights[1][i] += lightmap[i*3+1] * scale;
+ ds->blocklights[2][i] += lightmap[i*3+2] * scale;
}
lightmap += size * 3; // skip to next lightmap
}
+ }
// add all the dynamic lights
- if (surf->dlightframe == r_framecount)
- R_AddDynamicLights(e);
+ if(ms->dlightframe == r_framecount)
+ R_AddDynamicLights(e, ds);
// bound, invert, and shift
- for (i=0 ; i<size ; i++)
- {
- t = (255*256 - (int)blocklights[0][i]) >> (8 - VID_CBITS);
- blocklights[0][i] = max(t, (1<<6));
- t = (255*256 - (int)blocklights[1][i]) >> (8 - VID_CBITS);
- blocklights[1][i] = max(t, (1<<6));
- t = (255*256 - (int)blocklights[2][i]) >> (8 - VID_CBITS);
- blocklights[2][i] = max(t, (1<<6));
+ for(i = 0; i < size; i++){
+ t = (255*256 - (int)ds->blocklights[0][i]) >> (8 - VID_CBITS);
+ ds->blocklights[0][i] = max(t, (1<<6));
+ t = (255*256 - (int)ds->blocklights[1][i]) >> (8 - VID_CBITS);
+ ds->blocklights[1][i] = max(t, (1<<6));
+ t = (255*256 - (int)ds->blocklights[2][i]) >> (8 - VID_CBITS);
+ ds->blocklights[2][i] = max(t, (1<<6));
}
}
@@ -161,28 +142,23 @@
texture_t *
R_TextureAnimation(entity_t *e, texture_t *base)
{
- int reletive;
- int count;
+ int relative, count;
- if (e->frame)
- {
- if (base->alternate_anims)
- base = base->alternate_anims;
- }
+ if(e->frame && base->alternate_anims)
+ base = base->alternate_anims;
- if (!base->anim_total)
+ if(!base->anim_total)
return base;
- reletive = (int)(cl.time*10) % base->anim_total;
+ relative = (int)(cl.time*10) % base->anim_total;
count = 0;
- while (base->anim_min > reletive || base->anim_max <= reletive)
- {
+ while(base->anim_min > relative || base->anim_max <= relative){
base = base->anim_next;
- if (!base)
- fatal ("R_TextureAnimation: broken cycle");
- if (++count > 100)
- fatal ("R_TextureAnimation: infinite cycle");
+ if(!base)
+ fatal("R_TextureAnimation: broken cycle");
+ if(++count > 100)
+ fatal("R_TextureAnimation: infinite cycle");
}
return base;
@@ -252,7 +228,7 @@
#undef DrawSurfaceBlock_m2
#undef DrawSurfaceBlock_m3
-typedef void (*drawfunc)(unsigned *lp[4], unsigned lw, int nb);
+typedef void (*drawfunc)(pixel_t *psource, pixel_t *prowdest, pixel_t *sourcemax, int deststep, int tstep, int stepback, unsigned *lp[4], unsigned lw, int nb);
static const drawfunc drawsurf[2/*fullbright*/][2/*additive*/][4/*mipmap*/] = {
{
@@ -282,7 +258,8 @@
R_DrawSurface
===============
*/
-void R_DrawSurface (entity_t *e)
+void
+R_DrawSurface(entity_t *e, drawsurf_t *ds)
{
pixel_t *basetptr;
int smax, tmax, twidth, lightwidth;
@@ -292,68 +269,67 @@
int r_numhblocks, r_numvblocks;
pixel_t *pcolumndest;
texture_t *mt;
+ msurface_t *ms;
drawfunc draw;
unsigned *lp[3];
+ int sourcetstep, stepback;
+ pixel_t *source, *sourcemax;
// calculate the lightings
- R_BuildLightMap(e);
+ R_BuildLightMap(e, ds);
- surfrowbytes = r_drawsurf.rowbytes;
+ mt = ds->texture;
+ ms = ds->m;
- mt = r_drawsurf.texture;
+ draw = drawsurf[mt->drawsurf][e != nil && (e->effects & EF_ADDITIVE) != 0][ds->mip];
- draw = drawsurf[mt->drawsurf][e != nil && (e->effects & EF_ADDITIVE) != 0][r_drawsurf.surfmip];
+ source = mt->pixels + mt->offsets[ds->mip];
- r_source = mt->pixels + mt->offsets[r_drawsurf.surfmip];
-
// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
// from a source range of 0 - 255
- texwidth = mt->width >> r_drawsurf.surfmip;
+ texwidth = mt->width >> ds->mip;
- blocksize = 16 >> r_drawsurf.surfmip;
- blockdivshift = 4 - r_drawsurf.surfmip;
+ blocksize = 16 >> ds->mip;
+ blockdivshift = 4 - ds->mip;
- lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
+ lightwidth = (ms->extents[0]>>4)+1;
- r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
- r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
+ r_numhblocks = ds->width >> blockdivshift;
+ r_numvblocks = ds->height >> blockdivshift;
// TODO: only needs to be set when there is a display settings change
horzblockstep = blocksize;
- smax = mt->width >> r_drawsurf.surfmip;
+ smax = mt->width >> ds->mip;
twidth = texwidth;
- tmax = mt->height >> r_drawsurf.surfmip;
+ tmax = mt->height >> ds->mip;
sourcetstep = texwidth;
- r_stepback = tmax * twidth;
+ stepback = tmax * twidth;
+ sourcemax = source + (tmax * smax);
- r_sourcemax = r_source + (tmax * smax);
+ soffset = ms->texturemins[0];
+ basetoffset = ms->texturemins[1];
- soffset = r_drawsurf.surf->texturemins[0];
- basetoffset = r_drawsurf.surf->texturemins[1];
-
// << 16 components are to guarantee positive values for %
- soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
- basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) + (tmax << 16)) % tmax) * twidth)];
+ soffset = ((soffset >> ds->mip) + (smax << 16)) % smax;
+ basetptr = &source[((((basetoffset >> ds->mip) + (tmax << 16)) % tmax) * twidth)];
- pcolumndest = r_drawsurf.surfdat;
+ for(u = 0, pcolumndest = ds->dat; u < r_numhblocks; u++, pcolumndest += horzblockstep){
+ lp[0] = ds->blocklights[0]+u;
+ lp[1] = ds->blocklights[1]+u;
+ lp[2] = ds->blocklights[2]+u;
- for (u=0 ; u<r_numhblocks; u++){
- prowdestbase = pcolumndest;
+ draw(
+ pcolumndest,
+ basetptr+soffset, sourcemax,
+ ds->width, sourcetstep, stepback,
+ lp, lightwidth, r_numvblocks
+ );
- pbasesource = basetptr + soffset;
- lp[0] = blocklights[0]+u;
- lp[1] = blocklights[1]+u;
- lp[2] = blocklights[2]+u;
-
- draw(lp, lightwidth, r_numvblocks);
-
soffset = soffset + blocksize;
- if (soffset >= smax)
+ if(soffset >= smax)
soffset = 0;
-
- pcolumndest += horzblockstep;
}
}
--- a/r_surf_block.h
+++ b/r_surf_block.h
@@ -1,16 +1,12 @@
#define N 3
static void
-DrawSurfaceBlock(unsigned *lp[N], unsigned lw, int nb)
+DrawSurfaceBlock(pixel_t *prowdest, pixel_t *psource, pixel_t *sourcemax, int deststep, int tstep, int stepback, unsigned *lp[N], unsigned lw, int nb)
{
- int b, v, i, j, lightstep[N], light[N], lightleft[N], lightright[N];
+ int b, v, i, j;
+ int lightstep[N], light[N], lightleft[N], lightright[N];
int lightleftstep[N], lightrightstep[N];
- pixel_t *psource, *prowdest;
- psource = pbasesource;
- prowdest = prowdestbase;
-
- for (v=0 ; v<nb ; v++)
- {
+ for(v = 0; v < nb; v++){
for(j = 0; j < N; j++){
lightleft[j] = lp[j][0];
lightright[j] = lp[j][1];
@@ -19,8 +15,7 @@
lightrightstep[j] = (lp[j][1] - lightright[j]) >> (4-mip);
}
- for (i=0 ; i<16>>mip; i++)
- {
+ for(i = 0; i < 16>>mip; i++){
for(j = 0; j < N; j++){
lightstep[j] = (lightleft[j] - lightright[j]) >> (4-mip);
light[j] = lightright[j];
@@ -32,8 +27,8 @@
light[j] += lightstep[j];
}
- psource += sourcetstep;
- prowdest += surfrowbytes;
+ psource += tstep;
+ prowdest += deststep;
for(j = 0; j < N; j++){
lightright[j] += lightrightstep[j];
@@ -41,8 +36,8 @@
}
}
- if (psource >= r_sourcemax)
- psource -= r_stepback;
+ if(psource >= sourcemax)
+ psource -= stepback;
}
}
#undef N