mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +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;
|
Thread->Viewport->viewpoint.sector = port->mDestination;
|
||||||
assert(Thread->Viewport->viewpoint.sector != nullptr);
|
assert(Thread->Viewport->viewpoint.sector != nullptr);
|
||||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||||
|
Thread->Viewport->SetupPolyViewport(Thread);
|
||||||
Thread->OpaquePass->ClearSeenSprites();
|
Thread->OpaquePass->ClearSeenSprites();
|
||||||
Thread->Clip3D->ClearFakeFloors();
|
Thread->Clip3D->ClearFakeFloors();
|
||||||
|
|
||||||
|
@ -239,6 +240,7 @@ namespace swrenderer
|
||||||
// Masked textures and planes need the view coordinates restored for proper positioning.
|
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||||
viewposStack.Pop(Thread->Viewport->viewpoint.Pos);
|
viewposStack.Pop(Thread->Viewport->viewpoint.Pos);
|
||||||
|
|
||||||
|
Thread->Viewport->SetupPolyViewport(Thread);
|
||||||
Thread->TranslucentPass->Render();
|
Thread->TranslucentPass->Render();
|
||||||
|
|
||||||
VisiblePlane *pl = nullptr; // quiet, GCC!
|
VisiblePlane *pl = nullptr; // quiet, GCC!
|
||||||
|
@ -259,6 +261,7 @@ namespace swrenderer
|
||||||
Thread->Viewport->viewpoint.extralight = savedextralight;
|
Thread->Viewport->viewpoint.extralight = savedextralight;
|
||||||
Thread->Viewport->viewpoint.Angles = savedangles;
|
Thread->Viewport->viewpoint.Angles = savedangles;
|
||||||
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
R_SetViewAngle(Thread->Viewport->viewpoint, Thread->Viewport->viewwindow);
|
||||||
|
Thread->Viewport->SetupPolyViewport(Thread);
|
||||||
|
|
||||||
CurrentPortalInSkybox = false;
|
CurrentPortalInSkybox = false;
|
||||||
Thread->Clip3D->LeaveSkybox();
|
Thread->Clip3D->LeaveSkybox();
|
||||||
|
@ -426,6 +429,8 @@ namespace swrenderer
|
||||||
else MirrorFlags |= RF_XFLIP;
|
else MirrorFlags |= RF_XFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread->Viewport->SetupPolyViewport(Thread);
|
||||||
|
|
||||||
// some portals have height differences, account for this here
|
// some portals have height differences, account for this here
|
||||||
Thread->Clip3D->EnterSkybox(); // push 3D floor height map
|
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.
|
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.Pos = startpos;
|
||||||
viewpoint.Path[0] = savedpath[0];
|
viewpoint.Path[0] = savedpath[0];
|
||||||
viewpoint.Path[1] = savedpath[1];
|
viewpoint.Path[1] = savedpath[1];
|
||||||
|
|
||||||
|
viewport->SetupPolyViewport(Thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -159,6 +159,8 @@ namespace swrenderer
|
||||||
if (r_models)
|
if (r_models)
|
||||||
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
MainThread()->Viewport->SetupPolyViewport(MainThread());
|
||||||
|
|
||||||
|
FRenderViewpoint origviewpoint = MainThread()->Viewport->viewpoint;
|
||||||
|
|
||||||
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
|
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
|
||||||
// Never draw the player unless in chasecam mode
|
// Never draw the player unless in chasecam mode
|
||||||
if (!MainThread()->Viewport->viewpoint.showviewer)
|
if (!MainThread()->Viewport->viewpoint.showviewer)
|
||||||
|
@ -167,6 +169,12 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderThreadSlices();
|
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();
|
RenderPSprites();
|
||||||
|
|
||||||
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
MainThread()->Viewport->viewpoint.camera->renderflags = savedflags;
|
||||||
|
|
|
@ -47,12 +47,22 @@ namespace swrenderer
|
||||||
if (tz < MINZ)
|
if (tz < MINZ)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// too far off the side?
|
|
||||||
double tx = tr_x * thread->Viewport->viewpoint.Sin - tr_y * thread->Viewport->viewpoint.Cos;
|
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))
|
if (fabs(tx / 64) > fabs(tz))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RenderModel *vis = thread->FrameMemory->NewObject<RenderModel>(x, y, z, smf, actor, float(1 / tz));
|
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);
|
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)
|
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);
|
renderer.RenderModel(x, y, z, smf, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,13 +82,14 @@ namespace swrenderer
|
||||||
|
|
||||||
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
|
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);
|
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))
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] || !!(smf->flags & MDL_DONTCULLBACKFACES))
|
||||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !mirrored);
|
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||||
|
@ -194,7 +205,7 @@ namespace swrenderer
|
||||||
|
|
||||||
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
if (actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])
|
||||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||||
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, mirrored);
|
PolyTriangleDrawer::SetCullCCW(Thread->DrawQueue, !(mirrored ^ MirrorWorldToClip));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||||
|
@ -225,7 +236,7 @@ namespace swrenderer
|
||||||
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
|
swapYZ.Matrix[2 + 1 * 4] = 1.0f;
|
||||||
swapYZ.Matrix[3 + 3 * 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)
|
void SWModelRenderer::DrawArrays(int start, int count)
|
||||||
|
|
|
@ -47,12 +47,14 @@ namespace swrenderer
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
FSpriteModelFrame *smf;
|
FSpriteModelFrame *smf;
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
|
Mat4f WorldToClip;
|
||||||
|
bool MirrorWorldToClip;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SWModelRenderer : public FModelRenderer
|
class SWModelRenderer : public FModelRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor);
|
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip);
|
||||||
|
|
||||||
ModelRendererType GetType() const override { return SWModelRendererType; }
|
ModelRendererType GetType() const override { return SWModelRendererType; }
|
||||||
|
|
||||||
|
@ -81,6 +83,8 @@ namespace swrenderer
|
||||||
unsigned int *IndexBuffer = nullptr;
|
unsigned int *IndexBuffer = nullptr;
|
||||||
TriVertex *VertexBuffer = nullptr;
|
TriVertex *VertexBuffer = nullptr;
|
||||||
float InterpolationFactor = 0.0;
|
float InterpolationFactor = 0.0;
|
||||||
|
Mat4f *WorldToClip = nullptr;
|
||||||
|
bool MirrorWorldToClip = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SWModelVertexBuffer : public IModelVertexBuffer
|
class SWModelVertexBuffer : public IModelVertexBuffer
|
||||||
|
|
|
@ -62,6 +62,10 @@ namespace swrenderer
|
||||||
void RenderViewport::SetupPolyViewport(RenderThread *thread)
|
void RenderViewport::SetupPolyViewport(RenderThread *thread)
|
||||||
{
|
{
|
||||||
WorldToView = SoftwareWorldToView(viewpoint);
|
WorldToView = SoftwareWorldToView(viewpoint);
|
||||||
|
|
||||||
|
if (thread->Portal->MirrorFlags & RF_XFLIP)
|
||||||
|
WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * WorldToView;
|
||||||
|
|
||||||
ViewToClip = SoftwareViewToClip();
|
ViewToClip = SoftwareViewToClip();
|
||||||
WorldToClip = ViewToClip * WorldToView;
|
WorldToClip = ViewToClip * WorldToView;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue