mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Split line drawing into more functions
This commit is contained in:
parent
ae0ef8b09d
commit
22be201fc7
2 changed files with 188 additions and 131 deletions
|
@ -506,25 +506,19 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
// render it
|
||||
if (markceiling)
|
||||
{
|
||||
mCeilingPlane = Thread->PlaneList->GetRange(mCeilingPlane, start, stop);
|
||||
}
|
||||
|
||||
if (markfloor)
|
||||
{
|
||||
mFloorPlane = Thread->PlaneList->GetRange(mFloorPlane, start, stop);
|
||||
}
|
||||
|
||||
ClipSegmentTopBottom(start, stop);
|
||||
RenderWallSegmentTextures(start, stop);
|
||||
|
||||
MarkCeilingPlane(start, stop);
|
||||
MarkFloorPlane(start, stop);
|
||||
Mark3DFloors(start, stop);
|
||||
|
||||
if (clip3d->fake3D & FAKE3D_FAKEMASK)
|
||||
{
|
||||
return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
|
||||
}
|
||||
|
||||
MarkOpaquePassClip(start, stop);
|
||||
|
||||
// save sprite clipping info
|
||||
if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr)
|
||||
{
|
||||
|
@ -543,6 +537,10 @@ namespace swrenderer
|
|||
draw_segment->silhouette |= SIL_TOP | SIL_BOTTOM;
|
||||
}
|
||||
|
||||
RenderMiddleTexture(start, stop);
|
||||
RenderTopTexture(start, stop);
|
||||
RenderBottomTexture(start, stop);
|
||||
|
||||
// [RH] Draw any decals bound to the seg
|
||||
// [ZZ] Only if not an active mirror
|
||||
if (!markportal)
|
||||
|
@ -999,35 +997,18 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
// Draws zero, one, or two textures for walls.
|
||||
// Can draw or mark the starting pixel of floor and ceiling textures.
|
||||
void SWRenderLine::RenderWallSegmentTextures(int x1, int x2)
|
||||
void SWRenderLine::MarkCeilingPlane(int x1, int x2)
|
||||
{
|
||||
int x;
|
||||
double xscale;
|
||||
double yscale;
|
||||
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->FixedLightLevel()));
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
// mark ceiling areas
|
||||
if (markceiling)
|
||||
{
|
||||
for (x = x1; x < x2; ++x)
|
||||
mCeilingPlane = Thread->PlaneList->GetRange(mCeilingPlane, x1, x2);
|
||||
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
|
||||
short bottom = MIN(walltop.ScreenY[x], floorclip[x]);
|
||||
|
@ -1038,11 +1019,19 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mark floor areas
|
||||
void SWRenderLine::MarkFloorPlane(int x1, int x2)
|
||||
{
|
||||
if (markfloor)
|
||||
{
|
||||
for (x = x1; x < x2; ++x)
|
||||
mFloorPlane = Thread->PlaneList->GetRange(mFloorPlane, x1, x2);
|
||||
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]);
|
||||
short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
|
||||
|
@ -1054,17 +1043,25 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SWRenderLine::Mark3DFloors(int x1, int x2)
|
||||
{
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
// kg3D - fake planes clipping
|
||||
if (clip3d->fake3D & FAKE3D_REFRESHCLIP)
|
||||
{
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
|
||||
if (clip3d->fake3D & FAKE3D_CLIPBOTFRONT)
|
||||
{
|
||||
memcpy(clip3d->fakeFloor->floorclip + x1, wallbottom.ScreenY + x1, (x2 - x1) * sizeof(short));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = x1; x < x2; ++x)
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
walllower.ScreenY[x] = MIN(MAX(walllower.ScreenY[x], ceilingclip[x]), wallbottom.ScreenY[x]);
|
||||
}
|
||||
|
@ -1076,47 +1073,22 @@ namespace swrenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
for (x = x1; x < x2; ++x)
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
wallupper.ScreenY[x] = MAX(MIN(wallupper.ScreenY[x], floorclip[x]), walltop.ScreenY[x]);
|
||||
}
|
||||
memcpy(clip3d->fakeFloor->ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short));
|
||||
}
|
||||
}
|
||||
if (clip3d->fake3D & FAKE3D_FAKEMASK) return;
|
||||
}
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
void SWRenderLine::MarkOpaquePassClip(int x1, int x2)
|
||||
{
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
|
||||
// draw the wall tiers
|
||||
if (mMiddlePart.Texture)
|
||||
{ // one sided line
|
||||
if (mMiddlePart.Texture->UseType != FTexture::TEX_Null && viewactive)
|
||||
{
|
||||
FTexture *rw_pic = mMiddlePart.Texture;
|
||||
xscale = rw_pic->Scale.X * mMiddlePart.TextureScaleU;
|
||||
yscale = rw_pic->Scale.Y * mMiddlePart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mMiddlePart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mMiddlePart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
if (mMiddlePart.Texture) // one sided line
|
||||
{
|
||||
fillshort(ceilingclip + x1, x2 - x1, viewheight);
|
||||
fillshort(floorclip + x1, x2 - x1, 0xffff);
|
||||
}
|
||||
|
@ -1124,37 +1096,10 @@ namespace swrenderer
|
|||
{ // two sided line
|
||||
if (mTopPart.Texture != NULL && mTopPart.Texture->UseType != FTexture::TEX_Null)
|
||||
{ // top wall
|
||||
for (x = x1; x < x2; ++x)
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
wallupper.ScreenY[x] = MAX(MIN(wallupper.ScreenY[x], floorclip[x]), walltop.ScreenY[x]);
|
||||
}
|
||||
if (viewactive)
|
||||
{
|
||||
FTexture *rw_pic = mTopPart.Texture;
|
||||
xscale = rw_pic->Scale.X * mTopPart.TextureScaleU;
|
||||
yscale = rw_pic->Scale.Y * mTopPart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mTopPart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mTopPart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short));
|
||||
}
|
||||
else if (markceiling)
|
||||
|
@ -1162,40 +1107,12 @@ namespace swrenderer
|
|||
memcpy(ceilingclip + x1, walltop.ScreenY + x1, (x2 - x1) * sizeof(short));
|
||||
}
|
||||
|
||||
|
||||
if (mBottomPart.Texture != NULL && mBottomPart.Texture->UseType != FTexture::TEX_Null)
|
||||
{ // bottom wall
|
||||
for (x = x1; x < x2; ++x)
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
walllower.ScreenY[x] = MIN(MAX(walllower.ScreenY[x], ceilingclip[x]), wallbottom.ScreenY[x]);
|
||||
}
|
||||
if (viewactive)
|
||||
{
|
||||
FTexture *rw_pic = mBottomPart.Texture;
|
||||
xscale = rw_pic->Scale.X * mBottomPart.TextureScaleU;
|
||||
yscale = rw_pic->Scale.Y * mBottomPart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mBottomPart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mBottomPart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
memcpy(floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short));
|
||||
}
|
||||
else if (markfloor)
|
||||
|
@ -1205,6 +1122,140 @@ namespace swrenderer
|
|||
}
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderTopTexture(int x1, int x2)
|
||||
{
|
||||
if (mMiddlePart.Texture) return;
|
||||
if (!mTopPart.Texture || mTopPart.Texture->UseType == FTexture::TEX_Null) return;
|
||||
if (!viewactive) return;
|
||||
|
||||
FTexture *rw_pic = mTopPart.Texture;
|
||||
double xscale = rw_pic->Scale.X * mTopPart.TextureScaleU;
|
||||
double yscale = rw_pic->Scale.Y * mTopPart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mTopPart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mTopPart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->FixedLightLevel()));
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderMiddleTexture(int x1, int x2)
|
||||
{
|
||||
if (!mMiddlePart.Texture || mMiddlePart.Texture->UseType == FTexture::TEX_Null) return;
|
||||
if (!viewactive) return;
|
||||
|
||||
FTexture *rw_pic = mMiddlePart.Texture;
|
||||
double xscale = rw_pic->Scale.X * mMiddlePart.TextureScaleU;
|
||||
double yscale = rw_pic->Scale.Y * mMiddlePart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mMiddlePart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mMiddlePart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->FixedLightLevel()));
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
|
||||
void SWRenderLine::RenderBottomTexture(int x1, int x2)
|
||||
{
|
||||
if (mMiddlePart.Texture) return;
|
||||
if (!mBottomPart.Texture || mBottomPart.Texture->UseType == FTexture::TEX_Null) return;
|
||||
if (!viewactive) return;
|
||||
|
||||
FTexture *rw_pic = mBottomPart.Texture;
|
||||
double xscale = rw_pic->Scale.X * mBottomPart.TextureScaleU;
|
||||
double yscale = rw_pic->Scale.Y * mBottomPart.TextureScaleV;
|
||||
if (xscale != lwallscale)
|
||||
{
|
||||
walltexcoords.ProjectPos(mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT);
|
||||
lwallscale = xscale;
|
||||
}
|
||||
fixed_t offset;
|
||||
if (mBottomPart.Texture->bWorldPanning)
|
||||
{
|
||||
offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = mBottomPart.TextureOffsetU;
|
||||
}
|
||||
if (xscale < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
WallDrawerArgs drawerargs;
|
||||
drawerargs.SetStyle(false, false, OPAQUE);
|
||||
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0)
|
||||
drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, FIXEDLIGHT2SHADE(cameraLight->FixedLightLevel()));
|
||||
else if (cameraLight->FixedColormap() != nullptr)
|
||||
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
|
||||
|
||||
float rw_light = rw_lightleft + rw_lightstep * (x1 - WallC.sx1);
|
||||
|
||||
FLightNode *light_list = (mLineSegment && mLineSegment->sidedef) ? mLineSegment->sidedef->lighthead : nullptr;
|
||||
|
||||
RenderWallPart renderWallpart(Thread);
|
||||
renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Transform and clip coordinates. Returns true if it was clipped away
|
||||
|
|
|
@ -73,7 +73,13 @@ namespace swrenderer
|
|||
void SetMiddleTexture();
|
||||
void SetBottomTexture();
|
||||
void ClipSegmentTopBottom(int x1, int x2);
|
||||
void RenderWallSegmentTextures(int x1, int x2);
|
||||
void MarkCeilingPlane(int x1, int x2);
|
||||
void MarkFloorPlane(int x1, int x2);
|
||||
void Mark3DFloors(int x1, int x2);
|
||||
void MarkOpaquePassClip(int x1, int x2);
|
||||
void RenderTopTexture(int x1, int x2);
|
||||
void RenderMiddleTexture(int x1, int x2);
|
||||
void RenderBottomTexture(int x1, int x2);
|
||||
|
||||
bool IsFogBoundary(sector_t *front, sector_t *back) const;
|
||||
bool SkyboxCompare(sector_t *frontsector, sector_t *backsector) const;
|
||||
|
|
Loading…
Reference in a new issue