mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- draw models in mirrors and portals at the right location in the software renderer
This commit is contained in:
parent
512082b222
commit
b74a9965b8
5 changed files with 42 additions and 8 deletions
|
@ -173,6 +173,7 @@ namespace swrenderer
|
|||
Thread->Viewport->viewpoint.sector = port->mDestination;
|
||||
assert(Thread->Viewport->viewpoint.sector != nullptr);
|
||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
Thread->OpaquePass->ClearSeenSprites();
|
||||
Thread->Clip3D->ClearFakeFloors();
|
||||
|
||||
|
@ -239,6 +240,7 @@ namespace swrenderer
|
|||
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||
viewposStack.Pop(Thread->Viewport->viewpoint.Pos);
|
||||
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
Thread->TranslucentPass->Render();
|
||||
|
||||
VisiblePlane *pl = nullptr; // quiet, GCC!
|
||||
|
@ -259,6 +261,7 @@ namespace swrenderer
|
|||
Thread->Viewport->viewpoint.extralight = savedextralight;
|
||||
Thread->Viewport->viewpoint.Angles = savedangles;
|
||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
|
||||
CurrentPortalInSkybox = false;
|
||||
Thread->Clip3D->LeaveSkybox();
|
||||
|
@ -426,6 +429,8 @@ namespace swrenderer
|
|||
else MirrorFlags |= RF_XFLIP;
|
||||
}
|
||||
|
||||
Thread->Viewport->SetupPolyViewport(Thread);
|
||||
|
||||
// some portals have height differences, account for this here
|
||||
Thread->Clip3D->EnterSkybox(); // push 3D floor height map
|
||||
CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.
|
||||
|
@ -478,6 +483,8 @@ namespace swrenderer
|
|||
viewpoint.Pos = startpos;
|
||||
viewpoint.Path[0] = savedpath[0];
|
||||
viewpoint.Path[1] = savedpath[1];
|
||||
|
||||
viewport->SetupPolyViewport(Thread);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -159,6 +159,8 @@ namespace swrenderer
|
|||
if (r_models)
|
||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||
|
||||
FRenderViewpoint origviewpoint = MainThread()->Viewport->viewpoint;
|
||||
|
||||
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
|
||||
// Never draw the player unless in chasecam mode
|
||||
if (!MainThread()->Viewport->viewpoint.showviewer)
|
||||
|
@ -167,6 +169,12 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
RenderThreadSlices();
|
||||
|
||||
// Mirrors fail to restore the original viewpoint -- we need it for the HUD weapon to draw correctly.
|
||||
MainThread()->Viewport->viewpoint = origviewpoint;
|
||||
if (r_models)
|
||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||
|
||||
RenderPSprites();
|
||||
|
||||
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
||||
|
|
|
@ -47,12 +47,22 @@ namespace swrenderer
|
|||
if (tz < MINZ)
|
||||
return;
|
||||
|
||||
// too far off the side?
|
||||
double tx = tr_x * thread->Viewport->viewpoint.Sin - tr_y * thread->Viewport->viewpoint.Cos;
|
||||
|
||||
// Flip for mirrors
|
||||
if (thread->Portal->MirrorFlags & RF_XFLIP)
|
||||
{
|
||||
tx = viewwidth - tx - 1;
|
||||
}
|
||||
|
||||
// too far off the side?
|
||||
if (fabs(tx / 64) > fabs(tz))
|
||||
return;
|
||||
|
||||
RenderModel *vis = thread->FrameMemory->NewObject<RenderModel>(x, y, z, smf, actor, float(1 / tz));
|
||||
vis->CurrentPortalUniq = thread->Portal->CurrentPortalUniq;
|
||||
vis->WorldToClip = thread->Viewport->WorldToClip;
|
||||
vis->MirrorWorldToClip = !!(thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
thread->SpriteList->Push(vis);
|
||||
}
|
||||
|
||||
|
@ -64,7 +74,7 @@ namespace swrenderer
|
|||
|
||||
void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor)
|
||||
{
|
||||
SWModelRenderer renderer(thread, clip3DFloor);
|
||||
SWModelRenderer renderer(thread, clip3DFloor, &WorldToClip, MirrorWorldToClip);
|
||||
renderer.RenderModel(x, y, z, smf, actor);
|
||||
}
|
||||
|
||||
|
@ -72,13 +82,14 @@ namespace swrenderer
|
|||
|
||||
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
|
||||
{
|
||||
SWModelRenderer renderer(thread, Fake3DTranslucent());
|
||||
SWModelRenderer renderer(thread, Fake3DTranslucent(), &thread->Viewport->WorldToClip, false);
|
||||
renderer.RenderHUDModel(psp, ofsx, ofsy);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor)
|
||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip)
|
||||
: Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -123,7 +134,7 @@ namespace swrenderer
|
|||
|
||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !mirrored);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||
|
@ -194,7 +205,7 @@ namespace swrenderer
|
|||
|
||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, mirrored);
|
||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||
|
@ -225,7 +236,7 @@ namespace swrenderer
|
|||
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
|
||||
swapYZ.Matrix[3 + 3 * 4] = 1.0f;
|
||||
|
||||
PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject<Mat4f>(Thread->Viewport->WorldToClip * swapYZ * ObjectToWorld));
|
||||
PolyTriangleDrawer::SetTransform(Thread->DrawQueue, Thread->FrameMemory->NewObject<Mat4f>((*WorldToClip) * swapYZ * ObjectToWorld));
|
||||
}
|
||||
|
||||
void SWModelRenderer::DrawArrays(int start, int count)
|
||||
|
|
|
@ -47,12 +47,14 @@ namespace swrenderer
|
|||
float x, y, z;
|
||||
FSpriteModelFrame *smf;
|
||||
AActor *actor;
|
||||
Mat4f WorldToClip;
|
||||
bool MirrorWorldToClip;
|
||||
};
|
||||
|
||||
class SWModelRenderer : public FModelRenderer
|
||||
{
|
||||
public:
|
||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor);
|
||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip);
|
||||
|
||||
ModelRendererType GetType() const override { return SWModelRendererType; }
|
||||
|
||||
|
@ -81,6 +83,8 @@ namespace swrenderer
|
|||
unsigned int *IndexBuffer = nullptr;
|
||||
TriVertex *VertexBuffer = nullptr;
|
||||
float InterpolationFactor = 0.0;
|
||||
Mat4f *WorldToClip = nullptr;
|
||||
bool MirrorWorldToClip = false;
|
||||
};
|
||||
|
||||
class SWModelVertexBuffer : public IModelVertexBuffer
|
||||
|
|
|
@ -62,6 +62,10 @@ namespace swrenderer
|
|||
void RenderViewport::SetupPolyViewport(RenderThread *thread)
|
||||
{
|
||||
WorldToView = SoftwareWorldToView(viewpoint);
|
||||
|
||||
if (thread->Portal->MirrorFlags & RF_XFLIP)
|
||||
WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * WorldToView;
|
||||
|
||||
ViewToClip = SoftwareViewToClip();
|
||||
WorldToClip = ViewToClip * WorldToView;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue