mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
Remove the sprite drawer from wall drawing
This commit is contained in:
parent
3944ee5b67
commit
fec280a5fc
3 changed files with 67 additions and 159 deletions
|
@ -412,57 +412,57 @@ namespace swrenderer
|
|||
memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
|
||||
|
||||
draw_segment->bFogBoundary = IsFogBoundary(mFrontSector, mBackSector);
|
||||
bool is_translucent = sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls();
|
||||
if (is_translucent)
|
||||
if (sidedef->GetTexture(side_t::mid).isValid())
|
||||
{
|
||||
if (sidedef->GetTexture(side_t::mid).isValid())
|
||||
draw_segment->SetHas3DFloorMidTexture();
|
||||
|
||||
FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true);
|
||||
FSoftwareTexture *pic = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr;
|
||||
if (pic)
|
||||
{
|
||||
draw_segment->SetHas3DFloorMidTexture();
|
||||
|
||||
double yscale = GetYScale(sidedef, pic, side_t::mid);
|
||||
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
|
||||
double yscale = GetYScale(sidedef, pic, side_t::mid);
|
||||
double cameraZ = Thread->Viewport->viewpoint.Pos.Z;
|
||||
|
||||
double texZFloor = MAX(mFrontSector->GetPlaneTexZ(sector_t::floor), mBackSector->GetPlaneTexZ(sector_t::floor));
|
||||
double texZCeiling = MIN(mFrontSector->GetPlaneTexZ(sector_t::ceiling), mBackSector->GetPlaneTexZ(sector_t::ceiling));
|
||||
double texZFloor = MAX(mFrontSector->GetPlaneTexZ(sector_t::floor), mBackSector->GetPlaneTexZ(sector_t::floor));
|
||||
double texZCeiling = MIN(mFrontSector->GetPlaneTexZ(sector_t::ceiling), mBackSector->GetPlaneTexZ(sector_t::ceiling));
|
||||
|
||||
double TextureMid;
|
||||
if (yscale >= 0)
|
||||
{ // normal orientation
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{ // bottom of texture at bottom
|
||||
TextureMid = (texZFloor - cameraZ) * yscale + pic->GetHeight();
|
||||
double TextureMid;
|
||||
if (yscale >= 0)
|
||||
{ // normal orientation
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{ // bottom of texture at bottom
|
||||
TextureMid = (texZFloor - cameraZ) * yscale + pic->GetHeight();
|
||||
}
|
||||
else
|
||||
{ // top of texture at top
|
||||
TextureMid = (texZCeiling - cameraZ) * yscale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // top of texture at top
|
||||
TextureMid = (texZCeiling - cameraZ) * yscale;
|
||||
{ // upside down
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{ // top of texture at bottom
|
||||
TextureMid = (texZFloor - cameraZ) * yscale;
|
||||
}
|
||||
else
|
||||
{ // bottom of texture at top
|
||||
TextureMid = (texZCeiling - cameraZ) * yscale + pic->GetHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // upside down
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{ // top of texture at bottom
|
||||
TextureMid = (texZFloor - cameraZ) * yscale;
|
||||
}
|
||||
else
|
||||
{ // bottom of texture at top
|
||||
TextureMid = (texZCeiling - cameraZ) * yscale + pic->GetHeight();
|
||||
}
|
||||
}
|
||||
|
||||
TextureMid += GetRowOffset(linedef, sidedef, pic, side_t::mid);
|
||||
TextureMid += GetRowOffset(linedef, sidedef, pic, side_t::mid);
|
||||
|
||||
draw_segment->texcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), WallC.sx1, WallC.sx2, WallT);
|
||||
draw_segment->texcoords.xoffset = GetXOffset(sidedef, pic, side_t::mid);
|
||||
draw_segment->texcoords.yscale = yscale;
|
||||
draw_segment->texcoords.texturemid = TextureMid;
|
||||
draw_segment->texcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * GetXScale(sidedef, pic, side_t::mid), WallC.sx1, WallC.sx2, WallT);
|
||||
draw_segment->texcoords.xoffset = GetXOffset(sidedef, pic, side_t::mid);
|
||||
draw_segment->texcoords.yscale = yscale;
|
||||
draw_segment->texcoords.texturemid = TextureMid;
|
||||
}
|
||||
}
|
||||
|
||||
draw_segment->light = mLight.GetLightPos(start);
|
||||
draw_segment->lightstep = mLight.GetLightStep();
|
||||
|
||||
if (draw_segment->bFogBoundary || is_translucent)
|
||||
if (draw_segment->bFogBoundary || draw_segment->texcoords || draw_segment->Has3DFloorWalls())
|
||||
{
|
||||
Thread->DrawSegments->PushTranslucent(draw_segment);
|
||||
}
|
||||
|
|
|
@ -54,8 +54,6 @@
|
|||
#include "swrenderer/viewport/r_viewport.h"
|
||||
#include "swrenderer/viewport/r_spritedrawer.h"
|
||||
|
||||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
RenderDrawSegment::RenderDrawSegment(RenderThread *thread)
|
||||
|
@ -95,18 +93,13 @@ namespace swrenderer
|
|||
float alpha = (float)MIN(curline->linedef->alpha, 1.);
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
SpriteDrawerArgs columndrawerargs;
|
||||
ColormapLight cmlight;
|
||||
cmlight.SetColormap(Thread, MINZ, mLight.GetLightLevel(), mLight.GetFoggy(), mLight.GetBaseColormap(), false, false, false, false, false);
|
||||
bool visible = columndrawerargs.SetStyle(viewport, LegacyRenderStyles[additive ? STYLE_Add : STYLE_Translucent], alpha, 0, 0, cmlight);
|
||||
bool visible = alpha > 0.0f;
|
||||
if (!visible && !ds->bFogBoundary && !ds->Has3DFloorWalls())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// [RH] Draw fog partition
|
||||
bool renderwall = true;
|
||||
bool notrelevant = false;
|
||||
if (ds->bFogBoundary)
|
||||
{
|
||||
const short *mfloorclip = ds->sprbottomclip - ds->x1;
|
||||
|
@ -114,22 +107,17 @@ namespace swrenderer
|
|||
|
||||
RenderFogBoundary renderfog;
|
||||
renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, mLight);
|
||||
|
||||
if (!ds->texcoords)
|
||||
renderwall = false;
|
||||
}
|
||||
else if ((ds->Has3DFloorWalls() && !ds->Has3DFloorMidTexture()) || !visible)
|
||||
{
|
||||
renderwall = false;
|
||||
}
|
||||
|
||||
if (renderwall)
|
||||
notrelevant = RenderWall(ds, x1, x2, columndrawerargs, visible);
|
||||
bool notrelevant = false;
|
||||
if (ds->texcoords && visible)
|
||||
notrelevant = RenderWall(ds, x1, x2);
|
||||
|
||||
if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls())
|
||||
{
|
||||
RenderFakeWallRange(ds, x1, x2);
|
||||
}
|
||||
|
||||
if (!notrelevant)
|
||||
{
|
||||
ds->sprclipped = true;
|
||||
|
@ -137,7 +125,7 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible)
|
||||
bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2)
|
||||
{
|
||||
auto renderstyle = DefaultRenderStyle();
|
||||
auto viewport = Thread->Viewport.get();
|
||||
|
@ -159,9 +147,6 @@ namespace swrenderer
|
|||
bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
|
||||
if (!wrap)
|
||||
{ // Texture does not wrap vertically.
|
||||
double textop;
|
||||
|
||||
float MaskedScaleY = ds->texcoords.yscale;
|
||||
|
||||
// find positioning
|
||||
double texheight = tex->GetScaledHeightDouble();
|
||||
|
@ -171,45 +156,8 @@ namespace swrenderer
|
|||
texheight = texheight / texheightscale;
|
||||
}
|
||||
|
||||
double texturemid;
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
texturemid = MAX(frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
|
||||
}
|
||||
|
||||
double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
|
||||
|
||||
bool sprflipvert = false;
|
||||
|
||||
if (MaskedScaleY < 0)
|
||||
{
|
||||
MaskedScaleY = -MaskedScaleY;
|
||||
sprflipvert = true;
|
||||
}
|
||||
if (tex->useWorldPanning(curline->GetLevel()))
|
||||
{
|
||||
// rowoffset is added before the multiply so that the masked texture will
|
||||
// still be positioned in world units rather than texels.
|
||||
texturemid += rowoffset - Thread->Viewport->viewpoint.Pos.Z;
|
||||
textop = texturemid;
|
||||
texturemid *= MaskedScaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// rowoffset is added outside the multiply so that it positions the texture
|
||||
// by texels instead of world units.
|
||||
textop = texturemid + rowoffset / MaskedScaleY - Thread->Viewport->viewpoint.Pos.Z;
|
||||
texturemid = (texturemid - Thread->Viewport->viewpoint.Pos.Z) * MaskedScaleY + rowoffset;
|
||||
}
|
||||
if (sprflipvert)
|
||||
{
|
||||
MaskedScaleY = -MaskedScaleY;
|
||||
texturemid -= tex->GetHeight() << FRACBITS;
|
||||
}
|
||||
bool sprflipvert = ds->texcoords.yscale < 0;
|
||||
double textop = ds->texcoords.texturemid / ds->texcoords.yscale;
|
||||
|
||||
// [RH] Don't bother drawing segs that are completely offscreen
|
||||
if (viewport->globaldclip * ds->WallC.sz1 < -textop && viewport->globaldclip * ds->WallC.sz2 < -textop)
|
||||
|
@ -231,11 +179,6 @@ namespace swrenderer
|
|||
return true;
|
||||
}
|
||||
|
||||
WallC.sz1 = ds->WallC.sz1;
|
||||
WallC.sz2 = ds->WallC.sz2;
|
||||
WallC.sx1 = ds->WallC.sx1;
|
||||
WallC.sx2 = ds->WallC.sx2;
|
||||
|
||||
// Unclipped vanilla Doom range for the wall. Relies on ceiling/floor clip to clamp the wall in range.
|
||||
double ceilZ = textop;
|
||||
double floorZ = textop - texheight;
|
||||
|
@ -267,8 +210,8 @@ namespace swrenderer
|
|||
floorZ = MAX(floorZ, clipZ);
|
||||
}
|
||||
|
||||
wallupper.Project(Thread->Viewport.get(), ceilZ, &WallC);
|
||||
walllower.Project(Thread->Viewport.get(), floorZ, &WallC);
|
||||
wallupper.Project(Thread->Viewport.get(), ceilZ, &ds->WallC);
|
||||
walllower.Project(Thread->Viewport.get(), floorZ, &ds->WallC);
|
||||
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
|
@ -289,43 +232,15 @@ namespace swrenderer
|
|||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
|
||||
(curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
|
||||
{
|
||||
ClipMidtex(x1, x2);
|
||||
ClipMidtex(ds, x1, x2);
|
||||
}
|
||||
}
|
||||
|
||||
mfloorclip = walllower.ScreenY;
|
||||
mceilingclip = wallupper.ScreenY;
|
||||
|
||||
auto cameraLight = CameraLight::Instance();
|
||||
bool needslight = (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0);
|
||||
|
||||
ProjectedWallTexcoords texcoords = ds->texcoords;
|
||||
texcoords.texturemid = texturemid;
|
||||
texcoords.yscale = MaskedScaleY;
|
||||
|
||||
// draw the columns one at a time
|
||||
if (visible)
|
||||
{
|
||||
Thread->PrepareTexture(tex, renderstyle);
|
||||
float lightpos = mLight.GetLightPos(x1);
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
if (needslight)
|
||||
{
|
||||
columndrawerargs.SetLight(lightpos, mLight.GetLightLevel(), mLight.GetFoggy(), Thread->Viewport.get());
|
||||
lightpos += mLight.GetLightStep();
|
||||
}
|
||||
|
||||
columndrawerargs.DrawMaskedColumn(Thread, x, tex, texcoords, sprflipvert, mfloorclip, mceilingclip, renderstyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Texture does wrap vertically.
|
||||
WallC.sz1 = ds->WallC.sz1;
|
||||
WallC.sz2 = ds->WallC.sz2;
|
||||
WallC.sx1 = ds->WallC.sx1;
|
||||
WallC.sx2 = ds->WallC.sx2;
|
||||
|
||||
if (clip3d->CurrentSkybox)
|
||||
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
|
||||
|
@ -335,13 +250,13 @@ namespace swrenderer
|
|||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
|
||||
(curline->GetLevel()->ib_compatflags & BCOMPATF_CLIPMIDTEX))
|
||||
{
|
||||
ClipMidtex(x1, x2);
|
||||
ClipMidtex(ds, x1, x2);
|
||||
}
|
||||
}
|
||||
|
||||
if (m3DFloor.clipTop)
|
||||
{
|
||||
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
if (wallupper.ScreenY[i] < mceilingclip[i])
|
||||
|
@ -351,7 +266,7 @@ namespace swrenderer
|
|||
}
|
||||
if (m3DFloor.clipBottom)
|
||||
{
|
||||
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
if (walllower.ScreenY[i] > mfloorclip[i])
|
||||
|
@ -359,17 +274,17 @@ namespace swrenderer
|
|||
}
|
||||
mfloorclip = walllower.ScreenY;
|
||||
}
|
||||
|
||||
double top, bot;
|
||||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
float alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(frontsector, curline, WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
|
||||
}
|
||||
|
||||
double top, bot;
|
||||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
float alpha = FLOAT2FIXED((float)MIN(curline->linedef->alpha, 1.));
|
||||
bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(frontsector, curline, ds->WallC, tex, x1, x2, mceilingclip, mfloorclip, ds->texcoords, top, bot, true, additive, alpha, mLight, nullptr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -433,12 +348,9 @@ namespace swrenderer
|
|||
texturemid += rowoffset;
|
||||
}
|
||||
|
||||
WallC = ds->WallC;
|
||||
WallT = ds->tmapvals;
|
||||
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC);
|
||||
wallupper.Project(Thread->Viewport.get(), clipTop - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
walllower.Project(Thread->Viewport.get(), clipBottom - Thread->Viewport->viewpoint.Pos.Z, &ds->WallC);
|
||||
|
||||
for (i = x1; i < x2; i++)
|
||||
{
|
||||
|
@ -452,7 +364,7 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
ProjectedWallTexcoords walltexcoords;
|
||||
walltexcoords.Project(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->WallC.sx1, ds->WallC.sx2, WallT);
|
||||
walltexcoords.Project(Thread->Viewport.get(), curline->sidedef->TexelLength*xscale, ds->WallC.sx1, ds->WallC.sx2, ds->tmapvals);
|
||||
walltexcoords.texturemid = texturemid;
|
||||
walltexcoords.yscale = yscale;
|
||||
walltexcoords.xoffset = rw_offset;
|
||||
|
@ -461,7 +373,7 @@ namespace swrenderer
|
|||
GetMaskedWallTopBottom(ds, top, bot);
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, mLight, nullptr);
|
||||
renderWallpart.Render(frontsector, curline, ds->WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, walltexcoords, top, bot, true, (rover->flags & FF_ADDITIVETRANS) != 0, Alpha, mLight, nullptr);
|
||||
|
||||
RenderDecal::RenderDecals(Thread, curline->sidedef, ds, curline, mLight, wallupper.ScreenY, walllower.ScreenY, true);
|
||||
}
|
||||
|
@ -880,19 +792,19 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
// Clip a midtexture to the floor and ceiling of the sector in front of it.
|
||||
void RenderDrawSegment::ClipMidtex(int x1, int x2)
|
||||
void RenderDrawSegment::ClipMidtex(DrawSegment* ds, int x1, int x2)
|
||||
{
|
||||
ProjectedWallLine most;
|
||||
|
||||
RenderPortal *renderportal = Thread->Portal.get();
|
||||
|
||||
most.Project(Thread->Viewport.get(), curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
most.Project(Thread->Viewport.get(), curline->frontsector->ceilingplane, &ds->WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
for (int i = x1; i < x2; ++i)
|
||||
{
|
||||
if (wallupper.ScreenY[i] < most.ScreenY[i])
|
||||
wallupper.ScreenY[i] = most.ScreenY[i];
|
||||
}
|
||||
most.Project(Thread->Viewport.get(), curline->frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
most.Project(Thread->Viewport.get(), curline->frontsector->floorplane, &ds->WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||
for (int i = x1; i < x2; ++i)
|
||||
{
|
||||
if (walllower.ScreenY[i] > most.ScreenY[i])
|
||||
|
|
|
@ -37,9 +37,8 @@ namespace swrenderer
|
|||
RenderThread *Thread = nullptr;
|
||||
|
||||
private:
|
||||
bool RenderWall(DrawSegment *ds, int x1, int x2, SpriteDrawerArgs &columndrawerargs, bool visible);
|
||||
void RenderWrapWall(DrawSegment* ds, int x1, int x2, FSoftwareTexture* tex);
|
||||
void ClipMidtex(int x1, int x2);
|
||||
bool RenderWall(DrawSegment *ds, int x1, int x2);
|
||||
void ClipMidtex(DrawSegment* ds, int x1, int x2);
|
||||
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, double clipTop, double clipBottom, FSoftwareTexture *rw_pic);
|
||||
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2);
|
||||
void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
|
||||
|
@ -50,9 +49,6 @@ namespace swrenderer
|
|||
seg_t *curline = nullptr;
|
||||
Fake3DTranslucent m3DFloor;
|
||||
|
||||
FWallCoords WallC;
|
||||
FWallTmapVals WallT;
|
||||
|
||||
ProjectedWallLight mLight;
|
||||
|
||||
ProjectedWallLine wallupper;
|
||||
|
|
Loading…
Reference in a new issue