mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-21 11:21:04 +00:00
- Translucent 3d floor plane support
This commit is contained in:
parent
393373a661
commit
b80bf6930a
4 changed files with 199 additions and 117 deletions
|
@ -34,59 +34,6 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_3dfloors)
|
EXTERN_CVAR(Int, r_3dfloors)
|
||||||
|
|
||||||
void RenderPolyPlane::Render3DPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue)
|
|
||||||
{
|
|
||||||
if (!r_3dfloors || sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
|
||||||
|
|
||||||
auto frontsector = sub->sector;
|
|
||||||
auto &ffloors = frontsector->e->XFloor.ffloors;
|
|
||||||
|
|
||||||
// 3D floor floors
|
|
||||||
for (int i = 0; i < (int)ffloors.Size(); i++)
|
|
||||||
{
|
|
||||||
F3DFloor *fakeFloor = ffloors[i];
|
|
||||||
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
|
||||||
if (!fakeFloor->model) continue;
|
|
||||||
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
|
||||||
// R_3D_AddHeight(fakeFloor->top.plane, frontsector);
|
|
||||||
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
|
||||||
if (fakeFloor->alpha == 0) continue;
|
|
||||||
if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue;
|
|
||||||
//fakeFloor->alpha
|
|
||||||
|
|
||||||
double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
|
|
||||||
if (fakeFloor->bottom.plane->isSlope() || (fakeHeight < viewpoint.Pos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)))
|
|
||||||
{
|
|
||||||
RenderPolyPlane plane;
|
|
||||||
plane.Render3DFloor(worldToClip, clipPlane, sub, stencilValue, false, fakeFloor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3D floor ceilings
|
|
||||||
for (int i = 0; i < (int)ffloors.Size(); i++)
|
|
||||||
{
|
|
||||||
F3DFloor *fakeFloor = ffloors[i];
|
|
||||||
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
|
||||||
if (!fakeFloor->model) continue;
|
|
||||||
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
|
||||||
// R_3D_AddHeight(fakeFloor->bottom.plane, frontsector);
|
|
||||||
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
|
||||||
if (fakeFloor->alpha == 0) continue;
|
|
||||||
if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue;
|
|
||||||
//fakeFloor->alpha
|
|
||||||
|
|
||||||
double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
|
|
||||||
if (fakeFloor->bottom.plane->isSlope() || (fakeHeight > viewpoint.Pos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)))
|
|
||||||
{
|
|
||||||
RenderPolyPlane plane;
|
|
||||||
plane.Render3DFloor(worldToClip, clipPlane, sub, stencilValue, true, fakeFloor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||||
{
|
{
|
||||||
if (sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
if (sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
||||||
|
@ -97,59 +44,6 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipP
|
||||||
plane.Render(worldToClip, clipPlane, cull, sub, stencilValue, false, skyFloorHeight, sectorPortals);
|
plane.Render(worldToClip, clipPlane, cull, sub, stencilValue, false, skyFloorHeight, sectorPortals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
|
|
||||||
{
|
|
||||||
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
|
|
||||||
FTexture *tex = TexMan(picnum);
|
|
||||||
if (tex->UseType == FTexture::TEX_Null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
|
||||||
|
|
||||||
int lightlevel = 255;
|
|
||||||
bool foggy = false;
|
|
||||||
if (cameraLight->FixedLightLevel() < 0 && sub->sector->e->XFloor.lightlist.Size())
|
|
||||||
{
|
|
||||||
lightlist_t *light = P_GetPlaneLight(sub->sector, &sub->sector->ceilingplane, false);
|
|
||||||
//basecolormap = light->extra_colormap;
|
|
||||||
lightlevel = *light->p_lightlevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
|
||||||
lightlevel = clamp(lightlevel + actualextralight, 0, 255);
|
|
||||||
|
|
||||||
PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
|
|
||||||
|
|
||||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
|
||||||
if (ceiling)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
|
||||||
{
|
|
||||||
seg_t *line = &sub->firstline[i];
|
|
||||||
vertices[sub->numlines - 1 - i] = xform.GetVertex(line->v1, fakeFloor->bottom.plane->ZatPoint(line->v1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
|
||||||
{
|
|
||||||
seg_t *line = &sub->firstline[i];
|
|
||||||
vertices[i] = xform.GetVertex(line->v1, fakeFloor->top.plane->ZatPoint(line->v1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PolyDrawArgs args;
|
|
||||||
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
|
||||||
args.SetTransform(&worldToClip);
|
|
||||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
|
||||||
args.SetFaceCullCCW(true);
|
|
||||||
args.SetStencilTestValue(stencilValue);
|
|
||||||
args.SetWriteStencil(true, stencilValue + 1);
|
|
||||||
args.SetTexture(tex);
|
|
||||||
args.SetClipPlane(0, clipPlane);
|
|
||||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||||
{
|
{
|
||||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||||
|
@ -487,3 +381,161 @@ float PolyPlaneUVTransform::GetV(float x, float y) const
|
||||||
{
|
{
|
||||||
return (yOffs - x * sine - y * cosine) * yscale;
|
return (yOffs - x * sine - y * cosine) * yscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Render3DFloorPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects)
|
||||||
|
{
|
||||||
|
if (!r_3dfloors || sub->sector->CenterFloor() == sub->sector->CenterCeiling())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||||
|
|
||||||
|
auto frontsector = sub->sector;
|
||||||
|
auto &ffloors = frontsector->e->XFloor.ffloors;
|
||||||
|
|
||||||
|
// 3D floor floors
|
||||||
|
for (int i = 0; i < (int)ffloors.Size(); i++)
|
||||||
|
{
|
||||||
|
F3DFloor *fakeFloor = ffloors[i];
|
||||||
|
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
||||||
|
if (!fakeFloor->model) continue;
|
||||||
|
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
||||||
|
// R_3D_AddHeight(fakeFloor->top.plane, frontsector);
|
||||||
|
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
||||||
|
if (fakeFloor->alpha == 0) continue;
|
||||||
|
if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue;
|
||||||
|
//fakeFloor->alpha
|
||||||
|
|
||||||
|
double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
|
||||||
|
if (fakeFloor->bottom.plane->isSlope() || (fakeHeight < viewpoint.Pos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)))
|
||||||
|
{
|
||||||
|
Render3DFloorPlane plane;
|
||||||
|
plane.sub = sub;
|
||||||
|
plane.stencilValue = stencilValue;
|
||||||
|
plane.ceiling = false;
|
||||||
|
plane.fakeFloor = fakeFloor;
|
||||||
|
plane.Additive = !!(fakeFloor->flags & FF_ADDITIVETRANS);
|
||||||
|
if (!plane.Additive && fakeFloor->alpha == 255)
|
||||||
|
{
|
||||||
|
plane.Masked = false;
|
||||||
|
plane.Alpha = 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plane.Masked = true;
|
||||||
|
plane.Alpha = fakeFloor->alpha / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plane.Masked)
|
||||||
|
plane.Render(worldToClip, clipPlane);
|
||||||
|
else
|
||||||
|
translucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(plane, subsectorDepth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3D floor ceilings
|
||||||
|
for (int i = 0; i < (int)ffloors.Size(); i++)
|
||||||
|
{
|
||||||
|
F3DFloor *fakeFloor = ffloors[i];
|
||||||
|
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
||||||
|
if (!fakeFloor->model) continue;
|
||||||
|
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
||||||
|
// R_3D_AddHeight(fakeFloor->bottom.plane, frontsector);
|
||||||
|
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
||||||
|
if (fakeFloor->alpha == 0) continue;
|
||||||
|
if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue;
|
||||||
|
//fakeFloor->alpha
|
||||||
|
|
||||||
|
double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
|
||||||
|
if (fakeFloor->bottom.plane->isSlope() || (fakeHeight > viewpoint.Pos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)))
|
||||||
|
{
|
||||||
|
Render3DFloorPlane plane;
|
||||||
|
plane.sub = sub;
|
||||||
|
plane.stencilValue = stencilValue;
|
||||||
|
plane.ceiling = true;
|
||||||
|
plane.fakeFloor = fakeFloor;
|
||||||
|
plane.Additive = !!(fakeFloor->flags & FF_ADDITIVETRANS);
|
||||||
|
if (!plane.Additive && fakeFloor->alpha == 255)
|
||||||
|
{
|
||||||
|
plane.Masked = false;
|
||||||
|
plane.Alpha = 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plane.Masked = true;
|
||||||
|
plane.Alpha = fakeFloor->alpha / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plane.Masked)
|
||||||
|
plane.Render(worldToClip, clipPlane);
|
||||||
|
else
|
||||||
|
translucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(plane, subsectorDepth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render3DFloorPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane)
|
||||||
|
{
|
||||||
|
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
|
||||||
|
FTexture *tex = TexMan(picnum);
|
||||||
|
if (tex->UseType == FTexture::TEX_Null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||||
|
|
||||||
|
int lightlevel = 255;
|
||||||
|
bool foggy = false;
|
||||||
|
if (cameraLight->FixedLightLevel() < 0 && sub->sector->e->XFloor.lightlist.Size())
|
||||||
|
{
|
||||||
|
lightlist_t *light = P_GetPlaneLight(sub->sector, &sub->sector->ceilingplane, false);
|
||||||
|
//basecolormap = light->extra_colormap;
|
||||||
|
lightlevel = *light->p_lightlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4;
|
||||||
|
lightlevel = clamp(lightlevel + actualextralight, 0, 255);
|
||||||
|
|
||||||
|
PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
|
||||||
|
|
||||||
|
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
||||||
|
if (ceiling)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
vertices[sub->numlines - 1 - i] = xform.GetVertex(line->v1, fakeFloor->bottom.plane->ZatPoint(line->v1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
vertices[i] = xform.GetVertex(line->v1, fakeFloor->top.plane->ZatPoint(line->v1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PolyDrawArgs args;
|
||||||
|
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
||||||
|
args.SetTransform(&worldToClip);
|
||||||
|
if (!Masked)
|
||||||
|
{
|
||||||
|
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double srcalpha = MIN(Alpha, 1.0);
|
||||||
|
double destalpha = Additive ? 1.0 : 1.0 - srcalpha;
|
||||||
|
args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha);
|
||||||
|
args.SetDepthTest(true);
|
||||||
|
args.SetWriteDepth(true);
|
||||||
|
args.SetWriteStencil(false);
|
||||||
|
}
|
||||||
|
args.SetFaceCullCCW(true);
|
||||||
|
args.SetStencilTestValue(stencilValue);
|
||||||
|
args.SetWriteStencil(true, stencilValue + 1);
|
||||||
|
args.SetTexture(tex);
|
||||||
|
args.SetClipPlane(0, clipPlane);
|
||||||
|
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||||
|
}
|
||||||
|
|
|
@ -49,10 +49,24 @@ class RenderPolyPlane
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||||
static void Render3DPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
|
|
||||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||||
void RenderSkyWalls(PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform);
|
void RenderSkyWalls(PolyDrawArgs &args, subsector_t *sub, sector_t *frontsector, FSectorPortal *portal, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight, const PolyPlaneUVTransform &transform);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Render3DFloorPlane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t stencilValue, uint32_t subsectorDepth, std::vector<PolyTranslucentObject *> &translucentObjects);
|
||||||
|
|
||||||
|
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane);
|
||||||
|
|
||||||
|
subsector_t *sub = nullptr;
|
||||||
|
uint32_t stencilValue = 0;
|
||||||
|
bool ceiling = false;
|
||||||
|
F3DFloor *fakeFloor = nullptr;
|
||||||
|
bool Masked = false;
|
||||||
|
bool Additive = false;
|
||||||
|
double Alpha = 1.0;
|
||||||
|
};
|
||||||
|
|
|
@ -168,12 +168,12 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub, uint32_t ceilingSubsecto
|
||||||
RenderPolyNode(&sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
RenderPolyNode(&sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPolyPlane::Render3DPlanes(WorldToClip, PortalPlane, sub, StencilValue);
|
Render3DFloorPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, TranslucentObjects);
|
||||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RenderPolyPlane::Render3DPlanes(WorldToClip, PortalPlane, sub, StencilValue);
|
Render3DFloorPlane::RenderPlanes(WorldToClip, PortalPlane, sub, StencilValue, subsectorDepth, TranslucentObjects);
|
||||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
@ -458,21 +458,26 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
||||||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||||
{
|
{
|
||||||
PolyTranslucentObject *obj = *it;
|
PolyTranslucentObject *obj = *it;
|
||||||
if (obj->particle)
|
// To do: convert PolyTranslucentObject to an interface with subclasses!
|
||||||
|
if (obj->type == PolyTranslucentObjectType::Particle)
|
||||||
{
|
{
|
||||||
RenderPolyParticle spr;
|
RenderPolyParticle spr;
|
||||||
spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, StencilValue + 1);
|
spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, StencilValue + 1);
|
||||||
}
|
}
|
||||||
else if (!obj->thing)
|
else if (obj->type == PolyTranslucentObjectType::Wall)
|
||||||
{
|
{
|
||||||
obj->wall.Render(WorldToClip, PortalPlane);
|
obj->wall.Render(WorldToClip, PortalPlane);
|
||||||
}
|
}
|
||||||
else if ((obj->thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
else if (obj->type == PolyTranslucentObjectType::Plane)
|
||||||
|
{
|
||||||
|
obj->plane.Render(WorldToClip, PortalPlane);
|
||||||
|
}
|
||||||
|
else if (obj->type == PolyTranslucentObjectType::Thing && (obj->thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||||
{
|
{
|
||||||
RenderPolyWallSprite wallspr;
|
RenderPolyWallSprite wallspr;
|
||||||
wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1);
|
wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1);
|
||||||
}
|
}
|
||||||
else
|
else if (obj->type == PolyTranslucentObjectType::Thing)
|
||||||
{
|
{
|
||||||
RenderPolySprite spr;
|
RenderPolySprite spr;
|
||||||
spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
|
spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
|
||||||
|
|
|
@ -39,23 +39,34 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
enum class PolyTranslucentObjectType
|
||||||
|
{
|
||||||
|
Particle,
|
||||||
|
Thing,
|
||||||
|
Wall,
|
||||||
|
Plane
|
||||||
|
};
|
||||||
|
|
||||||
class PolyTranslucentObject
|
class PolyTranslucentObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PolyTranslucentObject(particle_t *particle, subsector_t *sub, uint32_t subsectorDepth) : particle(particle), sub(sub), subsectorDepth(subsectorDepth) { }
|
PolyTranslucentObject(particle_t *particle, subsector_t *sub, uint32_t subsectorDepth) : type(PolyTranslucentObjectType::Particle), particle(particle), sub(sub), subsectorDepth(subsectorDepth) { }
|
||||||
PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth, double dist, float t1, float t2) : thing(thing), sub(sub), subsectorDepth(subsectorDepth), DistanceSquared(dist), SpriteLeft(t1), SpriteRight(t2) { }
|
PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth, double dist, float t1, float t2) : type(PolyTranslucentObjectType::Thing), thing(thing), sub(sub), subsectorDepth(subsectorDepth), DistanceSquared(dist), SpriteLeft(t1), SpriteRight(t2) { }
|
||||||
PolyTranslucentObject(RenderPolyWall wall) : wall(wall), subsectorDepth(wall.SubsectorDepth), DistanceSquared(1.e6) { }
|
PolyTranslucentObject(RenderPolyWall wall) : type(PolyTranslucentObjectType::Wall), wall(wall), subsectorDepth(wall.SubsectorDepth), DistanceSquared(1.e6) { }
|
||||||
|
PolyTranslucentObject(Render3DFloorPlane plane, uint32_t subsectorDepth) : type(PolyTranslucentObjectType::Plane), plane(plane), subsectorDepth(subsectorDepth), DistanceSquared(1.e7) { }
|
||||||
|
|
||||||
bool operator<(const PolyTranslucentObject &other) const
|
bool operator<(const PolyTranslucentObject &other) const
|
||||||
{
|
{
|
||||||
return subsectorDepth != other.subsectorDepth ? subsectorDepth < other.subsectorDepth : DistanceSquared < other.DistanceSquared;
|
return subsectorDepth != other.subsectorDepth ? subsectorDepth < other.subsectorDepth : DistanceSquared < other.DistanceSquared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PolyTranslucentObjectType type;
|
||||||
particle_t *particle = nullptr;
|
particle_t *particle = nullptr;
|
||||||
AActor *thing = nullptr;
|
AActor *thing = nullptr;
|
||||||
subsector_t *sub = nullptr;
|
subsector_t *sub = nullptr;
|
||||||
|
|
||||||
RenderPolyWall wall;
|
RenderPolyWall wall;
|
||||||
|
Render3DFloorPlane plane;
|
||||||
|
|
||||||
uint32_t subsectorDepth = 0;
|
uint32_t subsectorDepth = 0;
|
||||||
double DistanceSquared = 0.0;
|
double DistanceSquared = 0.0;
|
||||||
|
|
Loading…
Reference in a new issue