Remove the ProjectedWallTexcoords arrays

This commit is contained in:
Magnus Norddahl 2019-11-09 03:16:48 +01:00
parent 370c185415
commit 5c21a6c973
8 changed files with 76 additions and 156 deletions

View file

@ -427,7 +427,9 @@ namespace swrenderer
xoffset = xs_RoundToInt(xoffset * lwallscale);
}
draw_segment->texcoords.Set(Thread, walltexcoords, start, stop, xoffset, yscale);
draw_segment->texcoords = walltexcoords;
draw_segment->texcoords.xoffset = xoffset;
draw_segment->texcoords.yscale = yscale;
}
draw_segment->light = mLight.GetLightPos(start);

View file

@ -54,7 +54,7 @@
namespace swrenderer
{
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
void RenderWallPart::ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords)
{
if (rw_pic == nullptr)
return;
@ -114,12 +114,12 @@ namespace swrenderer
if (!fixed)
drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x]));
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(texcoords.UPos(x + 1)) - FIXED2DBL(texcoords.UPos(x)));
fixed_t xxoffset = (lwal[x] + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
fixed_t xxoffset = (texcoords.UPos(x) + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
// Normalize to 0-1 range:
double uv_stepd = swal[x] * yrepeat;
double uv_stepd = texcoords.VStep(x) * yrepeat;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
v = v - floor(v);
double v_step = uv_stepd / rw_pic->GetHeight();
@ -227,18 +227,18 @@ namespace swrenderer
if (!fixed)
drawerargs.SetLight(curlight, mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x]));
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(texcoords.UPos(x + 1)) - FIXED2DBL(texcoords.UPos(x)));
uint32_t uv_pos;
uint32_t uv_step;
fixed_t xxoffset = (lwal[x] + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
fixed_t xxoffset = (texcoords.UPos(x) + xoffset + FLOAT2FIXED(xmagnitude * 0.5)) * rw_pic->GetPhysicalScale();
if (uv_fracbits != 32)
{
// Find start uv in [0-base_height[ range.
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
double uv_stepd = swal[x] * yrepeat;
double uv_stepd = texcoords.VStep(x) * yrepeat;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / rw_pic->GetHeight();
v = v - floor(v);
v *= height;
@ -410,7 +410,7 @@ namespace swrenderer
}
}
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
void RenderWallPart::ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords)
{
ProjectedWallLine most1, most2, most3;
const short *up;
@ -434,7 +434,7 @@ namespace swrenderer
{
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
}
ProcessNormalWall(up, down, texturemid, swal, lwal);
ProcessNormalWall(up, down, texturemid, texcoords);
up = down;
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
}
@ -442,19 +442,19 @@ namespace swrenderer
mLight.SetColormap(frontsector, curline, &frontsector->e->XFloor.lightlist[i]);
}
ProcessNormalWall(up, dwal, texturemid, swal, lwal);
ProcessNormalWall(up, dwal, texturemid, texcoords);
}
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal)
void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords)
{
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0 || !(frontsector->e && frontsector->e->XFloor.lightlist.Size()))
{
ProcessNormalWall(uwal, dwal, texturemid, swal, lwal);
ProcessNormalWall(uwal, dwal, texturemid, texcoords);
}
else
{
ProcessStripedWall(uwal, dwal, texturemid, swal, lwal);
ProcessStripedWall(uwal, dwal, texturemid, texcoords);
}
}
@ -469,7 +469,7 @@ namespace swrenderer
//
//=============================================================================
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal, double top, double bot)
void RenderWallPart::ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords, double top, double bot)
{
ProjectedWallLine most1, most2, most3;
double texheight = rw_pic->GetHeight();
@ -495,14 +495,14 @@ namespace swrenderer
{
down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]);
}
ProcessWall(up, down, texturemid, swal, lwal);
ProcessWall(up, down, texturemid, texcoords);
up = down;
down = (down == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
}
partition -= scaledtexheight;
texturemid -= texheight;
}
ProcessWall(up, dwal, texturemid, swal, lwal);
ProcessWall(up, dwal, texturemid, texcoords);
}
else
{ // upside down: draw strips from bottom to top
@ -519,14 +519,14 @@ namespace swrenderer
{
up[j] = clamp(most3.ScreenY[j], uwal[j], down[j]);
}
ProcessWall(up, down, texturemid, swal, lwal);
ProcessWall(up, down, texturemid, texcoords);
down = up;
up = (up == most1.ScreenY) ? most2.ScreenY : most1.ScreenY;
}
partition -= scaledtexheight;
texturemid -= texheight;
}
ProcessWall(uwal, down, texturemid, swal, lwal);
ProcessWall(uwal, down, texturemid, texcoords);
}
}
@ -550,39 +550,11 @@ namespace swrenderer
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits())
{
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos, top, bottom);
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords, top, bottom);
}
else
{
ProcessWall(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos);
}
}
void RenderWallPart::Render(sector_t* frontsector, seg_t* curline, const FWallCoords& WallC, FSoftwareTexture* pic, int x1, int x2, const short* walltop, const short* wallbottom, double texturemid, const DrawSegmentWallTexcoords& texcoords, double yscale, double top, double bottom, bool mask, bool additive, fixed_t alpha, fixed_t xoffset, const ProjectedWallLight& light, FLightNode* light_list)
{
this->x1 = x1;
this->x2 = x2;
this->frontsector = frontsector;
this->curline = curline;
this->WallC = WallC;
this->yrepeat = yscale;
this->mLight = light;
this->xoffset = xoffset;
this->light_list = light_list;
this->rw_pic = pic;
this->mask = mask;
this->additive = additive;
this->alpha = alpha;
Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits())
{
ProcessWallNP2(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos, top, bottom);
}
else
{
ProcessWall(walltop, wallbottom, texturemid, texcoords.VStep, texcoords.UPos);
ProcessWall(walltop, wallbottom, texturemid, texcoords);
}
}

View file

@ -66,34 +66,13 @@ namespace swrenderer
const ProjectedWallLight &light,
FLightNode *light_list);
void Render(
sector_t* frontsector,
seg_t* curline,
const FWallCoords& WallC,
FSoftwareTexture* rw_pic,
int x1,
int x2,
const short* walltop,
const short* wallbottom,
double texturemid,
const DrawSegmentWallTexcoords& texcoords,
double yscale,
double top,
double bottom,
bool mask,
bool additive,
fixed_t alpha,
fixed_t xoffset,
const ProjectedWallLight& light,
FLightNode* light_list);
RenderThread *Thread = nullptr;
private:
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal, double top, double bot);
void ProcessWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const float *swal, const fixed_t *lwal);
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords, double top, double bot);
void ProcessWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords);
void ProcessStripedWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords);
void ProcessNormalWall(const short *uwal, const short *dwal, double texturemid, const ProjectedWallTexcoords& texcoords);
void SetLights(WallDrawerArgs &drawerargs, int x, int y1);
int x1 = 0;

View file

@ -223,65 +223,53 @@ namespace swrenderer
void ProjectedWallTexcoords::Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx)
{
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - viewport->CenterX);
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - viewport->CenterX);
this->walxrepeat = walxrepeat;
this->x1 = x1;
this->x2 = x2;
this->WallT = WallT;
CenterX = viewport->CenterX;
WallTMapScale2 = viewport->WallTMapScale2;
valid = true;
}
float ProjectedWallTexcoords::VStep(int x) const
{
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - CenterX);
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX);
float uGradient = WallT.UoverZstep;
float zGradient = WallT.InvZstep;
float xrepeat = (float)fabs(walxrepeat);
float depthScale = (float)(WallT.InvZstep * viewport->WallTMapScale2);
float depthOrg = (float)(-WallT.UoverZstep * viewport->WallTMapScale2);
float depthScale = (float)(WallT.InvZstep * WallTMapScale2);
float depthOrg = (float)(-WallT.UoverZstep * WallTMapScale2);
float u = (uOverZ + uGradient * (x - x1)) / (invZ + zGradient * (x - x1));
return depthOrg + u * depthScale;
}
fixed_t ProjectedWallTexcoords::UPos(int x) const
{
float uOverZ = WallT.UoverZorg + WallT.UoverZstep * (float)(x1 + 0.5 - CenterX);
float invZ = WallT.InvZorg + WallT.InvZstep * (float)(x1 + 0.5 - CenterX);
float uGradient = WallT.UoverZstep;
float zGradient = WallT.InvZstep;
float u = (uOverZ + uGradient * (x - x1)) / (invZ + zGradient * (x - x1));
fixed_t value;
if (walxrepeat < 0.0)
{
for (int x = x1; x < x2; x++)
{
float u = uOverZ / invZ;
UPos[x] = (fixed_t)((xrepeat - u * xrepeat) * FRACUNIT);
VStep[x] = depthOrg + u * depthScale;
uOverZ += uGradient;
invZ += zGradient;
}
float xrepeat = -walxrepeat;
value = (fixed_t)((xrepeat - u * xrepeat) * FRACUNIT);
}
else
{
for (int x = x1; x < x2; x++)
{
float u = uOverZ / invZ;
UPos[x] = (fixed_t)(u * xrepeat * FRACUNIT);
VStep[x] = depthOrg + u * depthScale;
uOverZ += uGradient;
invZ += zGradient;
}
value = (fixed_t)(u * walxrepeat * FRACUNIT);
}
if (flipx)
{
int right = (int)walxrepeat - 1;
for (int i = x1; i < x2; i++)
{
UPos[i] = right - UPos[i];
}
}
}
/////////////////////////////////////////////////////////////////////////
void DrawSegmentWallTexcoords::Set(RenderThread* thread, const ProjectedWallTexcoords& texcoords, int x1, int x2, fixed_t xoffset, double yscale)
{
UPos = thread->FrameMemory->AllocMemory<fixed_t>(x2 - x1) - x1;
VStep = thread->FrameMemory->AllocMemory<float>(x2 - x1) - x1;
for (int i = x1; i < x2; i++)
{
UPos[i] = texcoords.UPos[i] + xoffset;
VStep[i] = texcoords.VStep[i];
value = (int)walxrepeat - 1 - value;
}
this->yscale = (float)yscale;
return value + xoffset;
}
/////////////////////////////////////////////////////////////////////////

View file

@ -63,27 +63,23 @@ namespace swrenderer
public:
void Project(RenderViewport *viewport, double walxrepeat, int x1, int x2, const FWallTmapVals &WallT, bool flipx = false);
private:
float VStep[MAXWIDTH]; // swall
fixed_t UPos[MAXWIDTH]; // lwall
float VStep(int x) const;
fixed_t UPos(int x) const;
friend class DrawSegmentWallTexcoords;
friend class RenderWallPart;
friend class SpriteDrawerArgs;
};
float yscale = 1.0f;
fixed_t xoffset = 0;
class DrawSegmentWallTexcoords
{
public:
void Set(RenderThread *thread, const ProjectedWallTexcoords& texcoords, int x1, int x2, fixed_t xoffset, double yscale);
float yscale;
explicit operator bool() const { return UPos; }
explicit operator bool() const { return valid; }
private:
float* VStep = nullptr; // swall
fixed_t* UPos = nullptr; // maskedtexturecol
bool valid = false;
double CenterX;
double WallTMapScale2;
double walxrepeat;
int x1;
int x2;
FWallTmapVals WallT;
bool flipx;
friend class RenderWallPart;
friend class SpriteDrawerArgs;

View file

@ -34,7 +34,7 @@ namespace swrenderer
uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both
bool bFogBoundary = false;
DrawSegmentWallTexcoords texcoords;
ProjectedWallTexcoords texcoords;
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
short *sprtopclip = nullptr;

View file

@ -47,7 +47,7 @@ namespace swrenderer
{
auto viewport = thread->Viewport.get();
float iscale = walltexcoords.VStep[x] * maskedScaleY;
float iscale = walltexcoords.VStep(x) * maskedScaleY;
double spryscale = 1 / iscale;
double sprtopscreen;
if (sprflipvert)
@ -55,22 +55,7 @@ namespace swrenderer
else
sprtopscreen = viewport->CenterY - texturemid * spryscale;
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
}
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const DrawSegmentWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style)
{
auto viewport = thread->Viewport.get();
float iscale = walltexcoords.VStep[x] * maskedScaleY;
double spryscale = 1 / iscale;
double sprtopscreen;
if (sprflipvert)
sprtopscreen = viewport->CenterY + texturemid * spryscale;
else
sprtopscreen = viewport->CenterY - texturemid * spryscale;
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
DrawMaskedColumn(thread, x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos(x), spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, style);
}
void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked)

View file

@ -10,7 +10,6 @@ namespace swrenderer
{
class RenderThread;
class ProjectedWallTexcoords;
class DrawSegmentWallTexcoords;
class VoxelBlock
{
@ -36,7 +35,6 @@ namespace swrenderer
void SetDynamicLight(uint32_t color) { dynlightcolor = color; }
void DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const ProjectedWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style);
void DrawMaskedColumn(RenderThread* thread, int x, FSoftwareTexture* WallSpriteTile, const DrawSegmentWallTexcoords& walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short* mfloorclip, const short* mceilingclip, FRenderStyle style);
void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false);
void FillColumn(RenderThread *thread);
void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount);