mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 13:31:37 +00:00
- fix softpoly mirrors
This commit is contained in:
parent
ee9fa7c33e
commit
6e77cb4906
7 changed files with 37 additions and 25 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue