Skip to content
Permalink
Browse files

- change ProjectedWallTexcoords to use gradients for its texture coor…

…dinate calculations

- change SpriteDrawerArgs to draw a full sprite instead of one column at a time
- add r_noaccel cvar to allow forced software rendering of the psprites (useful for debugging and also one person on the forum actually requested this feature)
- remove FWallTmapVals and calculate texture coordinates directly from FWallCoords
- move portal clipping out of the inner sprite drawing loop
  • Loading branch information
dpjudas committed Nov 20, 2019
1 parent 1085287 commit 236b476933abab139f6ec0eb4672af96b7817952
@@ -81,7 +81,7 @@ namespace swrenderer
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
return;

if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12)))
if (WallC.Init(Thread, pt1, pt2, line))
return;

RenderPortal *renderportal = Thread->Portal.get();
@@ -87,7 +87,7 @@ namespace swrenderer
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
return;

if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12)))
if (WallC.Init(Thread, pt1, pt2, line))
return;

RenderPortal *renderportal = Thread->Portal.get();
@@ -108,8 +108,6 @@ namespace swrenderer
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos))
return;

WallT.InitFromLine(Thread, line);

mFrontCeilingZ1 = mFrontSector->ceilingplane.ZatPoint(line->v1);
mFrontFloorZ1 = mFrontSector->floorplane.ZatPoint(line->v1);
mFrontCeilingZ2 = mFrontSector->ceilingplane.ZatPoint(line->v2);
@@ -306,7 +304,6 @@ namespace swrenderer

draw_segment->drawsegclip.CurrentPortalUniq = renderportal->CurrentPortalUniq;
draw_segment->WallC = WallC;
draw_segment->tmapvals = WallT;
draw_segment->x1 = start;
draw_segment->x2 = stop;
draw_segment->curline = mLineSegment;
@@ -396,7 +393,7 @@ namespace swrenderer
if (pic)
{
draw_segment->SetHasTranslucentMidTexture();
draw_segment->texcoords.ProjectTranslucent(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, pic);
draw_segment->texcoords.ProjectTranslucent(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, pic);
draw_segment->drawsegclip.silhouette |= SIL_TOP | SIL_BOTTOM;
}
}
@@ -878,7 +875,7 @@ namespace swrenderer
if (!viewactive) return;

ProjectedWallTexcoords texcoords;
texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mTopTexture);
texcoords.ProjectTop(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mTopTexture);

RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mTopTexture, x1, x2, walltop.ScreenY, wallupper.ScreenY, texcoords, false, false, OPAQUE);
@@ -890,7 +887,7 @@ namespace swrenderer
if (!viewactive) return;

ProjectedWallTexcoords texcoords;
texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mMiddleTexture);
texcoords.ProjectMid(Thread->Viewport.get(), mFrontSector, mLineSegment, WallC, mMiddleTexture);

RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mMiddleTexture, x1, x2, walltop.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
@@ -903,85 +900,9 @@ namespace swrenderer
if (!viewactive) return;

ProjectedWallTexcoords texcoords;
texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC.sx1, WallC.sx2, WallT, mBottomTexture);
texcoords.ProjectBottom(Thread->Viewport.get(), mFrontSector, mBackSector, mLineSegment, WallC, mBottomTexture);

RenderWallPart renderWallpart(Thread);
renderWallpart.Render(mFrontSector, mLineSegment, WallC, mBottomTexture, x1, x2, walllower.ScreenY, wallbottom.ScreenY, texcoords, false, false, OPAQUE);
}

////////////////////////////////////////////////////////////////////////////

// Transform and clip coordinates. Returns true if it was clipped away
bool FWallCoords::Init(RenderThread *thread, const DVector2 &pt1, const DVector2 &pt2, double too_close)
{
auto viewport = thread->Viewport.get();
RenderPortal *renderportal = thread->Portal.get();

tleft.X = float(pt1.X * viewport->viewpoint.Sin - pt1.Y * viewport->viewpoint.Cos);
tright.X = float(pt2.X * viewport->viewpoint.Sin - pt2.Y * viewport->viewpoint.Cos);

tleft.Y = float(pt1.X * viewport->viewpoint.TanCos + pt1.Y * viewport->viewpoint.TanSin);
tright.Y = float(pt2.X * viewport->viewpoint.TanCos + pt2.Y * viewport->viewpoint.TanSin);

if (renderportal->MirrorFlags & RF_XFLIP)
{
float t = -tleft.X;
tleft.X = -tright.X;
tright.X = t;
swapvalues(tleft.Y, tright.Y);
}

float fsx1, fsz1, fsx2, fsz2;

if (tleft.X >= -tleft.Y)
{
if (tleft.X > tleft.Y) return true; // left edge is off the right side
if (tleft.Y == 0) return true;
fsx1 = viewport->CenterX + tleft.X * viewport->CenterX / tleft.Y;
fsz1 = tleft.Y;
}
else
{
if (tright.X < -tright.Y) return true; // wall is off the left side
float den = tleft.X - tright.X - tright.Y + tleft.Y;
if (den == 0) return true;
fsx1 = 0;
fsz1 = tleft.Y + (tright.Y - tleft.Y) * (tleft.X + tleft.Y) / den;
}

if (fsz1 < too_close)
return true;

if (tright.X <= tright.Y)
{
if (tright.X < -tright.Y) return true; // right edge is off the left side
if (tright.Y == 0) return true;
fsx2 = viewport->CenterX + tright.X * viewport->CenterX / tright.Y;
fsz2 = tright.Y;
}
else
{
if (tleft.X > tleft.Y) return true; // wall is off the right side
float den = tright.Y - tleft.Y - tright.X + tleft.X;
if (den == 0) return true;
fsx2 = viewwidth;
fsz2 = tleft.Y + (tright.Y - tleft.Y) * (tleft.X - tleft.Y) / den;
}

if (fsz2 < too_close)
return true;

sx1 = xs_RoundToInt(fsx1);
sx2 = xs_RoundToInt(fsx2);

float delta = fsx2 - fsx1;
float t1 = (sx1 + 0.5f - fsx1) / delta;
float t2 = (sx2 + 0.5f - fsx1) / delta;
float invZ1 = 1.0f / fsz1;
float invZ2 = 1.0f / fsz2;
sz1 = 1.0f / (invZ1 * (1.0f - t1) + invZ2 * t1);
sz2 = 1.0f / (invZ1 * (1.0f - t2) + invZ2 * t2);

return sx2 <= sx1;
}
}
@@ -39,17 +39,6 @@ namespace swrenderer
class RenderThread;
struct VisiblePlane;

struct FWallCoords
{
FVector2 tleft; // coords at left of wall in view space rx1,ry1
FVector2 tright; // coords at right of wall in view space rx2,ry2

float sz1, sz2; // depth at left, right of wall in screen space yb1,yb2
short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2

bool Init(RenderThread *thread, const DVector2 &pt1, const DVector2 &pt2, double too_close);
};

class SWRenderLine : VisibleSegmentRenderer
{
public:
@@ -107,7 +96,6 @@ namespace swrenderer
bool mDoorClosed;

FWallCoords WallC;
FWallTmapVals WallT;

// Wall segment variables:

@@ -218,7 +218,7 @@ namespace swrenderer
walllower.ClipBottom(x1, x2, ds->drawsegclip);

ProjectedWallTexcoords walltexcoords;
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC.sx1, ds->WallC.sx2, ds->tmapvals, rw_pic);
walltexcoords.Project3DFloor(Thread->Viewport.get(), rover, curline, ds->WallC, rw_pic);

RenderWallPart renderWallpart(Thread);
renderWallpart.Render(lightsector, curline, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha);

0 comments on commit 236b476

Please sign in to comment.
You can’t perform that action at this time.