- 3d floor clipping support for models

This commit is contained in:
Magnus Norddahl 2018-05-08 01:36:18 +02:00
parent 49c9de350f
commit b27655db70
3 changed files with 50 additions and 8 deletions

View file

@ -67,7 +67,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); SWModelRenderer renderer(thread, clip3DFloor);
renderer.RenderModel(x, y, z, smf, actor); renderer.RenderModel(x, y, z, smf, actor);
} }
@ -75,13 +75,13 @@ 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); SWModelRenderer renderer(thread, Fake3DTranslucent());
renderer.RenderHUDModel(psp, ofsx, ofsy); renderer.RenderHUDModel(psp, ofsx, ofsy);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
SWModelRenderer::SWModelRenderer(RenderThread *thread) : Thread(thread) SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor)
{ {
if (polymodelsInUse) if (polymodelsInUse)
{ {
@ -94,6 +94,39 @@ namespace swrenderer
{ {
ModelActor = actor; ModelActor = actor;
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix); const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
ClipTop = {};
ClipBottom = {};
if (Clip3DFloor.clipTop || Clip3DFloor.clipBottom)
{
// Convert 3d floor clipping planes from world to object space
VSMatrix inverseMat;
const_cast<VSMatrix &>(objectToWorldMatrix).inverseMatrix(inverseMat);
Mat4f worldToObject;
inverseMat.copy(worldToObject.Matrix);
// Note: Y and Z is swapped here
Vec4f one = worldToObject * Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
Vec4f zero = worldToObject * Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
Vec4f up = { one.X - zero.X, one.Y - zero.Y, one.Z - zero.Z };
if (Clip3DFloor.clipTop)
{
Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipTop, 0.0f, 1.0f);
float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z;
ClipTop = { -up.X, -up.Y, -up.Z, d };
}
if (Clip3DFloor.clipBottom)
{
Vec4f p = worldToObject * Vec4f(0.0f, Clip3DFloor.sclipBottom, 0.0f, 1.0f);
float d = up.X * p.X + up.Y * p.Y + up.Z * p.Z;
ClipBottom = { up.X, up.Y, up.Z, -d };
}
}
SetTransform(); SetTransform();
} }
@ -154,6 +187,8 @@ namespace swrenderer
{ {
ModelActor = actor; ModelActor = actor;
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix); const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
ClipTop = {};
ClipBottom = {};
SetTransform(); SetTransform();
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
} }
@ -198,7 +233,6 @@ namespace swrenderer
PolyDrawArgs args; PolyDrawArgs args;
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite); args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite);
args.SetClipPlane(0, PolyClipPlane());
args.SetStyle(TriBlendMode::TextureOpaque); args.SetStyle(TriBlendMode::TextureOpaque);
if (Thread->Viewport->RenderTarget->IsBgra()) if (Thread->Viewport->RenderTarget->IsBgra())
@ -209,6 +243,10 @@ namespace swrenderer
args.SetDepthTest(true); args.SetDepthTest(true);
args.SetWriteDepth(true); args.SetWriteDepth(true);
args.SetWriteStencil(false); args.SetWriteStencil(false);
args.SetClipPlane(0, PolyClipPlane());
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
args.DrawArray(Thread->DrawQueue, VertexBuffer + start, count); args.DrawArray(Thread->DrawQueue, VertexBuffer + start, count);
} }
@ -225,7 +263,6 @@ namespace swrenderer
PolyDrawArgs args; PolyDrawArgs args;
args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite); args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, Thread->Light->SpriteGlobVis(foggy), fullbrightSprite);
args.SetClipPlane(0, PolyClipPlane());
args.SetStyle(TriBlendMode::TextureOpaque); args.SetStyle(TriBlendMode::TextureOpaque);
if (Thread->Viewport->RenderTarget->IsBgra()) if (Thread->Viewport->RenderTarget->IsBgra())
@ -236,6 +273,10 @@ namespace swrenderer
args.SetDepthTest(true); args.SetDepthTest(true);
args.SetWriteDepth(true); args.SetWriteDepth(true);
args.SetWriteStencil(false); args.SetWriteStencil(false);
args.SetClipPlane(0, PolyClipPlane());
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
args.DrawElements(Thread->DrawQueue, VertexBuffer, IndexBuffer + offset / sizeof(unsigned int), numIndices); args.DrawElements(Thread->DrawQueue, VertexBuffer, IndexBuffer + offset / sizeof(unsigned int), numIndices);
} }

View file

@ -52,7 +52,7 @@ namespace swrenderer
class SWModelRenderer : public FModelRenderer class SWModelRenderer : public FModelRenderer
{ {
public: public:
SWModelRenderer(RenderThread *thread); SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor);
void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override;
void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override;
@ -70,9 +70,11 @@ namespace swrenderer
void SetTransform(); void SetTransform();
RenderThread *Thread = nullptr; RenderThread *Thread = nullptr;
Fake3DTranslucent Clip3DFloor;
AActor *ModelActor = nullptr; AActor *ModelActor = nullptr;
Mat4f ObjectToWorld; Mat4f ObjectToWorld;
PolyClipPlane ClipTop, ClipBottom;
FTexture *SkinTexture = nullptr; FTexture *SkinTexture = nullptr;
unsigned int *IndexBuffer = nullptr; unsigned int *IndexBuffer = nullptr;
TriVertex *VertexBuffer = nullptr; TriVertex *VertexBuffer = nullptr;

View file

@ -94,8 +94,7 @@ namespace swrenderer
(r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0)) (r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0))
return; return;
if (r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player)) renderHUDModel = r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
renderHUDModel = true;
FDynamicColormap *basecolormap; FDynamicColormap *basecolormap;
CameraLight *cameraLight = CameraLight::Instance(); CameraLight *cameraLight = CameraLight::Instance();