- 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)
{
SWModelRenderer renderer(thread);
SWModelRenderer renderer(thread, clip3DFloor);
renderer.RenderModel(x, y, z, smf, actor);
}
@ -75,13 +75,13 @@ namespace swrenderer
void RenderHUDModel(RenderThread *thread, DPSprite *psp, float ofsx, float ofsy)
{
SWModelRenderer renderer(thread);
SWModelRenderer renderer(thread, Fake3DTranslucent());
renderer.RenderHUDModel(psp, ofsx, ofsy);
}
/////////////////////////////////////////////////////////////////////////////
SWModelRenderer::SWModelRenderer(RenderThread *thread) : Thread(thread)
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor)
{
if (polymodelsInUse)
{
@ -94,6 +94,39 @@ namespace swrenderer
{
ModelActor = actor;
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();
}
@ -154,6 +187,8 @@ namespace swrenderer
{
ModelActor = actor;
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
ClipTop = {};
ClipBottom = {};
SetTransform();
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
}
@ -198,7 +233,6 @@ namespace swrenderer
PolyDrawArgs args;
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);
if (Thread->Viewport->RenderTarget->IsBgra())
@ -209,6 +243,10 @@ namespace swrenderer
args.SetDepthTest(true);
args.SetWriteDepth(true);
args.SetWriteStencil(false);
args.SetClipPlane(0, PolyClipPlane());
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
args.DrawArray(Thread->DrawQueue, VertexBuffer + start, count);
}
@ -225,7 +263,6 @@ namespace swrenderer
PolyDrawArgs args;
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);
if (Thread->Viewport->RenderTarget->IsBgra())
@ -236,6 +273,10 @@ namespace swrenderer
args.SetDepthTest(true);
args.SetWriteDepth(true);
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);
}

View file

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

View file

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