- 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); queue->Push<PolySetCullCCWCommand>(ccw);
} }
void PolyTriangleDrawer::SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided)
{
queue->Push<PolySetTwoSidedCommand>(twosided);
}
void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable) void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable)
{ {
queue->Push<PolySetWeaponSceneCommand>(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 // Draw screen triangles
if (ccw) 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) PolySetWeaponSceneCommand::PolySetWeaponSceneCommand(bool value) : value(value)
{ {
} }

View file

@ -35,6 +35,7 @@ public:
static void ClearBuffers(DCanvas *canvas); 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 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 SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable); static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip); 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 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 SetTransform(const Mat4f *objectToClip);
void SetCullCCW(bool value) { ccw = value; } void SetCullCCW(bool value) { ccw = value; }
void SetTwoSided(bool value) { twosided = value; }
void SetWeaponScene(bool value) { weaponScene = value; } void SetWeaponScene(bool value) { weaponScene = value; }
void DrawElements(const PolyDrawArgs &args); void DrawElements(const PolyDrawArgs &args);
@ -81,6 +83,7 @@ private:
bool dest_bgra = false; bool dest_bgra = false;
uint8_t *dest = nullptr; uint8_t *dest = nullptr;
bool ccw = true; bool ccw = true;
bool twosided = false;
bool weaponScene = false; bool weaponScene = false;
const Mat4f *objectToClip = nullptr; const Mat4f *objectToClip = nullptr;
bool span_drawers = false; bool span_drawers = false;
@ -112,6 +115,18 @@ private:
bool ccw; 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 class PolySetWeaponSceneCommand : public DrawerCommand
{ {
public: public:

View file

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

View file

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