Support for drawing 'island sectors' for TROR/classic (and with limited

functionality, Polymost).

The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.

The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall.  Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).

Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map.  In particular, multiple islands
shouldn't 'see' each other.

Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost.  Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--

Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.

git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-09-15 17:04:14 +00:00
parent 701c69fecc
commit 2415b03c79
5 changed files with 86 additions and 21 deletions

View file

@ -90,6 +90,8 @@ void yax_updategrays(int32_t posze);
# define SECTORS_OF_BUNCH(Bunchnum, Cf, Itervar) Itervar = headsectbunch[Cf][Bunchnum]; \
Itervar != -1; Itervar = nextsectbunch[Cf][Itervar]
extern int32_t r_tror_nomaskpass;
extern int16_t yax_bunchnum[MAXSECTORS][2];
extern int16_t yax_nextwall[MAXWALLS][2];

View file

@ -340,6 +340,9 @@ int32_t baselayer_init(void)
{ "r_novoxmips","r_novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels",(void *) &novoxmips, CVAR_BOOL, 0, 1 },
{ "r_voxels","r_voxels: enable/disable automatic sprite->voxel rendering",(void *) &usevoxels, CVAR_BOOL, 0, 1 },
/* { "r_scrcaptureformat","r_scrcaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars, CVAR_FUNCPTR, 0, 0 },*/
#ifdef YAX_ENABLE
{ "r_tror_nomaskpass", "r_tror_nomaskpass: enable/disable additional pass in TROR software rendering", (void *)&r_tror_nomaskpass, CVAR_BOOL, 0, 1 },
#endif
{ "vid_gamma","vid_gamma <gamma>: adjusts gamma ramp",(void *) &vid_gamma, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_contrast","vid_contrast <gamma>: adjusts gamma ramp",(void *) &vid_contrast, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },
{ "vid_brightness","vid_brightness <gamma>: adjusts gamma ramp",(void *) &vid_brightness, CVAR_DOUBLE|CVAR_FUNCPTR, 0, 10 },

View file

@ -261,7 +261,8 @@ void yax_updategrays(int32_t posze)
int32_t g_nodraw = 0;
int32_t scansector_retfast = 0;
static int32_t scansector_collectsprites = 1;
static int32_t yax_globalcf = -1, yax_nomaskpass=0;
int32_t yax_globalcf = -1, yax_nomaskpass=0, yax_nomaskdidit; // engine internal
int32_t r_tror_nomaskpass = 1; // cvar
int32_t yax_globallev = YAX_MAXDRAWS;
int32_t yax_globalbunch = -1;
@ -273,6 +274,9 @@ int32_t yax_globalbunch = -1;
static int16_t yax_spritesortcnt[1 + 2*YAX_MAXDRAWS];
static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN];
// drawn sectors
uint8_t yax_gotsector[MAXSECTORS>>3]; // engine internal
// game-time YAX data structures
int16_t yax_bunchnum[MAXSECTORS][2];
int16_t yax_nextwall[MAXWALLS][2];
@ -282,11 +286,6 @@ static int32_t yax_islockededge(int32_t line, int32_t cf)
return !!(wall[line].cstat&(YAX_NEXTWALLBIT(cf)));
}
static int32_t yax_isislandwall(int32_t line, int32_t cf)
{
return (yax_vnextsec(line, cf)>=0);
}
#define YAX_BUNCHNUM(Sect, Cf) (*(&sector[Sect].ceilingxpanning + 8*Cf))
//// bunch getters/setters
@ -758,7 +757,7 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
{
static uint8_t havebunch[YAX_MAXBUNCHES>>3];
int32_t i, j, k, lev, cf;
int32_t i, j, k, lev, cf, nmp;
int32_t bnchcnt, bnchnum[2] = {0,0}, maxlev[2];
int16_t ourbunch[2] = {-1,-1}, osectnum=sectnum;
int32_t bnchbeg[YAX_MAXDRAWS][2], bnchend[YAX_MAXDRAWS][2];
@ -865,8 +864,8 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
for (i=0; i<(numsectors+7)>>3; i++)
lgotsector[i] |= gotsector[i];
yaxdebug("%s, l %d: faked sec %3d (bunch %2d),%3d dspr, ob=[%2d,%2d], sn=%3d,%3d ms",
cf?"v":"^", lev, k, j, yax_spritesortcnt[yax_globallev],
yaxdebug("l%d: faked sec %3d (bunch %2d),%3d dspr, ob=[%2d,%2d], sn=%3d,%3d ms",
yax_globallev-YAX_MAXDRAWS, k, j, yax_spritesortcnt[yax_globallev],
ourbunch[0],ourbunch[1],sectnum,getticks()-t);
}
@ -941,13 +940,28 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
if (k < 0)
continue;
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force
yax_nomaskdidit = 0;
for (nmp=r_tror_nomaskpass; nmp>=0; nmp--)
{
yax_nomaskpass = nmp;
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force
yaxdebug("l%d nm%d: DRAWN sec %3d (bn %2d),%3d tspr,%3d ms",
yax_globallev-YAX_MAXDRAWS, nmp, k, j, spritesortcnt, getticks()-t);
if (nmp==1)
{
if (!yax_nomaskdidit)
{
yax_nomaskpass = 0;
break; // no need to draw the same stuff twice
}
Bmemcpy(yax_gotsector, gotsector, (numsectors+7)>>3);
}
}
yax_copytsprite(j, !scansector_collectsprites);
yaxdebug("%s, l %d: DRAWN sec %3d (bunch %2d),%3d tspr,%3d ms",
cf?"v":"^", lev, k, j, spritesortcnt, getticks()-t);
ExtAnalyzeSprites();
drawmasks();
}
@ -961,7 +975,7 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
#ifdef YAX_DEBUG
t=getticks();
#endif
yax_globalcf = -1; // remove?
yax_globalcf = -1;
yax_globalbunch = -1;
yax_globallev = YAX_MAXDRAWS;
scansector_collectsprites = 0;
@ -2029,7 +2043,7 @@ static int32_t smostcnt;
static int16_t smost[MAXYSAVES];
static int16_t smoststart[MAXWALLSB];
static char smostwalltype[MAXWALLSB];
static int32_t smostwall[MAXWALLSB], smostwallcnt = -1L;
static int32_t smostwall[MAXWALLSB], smostwallcnt = -1;
int16_t maskwall[MAXWALLSB], maskwallcnt;
static int32_t spritesx[MAXSPRITESONSCREEN];
@ -2201,16 +2215,24 @@ int32_t engine_addtsprite(int16_t z, int16_t sectnum)
if (g_nodraw==0)
{
if (numyaxbunches==0)
{
#endif
if (spritesortcnt >= MAXSPRITESONSCREEN)
return 1;
copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype));
spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt];
tsprite[spritesortcnt++].owner = z;
if (spritesortcnt >= MAXSPRITESONSCREEN)
return 1;
copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype));
spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt];
tsprite[spritesortcnt++].owner = z;
#ifdef YAX_ENABLE
}
}
else
#ifdef YAX_ENABLE
if (yax_nomaskpass==0)
#endif
{
sortcnt = &yax_spritesortcnt[yax_globallev];
if (*sortcnt >= MAXSPRITESONSCREEN)
@ -2307,6 +2329,9 @@ static void scansector(int16_t sectnum)
x2 = wal2->x-globalposx; y2 = wal2->y-globalposy;
if ((nextsectnum >= 0) && ((wal->cstat&32) == 0))
#ifdef YAX_ENABLE
if (yax_nomaskpass==0 || !yax_isislandwall(z, !yax_globalcf) || (yax_nomaskdidit=1, 0))
#endif
if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)
{
tempint = x1*y2-x2*y1;
@ -4336,6 +4361,11 @@ static void drawalls(int32_t bunch)
#endif
{
if ((andwstat1&3) != 3) //draw ceilings
#ifdef YAX_ENABLE
// this is to prevent double-drawing of translucent masked ceilings
if (r_tror_nomaskpass==0 || yax_globallev==YAX_MAXDRAWS || (sec->ceilingstat&256)==0 ||
yax_nomaskpass==1 || !(yax_gotsector[sectnum>>3]&(1<<(sectnum&7))))
#endif
{
if ((sec->ceilingstat&3) == 2)
grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0);
@ -4344,6 +4374,12 @@ static void drawalls(int32_t bunch)
else
parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch);
}
#ifdef YAX_ENABLE
// this is to prevent double-drawing of translucent masked floors
if (r_tror_nomaskpass==0 || yax_globallev==YAX_MAXDRAWS || (sec->floorstat&256)==0 ||
yax_nomaskpass==1 || !(yax_gotsector[sectnum>>3]&(1<<(sectnum&7))))
#endif
if ((andwstat2&12) != 12) //draw floors
{
if ((sec->floorstat&3) == 2)
@ -4395,6 +4431,9 @@ static void drawalls(int32_t bunch)
}
}
#ifdef YAX_ENABLE
if (yax_nomaskpass==0 || !yax_isislandwall(wallnum, !yax_globalcf) || (yax_nomaskdidit=1, 0))
#endif
if (nextsectnum >= 0)
{
getzsofslope((int16_t)sectnum,wal->x,wal->y,&cz[0],&fz[0]);
@ -4496,6 +4535,7 @@ static void drawalls(int32_t bunch)
}
}
}
if (((sec->floorstat&1) == 0) || ((nextsec->floorstat&1) == 0))
{
if ((fz[2] >= fz[0]) && (fz[3] >= fz[1]))
@ -4604,6 +4644,7 @@ static void drawalls(int32_t bunch)
}
}
}
if (numhits < 0) return;
if ((!(wal->cstat&32)) && ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0))
{
@ -4706,7 +4747,7 @@ static void drawalls(int32_t bunch)
if (!g_nodraw)
#endif
{
static char fn[BMAX_PATH];
static char fn[32], tmpbuf[80];
static char bakframe[MAXXDIM*MAXYDIM];
char purple = getclosestcol(63, 0, 63);
@ -4730,6 +4771,10 @@ static void drawalls(int32_t bunch)
*((char *)frameplace + (dmost[x]-1)*bytesperline + x) = yellow;
}
Bsprintf(tmpbuf, "nmp%d l%d b%d s%d w%d", yax_nomaskpass, yax_globallev-YAX_MAXDRAWS,
yax_globalbunch, sectnum, wallnum);
printext256(8,8, whitecol,0, tmpbuf, 0);
Bsprintf(fn, "engshot%04d.png", engine_screenshot);
screencapture(fn, 0, "BUILD engine");
engine_screenshot++;

View file

@ -79,7 +79,14 @@ int32_t engine_addtsprite(int16_t z, int16_t sectnum);
#ifdef YAX_ENABLE
extern int32_t g_nodraw, scansector_retfast;
extern int32_t yax_globallev, yax_globalbunch;
extern int32_t yax_globalcf, yax_nomaskpass, yax_nomaskdidit;
extern uint8_t haveymost[YAX_MAXBUNCHES>>3];
extern uint8_t yax_gotsector[MAXSECTORS>>3];
static inline int32_t yax_isislandwall(int32_t line, int32_t cf)
{
return (yax_vnextsec(line, cf)>=0);
}
#endif
#ifdef YAX_DEBUG

View file

@ -3321,6 +3321,11 @@ static void polymost_drawalls(int32_t bunch)
nextsectnum = wal->nextsector;
nextsec = nextsectnum>=0 ? &sector[nextsectnum] : NULL;
#ifdef YAX_ENABLE
if (yax_nomaskpass==1 && yax_isislandwall(wallnum, !yax_globalcf) && (yax_nomaskdidit=1))
continue;
#endif
//Offset&Rotate 3D coordinates to screen 3D space
x = wal->x-globalposx; y = wal->y-globalposy;
xp0 = (double)y*gcosang - (double)x*gsinang;
@ -4228,6 +4233,9 @@ void polymost_scansector(int32_t sectnum)
x2 = wal2->x-globalposx; y2 = wal2->y-globalposy;
nextsectnum = wal->nextsector; //Scan close sectors
#ifdef YAX_ENABLE
if (yax_nomaskpass==0 || !yax_isislandwall(z, !yax_globalcf) || (yax_nomaskdidit=1, 0))
#endif
if ((nextsectnum >= 0) && (!(wal->cstat&32)) && (!(gotsector[nextsectnum>>3]&pow2char[nextsectnum&7])))
{
d = (double)x1*(double)y2 - (double)x2*(double)y1; xp1 = (double)(x2-x1); yp1 = (double)(y2-y1);