Draw 3d floor sides

This commit is contained in:
Magnus Norddahl 2016-11-21 20:50:54 +01:00
parent ddb0161f9c
commit 7af504df58
4 changed files with 92 additions and 47 deletions

View file

@ -140,7 +140,9 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
{ {
seg_t *line = &sub->firstline[i]; seg_t *line = &sub->firstline[i];
if (line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) if (line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
{
RenderLine(sub, line, frontsector, subsectorDepth); RenderLine(sub, line, frontsector, subsectorDepth);
}
} }
bool mainBSP = ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors); bool mainBSP = ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors);
@ -206,6 +208,19 @@ void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *fronts
sub->flags |= SSECF_DRAWN; sub->flags |= SSECF_DRAWN;
} }
// Render 3D floor sides
if (line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
{
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
{
F3DFloor *fakeFloor = line->backsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue;
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
if (!fakeFloor->model) continue;
RenderPolyWall::Render3DFloorLine(WorldToClip, line, frontsector, subsectorDepth, fakeFloor, SubsectorTranslucentWalls);
}
}
// Render wall, and update culling info if its an occlusion blocker // Render wall, and update culling info if its an occlusion blocker
if (RenderPolyWall::RenderLine(WorldToClip, line, frontsector, subsectorDepth, SubsectorTranslucentWalls)) if (RenderPolyWall::RenderLine(WorldToClip, line, frontsector, subsectorDepth, SubsectorTranslucentWalls))
{ {

View file

@ -31,6 +31,9 @@
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const seg_t *line, uint32_t subsectorDepth) void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const seg_t *line, uint32_t subsectorDepth)
{ {
if (line->linedef == nullptr && line->sidedef == nullptr)
return;
for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext) for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext)
{ {
RenderPolyDecal render; RenderPolyDecal render;

View file

@ -32,17 +32,19 @@
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, std::vector<PolyTranslucentObject> &translucentWallsOutput) bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, std::vector<PolyTranslucentObject> &translucentWallsOutput)
{ {
RenderPolyWall wall;
wall.LineSeg = line;
wall.Line = line->linedef;
wall.Side = line->sidedef;
wall.Colormap = frontsector->ColorMap;
wall.Masked = false;
wall.SubsectorDepth = subsectorDepth;
double frontceilz1 = frontsector->ceilingplane.ZatPoint(line->v1); double frontceilz1 = frontsector->ceilingplane.ZatPoint(line->v1);
double frontfloorz1 = frontsector->floorplane.ZatPoint(line->v1); double frontfloorz1 = frontsector->floorplane.ZatPoint(line->v1);
double frontceilz2 = frontsector->ceilingplane.ZatPoint(line->v2); double frontceilz2 = frontsector->ceilingplane.ZatPoint(line->v2);
double frontfloorz2 = frontsector->floorplane.ZatPoint(line->v2); double frontfloorz2 = frontsector->floorplane.ZatPoint(line->v2);
RenderPolyWall wall;
wall.Line = line;
wall.Colormap = frontsector->ColorMap;
wall.Masked = false;
wall.SubsectorDepth = subsectorDepth;
if (line->backsector == nullptr) if (line->backsector == nullptr)
{ {
if (line->sidedef) if (line->sidedef)
@ -118,6 +120,28 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto
return false; return false;
} }
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput)
{
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
double frontceilz2 = fakeFloor->top.plane->ZatPoint(line->v2);
double frontfloorz2 = fakeFloor->bottom.plane->ZatPoint(line->v2);
RenderPolyWall wall;
wall.LineSeg = line;
wall.Line = fakeFloor->master;
wall.Side = fakeFloor->master->sidedef[0];
wall.Colormap = frontsector->ColorMap;
wall.Masked = false;
wall.SubsectorDepth = subsectorDepth;
wall.SetCoords(line->v1->fPos(), line->v2->fPos(), frontceilz1, frontfloorz1, frontceilz2, frontfloorz2);
wall.TopZ = frontceilz1;
wall.BottomZ = frontfloorz1;
wall.UnpeggedCeil = frontceilz1;
wall.Texpart = side_t::mid;
wall.Render(worldToClip);
}
void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2)
{ {
this->v1 = v1; this->v1 = v1;
@ -134,7 +158,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
if (!tex) if (!tex)
return; return;
PolyWallTextureCoords texcoords(tex, Line, Texpart, TopZ, BottomZ, UnpeggedCeil); PolyWallTextureCoords texcoords(tex, LineSeg, Line, Side, Texpart, TopZ, BottomZ, UnpeggedCeil);
TriVertex *vertices = PolyVertexBuffer::GetVertices(4); TriVertex *vertices = PolyVertexBuffer::GetVertices(4);
if (!vertices) if (!vertices)
@ -199,15 +223,15 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
} }
else else
{ {
args.uniforms.destalpha = (Line->linedef->flags & ML_ADDTRANS) ? 256 : (uint32_t)(256 - Line->linedef->alpha * 256); args.uniforms.destalpha = (Line->flags & ML_ADDTRANS) ? 256 : (uint32_t)(256 - Line->alpha * 256);
args.uniforms.srcalpha = (uint32_t)(Line->linedef->alpha * 256); args.uniforms.srcalpha = (uint32_t)(Line->alpha * 256);
if (args.uniforms.destalpha == 0 && args.uniforms.srcalpha == 256) if (args.uniforms.destalpha == 0 && args.uniforms.srcalpha == 256)
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
else else
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add);
} }
RenderPolyDecal::RenderWallDecals(worldToClip, Line, SubsectorDepth); RenderPolyDecal::RenderWallDecals(worldToClip, LineSeg, SubsectorDepth);
} }
void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)
@ -232,25 +256,25 @@ void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)
FTexture *RenderPolyWall::GetTexture() FTexture *RenderPolyWall::GetTexture()
{ {
FTexture *tex = TexMan(Line->sidedef->GetTexture(Texpart), true); FTexture *tex = TexMan(Side->GetTexture(Texpart), true);
if (tex == nullptr || tex->UseType == FTexture::TEX_Null) if (tex == nullptr || tex->UseType == FTexture::TEX_Null)
{ {
// Mapping error. Doom floodfills this with a plane. // Mapping error. Doom floodfills this with a plane.
// This code doesn't do that, but at least it uses the "right" texture.. // This code doesn't do that, but at least it uses the "right" texture..
if (Line->linedef && Line->backsector && Line->linedef->sidedef[0] == Line->sidedef) if (Line && Line->backsector && Line->sidedef[0] == Side)
{ {
if (Texpart == side_t::top) if (Texpart == side_t::top)
tex = TexMan(Line->linedef->backsector->GetTexture(sector_t::ceiling), true); tex = TexMan(Line->backsector->GetTexture(sector_t::ceiling), true);
else if (Texpart == side_t::bottom) else if (Texpart == side_t::bottom)
tex = TexMan(Line->linedef->backsector->GetTexture(sector_t::floor), true); tex = TexMan(Line->backsector->GetTexture(sector_t::floor), true);
} }
if (Line->linedef && Line->backsector && Line->linedef->sidedef[1] == Line->sidedef) if (Line && Line->backsector && Line->sidedef[1] == Side)
{ {
if (Texpart == side_t::top) if (Texpart == side_t::top)
tex = TexMan(Line->linedef->frontsector->GetTexture(sector_t::ceiling), true); tex = TexMan(Line->frontsector->GetTexture(sector_t::ceiling), true);
else if (Texpart == side_t::bottom) else if (Texpart == side_t::bottom)
tex = TexMan(Line->linedef->frontsector->GetTexture(sector_t::floor), true); tex = TexMan(Line->frontsector->GetTexture(sector_t::floor), true);
} }
if (tex == nullptr || tex->UseType == FTexture::TEX_Null) if (tex == nullptr || tex->UseType == FTexture::TEX_Null)
@ -269,33 +293,33 @@ int RenderPolyWall::GetLightLevel()
{ {
bool foggy = false; bool foggy = false;
int actualextralight = foggy ? 0 : extralight << 4; int actualextralight = foggy ? 0 : extralight << 4;
return clamp(Line->sidedef->GetLightLevel(foggy, Line->frontsector->lightlevel) + actualextralight, 0, 255); return clamp(Side->GetLightLevel(foggy, LineSeg->frontsector->lightlevel) + actualextralight, 0, 255);
} }
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
PolyWallTextureCoords::PolyWallTextureCoords(FTexture *tex, const seg_t *line, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil) PolyWallTextureCoords::PolyWallTextureCoords(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil)
{ {
CalcU(tex, line, texpart); CalcU(tex, lineseg, line, side, texpart);
CalcV(tex, line, texpart, topz, bottomz, unpeggedceil); CalcV(tex, line, side, texpart, topz, bottomz, unpeggedceil);
} }
void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *line, side_t::ETexpart texpart) void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart)
{ {
double lineLength = line->sidedef->TexelLength; double lineLength = side->TexelLength;
double lineStart = 0.0; double lineStart = 0.0;
bool entireSegment = ((line->linedef->v1 == line->v1) && (line->linedef->v2 == line->v2) || (line->linedef->v2 == line->v1) && (line->linedef->v1 == line->v2)); bool entireSegment = ((lineseg->v1 == line->v1) && (lineseg->v2 == line->v2) || (lineseg->v2 == line->v1) && (lineseg->v1 == line->v2));
if (!entireSegment) if (!entireSegment)
{ {
lineLength = (line->v2->fPos() - line->v1->fPos()).Length(); lineLength = (lineseg->v2->fPos() - lineseg->v1->fPos()).Length();
lineStart = (line->v1->fPos() - line->linedef->v1->fPos()).Length(); lineStart = (lineseg->v1->fPos() - lineseg->v1->fPos()).Length();
} }
int texWidth = tex->GetWidth(); int texWidth = tex->GetWidth();
double uscale = line->sidedef->GetTextureXScale(texpart) * tex->Scale.X; double uscale = side->GetTextureXScale(texpart) * tex->Scale.X;
u1 = lineStart + line->sidedef->GetTextureXOffset(texpart); u1 = lineStart + side->GetTextureXOffset(texpart);
u2 = u1 + lineLength; u2 = u1 + lineLength;
u1 *= uscale; u1 *= uscale;
u2 *= uscale; u2 *= uscale;
@ -303,11 +327,11 @@ void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *line, side_t::ETex
u2 /= texWidth; u2 /= texWidth;
} }
void PolyWallTextureCoords::CalcV(FTexture *tex, const seg_t *line, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil) void PolyWallTextureCoords::CalcV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil)
{ {
double vscale = line->sidedef->GetTextureYScale(texpart) * tex->Scale.Y; double vscale = side->GetTextureYScale(texpart) * tex->Scale.Y;
double yoffset = line->sidedef->GetTextureYOffset(texpart); double yoffset = side->GetTextureYOffset(texpart);
if (tex->bWorldPanning) if (tex->bWorldPanning)
yoffset *= vscale; yoffset *= vscale;
@ -315,13 +339,13 @@ void PolyWallTextureCoords::CalcV(FTexture *tex, const seg_t *line, side_t::ETex
{ {
default: default:
case side_t::mid: case side_t::mid:
CalcVMidPart(tex, line, topz, bottomz, vscale, yoffset); CalcVMidPart(tex, line, side, topz, bottomz, vscale, yoffset);
break; break;
case side_t::top: case side_t::top:
CalcVTopPart(tex, line, topz, bottomz, vscale, yoffset); CalcVTopPart(tex, line, side, topz, bottomz, vscale, yoffset);
break; break;
case side_t::bottom: case side_t::bottom:
CalcVBottomPart(tex, line, topz, bottomz, unpeggedceil, vscale, yoffset); CalcVBottomPart(tex, line, side, topz, bottomz, unpeggedceil, vscale, yoffset);
break; break;
} }
@ -330,9 +354,9 @@ void PolyWallTextureCoords::CalcV(FTexture *tex, const seg_t *line, side_t::ETex
v2 /= texHeight; v2 /= texHeight;
} }
void PolyWallTextureCoords::CalcVTopPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double vscale, double yoffset) void PolyWallTextureCoords::CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset)
{ {
bool pegged = (line->linedef->flags & ML_DONTPEGTOP) == 0; bool pegged = (line->flags & ML_DONTPEGTOP) == 0;
if (pegged) // bottom to top if (pegged) // bottom to top
{ {
int texHeight = tex->GetHeight(); int texHeight = tex->GetHeight();
@ -353,9 +377,9 @@ void PolyWallTextureCoords::CalcVTopPart(FTexture *tex, const seg_t *line, doubl
} }
} }
void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double vscale, double yoffset) void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset)
{ {
bool pegged = (line->linedef->flags & ML_DONTPEGBOTTOM) == 0; bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0;
if (pegged) // top to bottom if (pegged) // top to bottom
{ {
v1 = yoffset * vscale; v1 = yoffset * vscale;
@ -369,9 +393,9 @@ void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const seg_t *line, doubl
} }
} }
void PolyWallTextureCoords::CalcVBottomPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset) void PolyWallTextureCoords::CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset)
{ {
bool pegged = (line->linedef->flags & ML_DONTPEGBOTTOM) == 0; bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0;
if (pegged) // top to bottom if (pegged) // top to bottom
{ {
v1 = yoffset; v1 = yoffset;

View file

@ -30,6 +30,7 @@ class RenderPolyWall
{ {
public: public:
static bool RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, std::vector<PolyTranslucentObject> &translucentWallsOutput); static bool RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, std::vector<PolyTranslucentObject> &translucentWallsOutput);
static void Render3DFloorLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2); void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
void Render(const TriMatrix &worldToClip); void Render(const TriMatrix &worldToClip);
@ -41,7 +42,9 @@ public:
double ceil2 = 0.0; double ceil2 = 0.0;
double floor2 = 0.0; double floor2 = 0.0;
const seg_t *Line = nullptr; const seg_t *LineSeg = nullptr;
const line_t *Line = nullptr;
const side_t *Side = nullptr;
side_t::ETexpart Texpart = side_t::mid; side_t::ETexpart Texpart = side_t::mid;
double TopZ = 0.0; double TopZ = 0.0;
double BottomZ = 0.0; double BottomZ = 0.0;
@ -60,15 +63,15 @@ private:
class PolyWallTextureCoords class PolyWallTextureCoords
{ {
public: public:
PolyWallTextureCoords(FTexture *tex, const seg_t *line, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil); PolyWallTextureCoords(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil);
double u1, u2; double u1, u2;
double v1, v2; double v1, v2;
private: private:
void CalcU(FTexture *tex, const seg_t *line, side_t::ETexpart texpart); void CalcU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart texpart);
void CalcV(FTexture *tex, const seg_t *line, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil); void CalcV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart texpart, double topz, double bottomz, double unpeggedceil);
void CalcVTopPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double vscale, double yoffset); void CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset);
void CalcVMidPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double vscale, double yoffset); void CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double vscale, double yoffset);
void CalcVBottomPart(FTexture *tex, const seg_t *line, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset); void CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double vscale, double yoffset);
}; };