diff --git a/src/r_poly_portal.cpp b/src/r_poly_portal.cpp index 1bb600779..96df9daf0 100644 --- a/src/r_poly_portal.cpp +++ b/src/r_poly_portal.cpp @@ -162,11 +162,14 @@ void PolyDrawLinePortal::Render(int portalDepth) TriMatrix::scale(1.0f, glset.pixelstretch, 1.0f) * TriMatrix::swapYZ() * TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z); + if (Mirror) + worldToView = TriMatrix::scale(-1.0f, 1.0f, 1.0f) * worldToView; TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView; // Calculate plane clipping - DVector2 planePos = Portal->mDestination->v1->fPos(); - DVector2 planeNormal = (Portal->mDestination->v2->fPos() - Portal->mDestination->v1->fPos()).Rotated90CW(); + line_t *clipLine = Portal ? Portal->mDestination : Mirror; + DVector2 planePos = clipLine->v1->fPos(); + DVector2 planeNormal = (clipLine->v2->fPos() - clipLine->v1->fPos()).Rotated90CW(); planeNormal.MakeUnit(); double planeD = -(planeNormal | (planePos + planeNormal * 0.001)); Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD); @@ -191,7 +194,7 @@ void PolyDrawLinePortal::SaveGlobals() savedangle = ViewAngle; savedcamera = camera; savedsector = viewsector; - savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0); + savedinvisibility = camera ? (camera->renderflags & RF_INVISIBLE) == RF_INVISIBLE : false; savedViewPath[0] = ViewPath[0]; savedViewPath[1] = ViewPath[1]; @@ -229,6 +232,9 @@ void PolyDrawLinePortal::SaveGlobals() ViewPos.Y = (y1 + r * dy) * 2 - y; } ViewAngle = Mirror->Delta().Angle() * 2 - startang; + + if (camera) + camera->renderflags &= ~RF_INVISIBLE; } else { @@ -255,22 +261,25 @@ void PolyDrawLinePortal::SaveGlobals() } } } - - /*if (Portal->mirror) - { - if (MirrorFlags & RF_XFLIP) MirrorFlags &= ~RF_XFLIP; - else MirrorFlags |= RF_XFLIP; - }*/ } - camera = nullptr; + //camera = nullptr; //viewsector = R_PointInSubsector(ViewPos)->sector; R_SetViewAngle(); + + if (Mirror) + PolyTriangleDrawer::toggle_mirror(); } void PolyDrawLinePortal::RestoreGlobals() { - if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE; + if (camera) + { + if (savedinvisibility) + camera->renderflags |= RF_INVISIBLE; + else + camera->renderflags &= ~RF_INVISIBLE; + } camera = savedcamera; viewsector = savedsector; ViewPos = savedpos; @@ -279,4 +288,7 @@ void PolyDrawLinePortal::RestoreGlobals() ViewPath[0] = savedViewPath[0]; ViewPath[1] = savedViewPath[1]; R_SetViewAngle(); + + if (Mirror) + PolyTriangleDrawer::toggle_mirror(); } diff --git a/src/r_poly_portal.h b/src/r_poly_portal.h index 7835bb042..6cad98ff6 100644 --- a/src/r_poly_portal.h +++ b/src/r_poly_portal.h @@ -85,6 +85,6 @@ private: DAngle savedangle; AActor *savedcamera; sector_t *savedsector; - ActorRenderFlags savedvisibility; + bool savedinvisibility; DVector3 savedViewPath[2]; }; diff --git a/src/r_poly_scene.cpp b/src/r_poly_scene.cpp index 7304000a6..ef2ef5f1b 100644 --- a/src/r_poly_scene.cpp +++ b/src/r_poly_scene.cpp @@ -121,9 +121,16 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub) void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right) { if (numnodes == 0) - RenderSprite(thing, sortDistance, left, right, 0.0, 1.0, subsectors); + { + subsector_t *sub = subsectors; + auto it = SubsectorDepths.find(sub); + if (it != SubsectorDepths.end()) + TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, 0.0f, 1.0f }); + } else + { RenderSprite(thing, sortDistance, left, right, 0.0, 1.0, nodes + numnodes - 1); // The head node is the last node output. + } } void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node) diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index 4b6e1c344..45f244aab 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -45,6 +45,7 @@ int PolyTriangleDrawer::dest_width; int PolyTriangleDrawer::dest_height; uint8_t *PolyTriangleDrawer::dest; bool PolyTriangleDrawer::dest_bgra; +bool PolyTriangleDrawer::mirror; void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanvas *canvas) { @@ -66,11 +67,18 @@ void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanv dest += (offsetx + offsety * dest_pitch) * pixelsize; dest_width = clamp(viewport_x + viewport_width, 0, dest_width - offsetx); dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety); + + mirror = false; +} + +void PolyTriangleDrawer::toggle_mirror() +{ + mirror = !mirror; } void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode) { - DrawerCommandQueue::QueueCommand(args, variant, blendmode); + DrawerCommandQueue::QueueCommand(args, variant, blendmode, mirror); } void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread) @@ -328,9 +336,11 @@ void PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clipp ///////////////////////////////////////////////////////////////////////////// -DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode) +DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, bool mirror) : args(args), variant(variant), blendmode(blendmode) { + if (mirror) + this->args.ccw = !this->args.ccw; } void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index 46948310f..ecf05a921 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -158,6 +158,7 @@ class PolyTriangleDrawer public: static void set_viewport(int x, int y, int width, int height, DCanvas *canvas); static void draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode); + static void toggle_mirror(); private: static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v); @@ -169,6 +170,7 @@ private: static int viewport_x, viewport_y, viewport_width, viewport_height, dest_pitch, dest_width, dest_height; static bool dest_bgra; static uint8_t *dest; + static bool mirror; enum { max_additional_vertices = 16 }; @@ -245,7 +247,7 @@ private: class DrawPolyTrianglesCommand : public DrawerCommand { public: - DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode); + DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, bool mirror); void Execute(DrawerThread *thread) override; FString DebugInfo() override;