mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
- Move polyobj rendering to be handled as a special case in RenderPolyScene
This commit is contained in:
parent
f7d1a2a574
commit
5c6cbd17a1
3 changed files with 106 additions and 32 deletions
|
@ -70,26 +70,6 @@ void PolyCull::CullNode(void *node)
|
|||
|
||||
void PolyCull::CullSubsector(subsector_t *sub)
|
||||
{
|
||||
// Mark poly objects first
|
||||
if (sub->polys)
|
||||
{
|
||||
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||
{
|
||||
sub->BuildPolyBSP();
|
||||
}
|
||||
|
||||
if (sub->BSP->Nodes.Size() == 0)
|
||||
{
|
||||
CullSubsector(&sub->BSP->Subsectors[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
CullNode(&sub->BSP->Nodes.Last());
|
||||
}
|
||||
|
||||
return; // Hmm, seems a bit strange the subsector is then ignored. But that's what the sw renderer seems to be doing..
|
||||
}
|
||||
|
||||
// Update sky heights for the scene
|
||||
if (!FirstSkyHeight)
|
||||
{
|
||||
|
|
|
@ -111,25 +111,48 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
|
||||
uint32_t subsectorDepth = NextSubsectorDepth++;
|
||||
|
||||
bool mainBSP = sub->polys == nullptr;
|
||||
|
||||
if (sub->polys)
|
||||
{
|
||||
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||
{
|
||||
sub->BuildPolyBSP();
|
||||
|
||||
// This is done by the GL renderer, but not the sw renderer. No idea what the purpose is..
|
||||
for (unsigned i = 0; i < sub->BSP->Segs.Size(); i++)
|
||||
{
|
||||
sub->BSP->Segs[i].Subsector = sub;
|
||||
sub->BSP->Segs[i].PartnerSeg = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (sub->BSP->Nodes.Size() == 0)
|
||||
{
|
||||
RenderPolySubsector(&sub->BSP->Subsectors[0], subsectorDepth, frontsector);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderPolyNode(&sub->BSP->Nodes.Last(), subsectorDepth, frontsector);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
RenderLine(sub, line, frontsector, subsectorDepth);
|
||||
}
|
||||
}
|
||||
|
||||
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
||||
{
|
||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
if (line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
RenderLine(sub, line, frontsector, subsectorDepth);
|
||||
}
|
||||
}
|
||||
|
||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||
|
||||
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
|
||||
if (mainBSP)
|
||||
{
|
||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||
int subsectorIndex = sub->Index();
|
||||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
|
@ -142,6 +165,73 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
SubsectorDepths[sub] = subsectorDepth;
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
{
|
||||
while (!((size_t)node & 1)) // Keep going until found a subsector
|
||||
{
|
||||
node_t *bsp = (node_t *)node;
|
||||
|
||||
// Decide which side the view point is on.
|
||||
int side = PointOnSide(PolyRenderer::Instance()->Viewpoint.Pos, bsp);
|
||||
|
||||
// Recursively divide front space (toward the viewer).
|
||||
RenderPolyNode(bsp->children[side], subsectorDepth, frontsector);
|
||||
|
||||
// Possibly divide back space (away from the viewer).
|
||||
side ^= 1;
|
||||
|
||||
// Don't bother culling on poly objects
|
||||
//if (!CheckBBox(bsp->bbox[side]))
|
||||
// return;
|
||||
|
||||
node = bsp->children[side];
|
||||
}
|
||||
|
||||
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||
RenderPolySubsector(sub, subsectorDepth, frontsector);
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
seg_t *line = &sub->firstline[i];
|
||||
if (line->linedef)
|
||||
{
|
||||
// Reject lines not facing viewer
|
||||
DVector2 pt1 = line->v1->fPos() - viewpoint.Pos;
|
||||
DVector2 pt2 = line->v2->fPos() - viewpoint.Pos;
|
||||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
continue;
|
||||
|
||||
// Cull wall if not visible
|
||||
angle_t angle1, angle2;
|
||||
if (!Cull.GetAnglesForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), angle1, angle2))
|
||||
continue;
|
||||
|
||||
// Tell automap we saw this
|
||||
if (!PolyRenderer::Instance()->DontMapLines && line->linedef)
|
||||
{
|
||||
line->linedef->flags |= ML_MAPPED;
|
||||
sub->flags |= SSECF_DRAWN;
|
||||
}
|
||||
|
||||
// Render wall, and update culling info if its an occlusion blocker
|
||||
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, Cull, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals))
|
||||
{
|
||||
Cull.MarkSegmentCulled(angle1, angle2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RenderPolyScene::PointOnSide(const DVector2 &pos, const node_t *node)
|
||||
{
|
||||
return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0;
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right)
|
||||
{
|
||||
if (level.nodes.Size() == 0)
|
||||
|
|
|
@ -89,6 +89,10 @@ private:
|
|||
void RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right);
|
||||
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
||||
|
||||
void RenderPolySubsector(subsector_t *sub, uint32_t subsectorDepth, sector_t *frontsector);
|
||||
void RenderPolyNode(void *node, uint32_t subsectorDepth, sector_t *frontsector);
|
||||
static int PointOnSide(const DVector2 &pos, const node_t *node);
|
||||
|
||||
TriMatrix WorldToClip;
|
||||
PolyClipPlane PortalPlane;
|
||||
uint32_t StencilValue = 0;
|
||||
|
|
Loading…
Reference in a new issue