- add two-sided culling support in software and poly

This commit is contained in:
Magnus Norddahl 2018-05-24 01:39:36 +02:00
parent 771931db9f
commit 8098657cf4
4 changed files with 47 additions and 0 deletions

View file

@ -79,6 +79,11 @@ void PolyTriangleDrawer::SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw
queue->Push<PolySetCullCCWCommand>(ccw);
}
void PolyTriangleDrawer::SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided)
{
queue->Push<PolySetTwoSidedCommand>(twosided);
}
void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable)
{
queue->Push<PolySetWeaponSceneCommand>(enable);
@ -348,6 +353,14 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo
}
}
if (twosided && numclipvert > 2)
{
args->v1 = &clippedvert[0];
args->v2 = &clippedvert[1];
args->v3 = &clippedvert[2];
ccw = !IsFrontfacing(args);
}
// Draw screen triangles
if (ccw)
{
@ -588,6 +601,17 @@ void PolySetCullCCWCommand::Execute(DrawerThread *thread)
/////////////////////////////////////////////////////////////////////////////
PolySetTwoSidedCommand::PolySetTwoSidedCommand(bool twosided) : twosided(twosided)
{
}
void PolySetTwoSidedCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetTwoSided(twosided);
}
/////////////////////////////////////////////////////////////////////////////
PolySetWeaponSceneCommand::PolySetWeaponSceneCommand(bool value) : value(value)
{
}

View file

@ -35,6 +35,7 @@ public:
static void ClearBuffers(DCanvas *canvas);
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers);
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip);
};
@ -47,6 +48,7 @@ public:
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers);
void SetTransform(const Mat4f *objectToClip);
void SetCullCCW(bool value) { ccw = value; }
void SetTwoSided(bool value) { twosided = value; }
void SetWeaponScene(bool value) { weaponScene = value; }
void DrawElements(const PolyDrawArgs &args);
@ -81,6 +83,7 @@ private:
bool dest_bgra = false;
uint8_t *dest = nullptr;
bool ccw = true;
bool twosided = false;
bool weaponScene = false;
const Mat4f *objectToClip = nullptr;
bool span_drawers = false;
@ -112,6 +115,18 @@ private:
bool ccw;
};
class PolySetTwoSidedCommand : public DrawerCommand
{
public:
PolySetTwoSidedCommand(bool twosided);
void Execute(DrawerThread *thread) override;
FString DebugInfo() override { return "PolySetCullCCWCommand"; }
private:
bool twosided;
};
class PolySetWeaponSceneCommand : public DrawerCommand
{
public:

View file

@ -56,10 +56,12 @@ void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, co
ModelActor = actor;
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
SetTransform();
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
}
void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
{
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
ModelActor = nullptr;
}
@ -98,12 +100,14 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
SetTransform();
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
}
void PolyModelRenderer::EndDrawHUDModel(AActor *actor)
{
ModelActor = nullptr;
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
}
void PolyModelRenderer::SetInterpolation(double interpolation)

View file

@ -120,11 +120,13 @@ namespace swrenderer
}
SetTransform();
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
}
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
{
ModelActor = nullptr;
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
}
IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
@ -183,12 +185,14 @@ namespace swrenderer
ClipBottom = {};
SetTransform();
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
}
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
{
ModelActor = nullptr;
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
}
void SWModelRenderer::SetInterpolation(double interpolation)