- fix softpoly mirrors

This commit is contained in:
Magnus Norddahl 2018-04-22 23:29:39 +02:00
parent ee9fa7c33e
commit 6e77cb4906
7 changed files with 37 additions and 25 deletions

View file

@ -74,9 +74,9 @@ void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const
queue->Push<PolySetTransformCommand>(objectToClip); queue->Push<PolySetTransformCommand>(objectToClip);
} }
void PolyTriangleDrawer::ToggleMirror(const DrawerCommandQueuePtr &queue) void PolyTriangleDrawer::SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw)
{ {
queue->Push<PolyToggleMirrorCommand>(); queue->Push<PolySetCullCCWCommand>(ccw);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -93,7 +93,7 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui
dest_pitch = new_dest_pitch; dest_pitch = new_dest_pitch;
dest_bgra = new_dest_bgra; dest_bgra = new_dest_bgra;
span_drawers = new_span_drawers; span_drawers = new_span_drawers;
mirror = false; ccw = true;
} }
void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip) void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip)
@ -118,7 +118,6 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs)
args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.zbuffer = PolyZBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values();
bool ccw = !mirror;
const TriVertex *vinput = drawargs.Vertices(); const TriVertex *vinput = drawargs.Vertices();
const unsigned int *elements = drawargs.Elements(); const unsigned int *elements = drawargs.Elements();
int vcount = drawargs.VertexCount(); int vcount = drawargs.VertexCount();
@ -146,15 +145,16 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs)
} }
else // TriangleDrawMode::TriangleStrip else // TriangleDrawMode::TriangleStrip
{ {
bool toggleccw = ccw;
vert[0] = ShadeVertex(drawargs, vinput[*(elements++)]); vert[0] = ShadeVertex(drawargs, vinput[*(elements++)]);
vert[1] = ShadeVertex(drawargs, vinput[*(elements++)]); vert[1] = ShadeVertex(drawargs, vinput[*(elements++)]);
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = ShadeVertex(drawargs, vinput[*(elements++)]); vert[2] = ShadeVertex(drawargs, vinput[*(elements++)]);
DrawShadedTriangle(vert, ccw, &args); DrawShadedTriangle(vert, toggleccw, &args);
vert[0] = vert[1]; vert[0] = vert[1];
vert[1] = vert[2]; vert[1] = vert[2];
ccw = !ccw; toggleccw = !toggleccw;
} }
} }
} }
@ -176,7 +176,6 @@ void PolyTriangleThreadData::DrawArrays(const PolyDrawArgs &drawargs)
args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.zbuffer = PolyZBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values();
bool ccw = !mirror;
const TriVertex *vinput = drawargs.Vertices(); const TriVertex *vinput = drawargs.Vertices();
int vcount = drawargs.VertexCount(); int vcount = drawargs.VertexCount();
@ -203,15 +202,16 @@ void PolyTriangleThreadData::DrawArrays(const PolyDrawArgs &drawargs)
} }
else // TriangleDrawMode::TriangleStrip else // TriangleDrawMode::TriangleStrip
{ {
bool toggleccw = ccw;
vert[0] = ShadeVertex(drawargs, *(vinput++)); vert[0] = ShadeVertex(drawargs, *(vinput++));
vert[1] = ShadeVertex(drawargs, *(vinput++)); vert[1] = ShadeVertex(drawargs, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = ShadeVertex(drawargs, *(vinput++)); vert[2] = ShadeVertex(drawargs, *(vinput++));
DrawShadedTriangle(vert, ccw, &args); DrawShadedTriangle(vert, toggleccw, &args);
vert[0] = vert[1]; vert[0] = vert[1];
vert[1] = vert[2]; vert[1] = vert[2];
ccw = !ccw; toggleccw = !toggleccw;
} }
} }
} }
@ -569,9 +569,13 @@ void PolySetTransformCommand::Execute(DrawerThread *thread)
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
void PolyToggleMirrorCommand::Execute(DrawerThread *thread) PolySetCullCCWCommand::PolySetCullCCWCommand(bool ccw) : ccw(ccw)
{ {
PolyTriangleThreadData::Get(thread)->ToggleMirror(); }
void PolySetCullCCWCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetCullCCW(ccw);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -34,7 +34,7 @@ class PolyTriangleDrawer
public: public:
static void ClearBuffers(DCanvas *canvas); static void ClearBuffers(DCanvas *canvas);
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers); static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers);
static void ToggleMirror(const DrawerCommandQueuePtr &queue); static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip); static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip);
}; };
@ -45,7 +45,7 @@ public:
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers); void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers);
void SetTransform(const Mat4f *objectToClip); void SetTransform(const Mat4f *objectToClip);
void ToggleMirror() { mirror = !mirror; } void SetCullCCW(bool value) { ccw = value; }
void DrawElements(const PolyDrawArgs &args); void DrawElements(const PolyDrawArgs &args);
void DrawArrays(const PolyDrawArgs &args); void DrawArrays(const PolyDrawArgs &args);
@ -78,7 +78,7 @@ private:
int dest_height = 0; int dest_height = 0;
bool dest_bgra = false; bool dest_bgra = false;
uint8_t *dest = nullptr; uint8_t *dest = nullptr;
bool mirror = false; bool ccw = true;
const Mat4f *objectToClip = nullptr; const Mat4f *objectToClip = nullptr;
bool span_drawers = false; bool span_drawers = false;
@ -97,11 +97,16 @@ private:
const Mat4f *objectToClip; const Mat4f *objectToClip;
}; };
class PolyToggleMirrorCommand : public DrawerCommand class PolySetCullCCWCommand : public DrawerCommand
{ {
public: public:
PolySetCullCCWCommand(bool ccw);
void Execute(DrawerThread *thread) override; void Execute(DrawerThread *thread) override;
FString DebugInfo() override { return "PolyToggleMirror"; } FString DebugInfo() override { return "PolySetCullCCWCommand"; }
private:
bool ccw;
}; };
class PolySetViewportCommand : public DrawerCommand class PolySetViewportCommand : public DrawerCommand

View file

@ -210,7 +210,7 @@ void PolyRenderer::SetSceneViewport()
} }
} }
PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix() PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix(bool mirror)
{ {
// We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1.
double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians();
@ -235,6 +235,11 @@ PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix()
Mat4f::SwapYZ() * Mat4f::SwapYZ() *
Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z);
portalViewpoint.Mirror = mirror;
if (mirror)
portalViewpoint.WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * portalViewpoint.WorldToView;
portalViewpoint.WorldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * portalViewpoint.WorldToView; portalViewpoint.WorldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * portalViewpoint.WorldToView;
return portalViewpoint; return portalViewpoint;

View file

@ -55,7 +55,7 @@ public:
static PolyRenderer *Instance(); static PolyRenderer *Instance();
PolyPortalViewpoint SetupPerspectiveMatrix(); PolyPortalViewpoint SetupPerspectiveMatrix(bool mirror = false);
uint32_t GetNextStencilValue() { uint32_t value = NextStencilValue; NextStencilValue += 2; return value; } uint32_t GetNextStencilValue() { uint32_t value = NextStencilValue; NextStencilValue += 2; return value; }

View file

@ -150,7 +150,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
Segments.clear(); Segments.clear();
Segments.push_back({ angle1, angle2 });*/ Segments.push_back({ angle1, angle2 });*/
PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(); PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror);
PortalViewpoint.StencilValue = StencilValue; PortalViewpoint.StencilValue = StencilValue;
PortalViewpoint.PortalPlane = portalPlane; PortalViewpoint.PortalPlane = portalPlane;
PortalViewpoint.PortalDepth = portalDepth; PortalViewpoint.PortalDepth = portalDepth;
@ -248,9 +248,6 @@ void PolyDrawLinePortal::SaveGlobals()
viewpoint.sector = R_PointInSubsector(viewpoint.Pos)->sector; viewpoint.sector = R_PointInSubsector(viewpoint.Pos)->sector;
R_SetViewAngle(viewpoint, viewwindow); R_SetViewAngle(viewpoint, viewwindow);
if (Mirror)
PolyTriangleDrawer::ToggleMirror(PolyRenderer::Instance()->Threads.MainThread()->DrawQueue);
} }
void PolyDrawLinePortal::RestoreGlobals() void PolyDrawLinePortal::RestoreGlobals()
@ -269,7 +266,4 @@ void PolyDrawLinePortal::RestoreGlobals()
} }
R_SetViewAngle(viewpoint, viewwindow); R_SetViewAngle(viewpoint, viewwindow);
if (Mirror)
PolyTriangleDrawer::ToggleMirror(PolyRenderer::Instance()->Threads.MainThread()->DrawQueue);
} }

View file

@ -103,6 +103,7 @@ void RenderPolyScene::RenderSectors()
PolyRenderer::Instance()->Threads.RenderThreadSlices(totalcount, [&](PolyRenderThread *thread) PolyRenderer::Instance()->Threads.RenderThreadSlices(totalcount, [&](PolyRenderThread *thread)
{ {
PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror);
PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip)); PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip));
if (thread != mainthread) if (thread != mainthread)
@ -334,6 +335,7 @@ void RenderPolyScene::RenderPortals()
} }
Mat4f *transform = thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip); Mat4f *transform = thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip);
PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror);
PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform);
PolyDrawArgs args; PolyDrawArgs args;
@ -377,6 +379,7 @@ void RenderPolyScene::RenderTranslucent()
PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread();
Mat4f *transform = thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip); Mat4f *transform = thread->FrameMemory->NewObject<Mat4f>(CurrentViewpoint->WorldToClip);
PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror);
PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform);
PolyMaskedCycles.Clock(); PolyMaskedCycles.Clock();

View file

@ -63,6 +63,7 @@ public:
PolyClipPlane PortalPlane; PolyClipPlane PortalPlane;
uint32_t StencilValue = 0; uint32_t StencilValue = 0;
int PortalDepth = 0; int PortalDepth = 0;
bool Mirror = false;
line_t *PortalEnterLine = nullptr; line_t *PortalEnterLine = nullptr;