mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- 3d floor clipping support for models
This commit is contained in:
parent
49c9de350f
commit
b27655db70
3 changed files with 50 additions and 8 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue