Merged mirrors with portals; Render part of mirrors done, render part of portals needs further testing

This commit is contained in:
ZZYZX 2014-12-16 18:08:48 +02:00
commit cd39c4b8a6
15 changed files with 349 additions and 124 deletions

View file

@ -317,6 +317,44 @@ nextpost:
}
}
// [ZZ]
// R_ClipSpriteColumnWithPortals
//
bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprite_t* spr)
{
size_t numdrawsegs = ds_p-firstdrawseg;
for (int i = (int)numdrawsegs-1; i >= 0; i--)
{
drawseg_t* seg = &firstdrawseg[i];
// ignore segs from other portals
if (seg->CurrentPortalUniq != CurrentPortalUniq)
continue;
line_t* line = seg->curline->linedef;
// divline? wtf, anyway, divlines aren't supposed to be drawn. But I definitely saw NULL linedefs in drawsegs.
if (!line) continue;
// check if this line will clip sprites to itself
if (!line->portal)
continue;
// don't clip sprites with portal's back side (it's transparent)
if (seg->curline->sidedef != line->sidedef[0])
continue;
// don't clip if the sprite is in front of the portal
if (!P_PointOnLineSide(x, y, line))
continue;
// now if current column is covered by this drawseg, we clip it away
if ((dc_x >= seg->x1) && (dc_x <= seg->x2))
return true;
}
return false;
}
//
// R_DrawVisSprite
// mfloorclip and mceilingclip should also be set.
@ -330,6 +368,7 @@ void R_DrawVisSprite (vissprite_t *vis)
int x2, stop4;
fixed_t xiscale;
ESPSResult mode;
bool ispsprite = (!vis->sector && !vis->gx && !vis->gy && !vis->gz);
dc_colormap = vis->Style.colormap;
@ -373,7 +412,8 @@ void R_DrawVisSprite (vissprite_t *vis)
while ((dc_x < stop4) && (dc_x & 3))
{
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
R_DrawMaskedColumn (pixels, spans);
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis->gx, vis->gy, vis))
R_DrawMaskedColumn (pixels, spans);
dc_x++;
frac += xiscale;
}
@ -384,7 +424,8 @@ void R_DrawVisSprite (vissprite_t *vis)
for (int zz = 4; zz; --zz)
{
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
R_DrawMaskedColumnHoriz (pixels, spans);
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis->gx, vis->gy, vis))
R_DrawMaskedColumnHoriz (pixels, spans);
dc_x++;
frac += xiscale;
}
@ -394,7 +435,8 @@ void R_DrawVisSprite (vissprite_t *vis)
while (dc_x < x2)
{
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
R_DrawMaskedColumn (pixels, spans);
if (ispsprite || !R_ClipSpriteColumnWithPortals(vis->gx, vis->gy, vis))
R_DrawMaskedColumn (pixels, spans);
dc_x++;
frac += xiscale;
}
@ -504,7 +546,8 @@ void R_DrawWallSprite(vissprite_t *spr)
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT);
}
R_WallSpriteColumn(R_DrawMaskedColumn);
if (!R_ClipSpriteColumnWithPortals(spr->gx, spr->gy, spr))
R_WallSpriteColumn(R_DrawMaskedColumn);
dc_x++;
}
@ -517,7 +560,8 @@ void R_DrawWallSprite(vissprite_t *spr)
rt_initcols();
for (int zz = 4; zz; --zz)
{
R_WallSpriteColumn(R_DrawMaskedColumnHoriz);
if (!R_ClipSpriteColumnWithPortals(spr->gx, spr->gy, spr))
R_WallSpriteColumn(R_DrawMaskedColumnHoriz);
dc_x++;
}
rt_draw4cols(dc_x - 4);
@ -529,7 +573,8 @@ void R_DrawWallSprite(vissprite_t *spr)
{ // calculate lighting
dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT);
}
R_WallSpriteColumn(R_DrawMaskedColumn);
if (!R_ClipSpriteColumnWithPortals(spr->gx, spr->gy, spr))
R_WallSpriteColumn(R_DrawMaskedColumn);
dc_x++;
}
}
@ -669,6 +714,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
return;
}
// [ZZ] Or less definitely not visible (hue)
if (CurrentPortal && !!P_PointOnLineSide(thing->x, thing->y, CurrentPortal->dst))
return;
// [RH] Interpolate the sprite's position to make it look smooth
fx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX);
fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY);
@ -886,6 +935,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
// store information in a vissprite
vis = R_NewVisSprite();
vis->CurrentPortalUniq = CurrentPortalUniq;
vis->xscale = xscale;
vis->yscale = Scale(InvZtoScale, yscale, tz << 4);
vis->idepth = (unsigned)DivScale32(1, tz) >> 1; // tz is 20.12, so idepth ought to be 12.20, but signed math makes it 13.19
@ -913,6 +963,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
{
vis = R_NewVisSprite();
vis->CurrentPortalUniq = CurrentPortalUniq;
vis->xscale = xscale;
vis->yscale = yscale;
vis->x1 = WindowLeft;
@ -1074,6 +1125,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f
gzb = fz + yscale * scaled_bo;
vis = R_NewVisSprite();
vis->CurrentPortalUniq = CurrentPortalUniq;
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2-1;
vis->yscale = yscale;
@ -1774,7 +1826,6 @@ void R_SortVisSprites (bool (*compare)(vissprite_t *, vissprite_t *), size_t fir
std::stable_sort(&spritesorter[0], &spritesorter[vsprcount], compare);
}
//
// R_DrawSprite
//
@ -2069,8 +2120,11 @@ void R_DrawSprite (vissprite_t *spr)
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
{
// [ZZ] portal handling here
if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
continue;
// kg3D - no clipping on fake segs
if(ds->fake) continue;
if (ds->fake) continue;
// determine if the drawseg obscures the sprite
if (ds->x1 > x2 || ds->x2 < x1 ||
(!(ds->silhouette & SIL_BOTH) && ds->maskedtexturecol == -1 &&
@ -2205,6 +2259,8 @@ void R_DrawMaskedSingle (bool renew)
for (i = vsprcount; i > 0; i--)
{
if (spritesorter[i-1]->CurrentPortalUniq != CurrentPortalUniq)
continue; // probably another time
R_DrawSprite (spritesorter[i-1]);
}
@ -2222,6 +2278,9 @@ void R_DrawMaskedSingle (bool renew)
}
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
{
// [ZZ] the same as above
if (ds->CurrentPortalUniq != CurrentPortalUniq)
continue;
// kg3D - no fake segs
if (ds->fake) continue;
if (ds->maskedtexturecol != -1 || ds->bFogBoundary)
@ -2301,6 +2360,10 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
sector_t* heightsec = NULL;
BYTE* map;
// [ZZ] Particle not visible through the portal plane
if (CurrentPortal && !!P_PointOnLineSide(particle->x, particle->y, CurrentPortal->dst))
return;
// transform the origin point
tr_x = particle->x - viewx;
tr_y = particle->y - viewy;
@ -2404,6 +2467,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
// store information in a vissprite
vis = R_NewVisSprite ();
vis->CurrentPortalUniq = CurrentPortalUniq;
vis->heightsec = heightsec;
vis->xscale = xscale;
// vis->yscale = FixedMul (xscale, InvZtoScale);
@ -2456,8 +2520,11 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
for (unsigned int p = InterestingDrawsegs.Size(); p-- > FirstInterestingDrawseg; )
{
drawseg_t *ds = &drawsegs[InterestingDrawsegs[p]];
// [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves
if (ds->CurrentPortalUniq != vis->CurrentPortalUniq)
continue;
// kg3D - no fake segs
if(ds->fake) continue;
if (ds->fake) continue;
if (ds->x1 >= x2 || ds->x2 < x1)
{
continue;
@ -2495,6 +2562,8 @@ void R_DrawParticle (vissprite_t *vis)
fg = fg2rgb[color];
}
/*
spacing = RenderTarget->GetPitch() - countbase;
dest = ylookup[yl] + x1 + dc_destorg;
@ -2508,7 +2577,28 @@ void R_DrawParticle (vissprite_t *vis)
*dest++ = RGB32k.All[bg & (bg>>15)];
} while (--count);
dest += spacing;
} while (--ycount);
} while (--ycount);*/
// original was row-wise
// width = countbase
// height = ycount
spacing = RenderTarget->GetPitch();
for (int x = x1; x < (x1+countbase); x++)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis->gx, vis->gy, vis))
continue;
dest = ylookup[yl] + x + dc_destorg;
for (int y = 0; y < ycount; y++)
{
DWORD bg = bg2rgb[*dest];
bg = (fg+bg) | 0x1f07c1f;
*dest = RGB32k[0][0][bg & (bg>>15)];
dest += spacing;
}
}
}
extern fixed_t baseyaspectmul;