summaryrefslogtreecommitdiff
path: root/src/video_core/rasterizer.cpp
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2015-02-18 13:14:49 +0100
committerGravatar Tony Wasserka2015-02-18 14:50:28 +0100
commit638b370fb5a9dff1296e6c60c02ac68911ae666a (patch)
tree81b4b1569df208af9e8fa9c5fc6a3ae833a91b92 /src/video_core/rasterizer.cpp
parentPica: Cleanup clipping code and change screenspace z to range from -1..0. (diff)
downloadyuzu-638b370fb5a9dff1296e6c60c02ac68911ae666a.tar.gz
yuzu-638b370fb5a9dff1296e6c60c02ac68911ae666a.tar.xz
yuzu-638b370fb5a9dff1296e6c60c02ac68911ae666a.zip
Pica/Rasterizer: Clean up and fix backface culling.
Diffstat (limited to 'src/video_core/rasterizer.cpp')
-rw-r--r--src/video_core/rasterizer.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index 046c010ef..5769bd81e 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -90,9 +90,14 @@ static int SignedArea (const Math::Vec2<Fix12P4>& vtx1,
90 return Math::Cross(vec1, vec2).z; 90 return Math::Cross(vec1, vec2).z;
91}; 91};
92 92
93void ProcessTriangle(const VertexShader::OutputVertex& v0, 93/**
94 const VertexShader::OutputVertex& v1, 94 * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing
95 const VertexShader::OutputVertex& v2) 95 * culling via recursion.
96 */
97static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
98 const VertexShader::OutputVertex& v1,
99 const VertexShader::OutputVertex& v2,
100 bool reversed = false)
96{ 101{
97 // vertex positions in rasterizer coordinates 102 // vertex positions in rasterizer coordinates
98 auto FloatToFix = [](float24 flt) { 103 auto FloatToFix = [](float24 flt) {
@@ -106,17 +111,22 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
106 ScreenToRasterizerCoordinates(v1.screenpos), 111 ScreenToRasterizerCoordinates(v1.screenpos),
107 ScreenToRasterizerCoordinates(v2.screenpos) }; 112 ScreenToRasterizerCoordinates(v2.screenpos) };
108 113
109 if (registers.cull_mode == Regs::CullMode::KeepCounterClockWise) { 114 if (registers.cull_mode == Regs::CullMode::KeepAll) {
110 // Reverse vertex order and use the CW code path. 115 // Make sure we always end up with a triangle wound counter-clockwise
111 std::swap(vtxpos[1], vtxpos[2]); 116 if (!reversed && SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) {
112 } 117 ProcessTriangleInternal(v0, v2, v1, true);
118 return;
119 }
120 } else {
121 if (!reversed && registers.cull_mode == Regs::CullMode::KeepClockWise) {
122 // Reverse vertex order and use the CCW code path.
123 ProcessTriangleInternal(v0, v2, v1, true);
124 return;
125 }
113 126
114 if (registers.cull_mode != Regs::CullMode::KeepAll) { 127 // Cull away triangles which are wound clockwise.
115 // Cull away triangles which are wound counter-clockwise.
116 if (SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) 128 if (SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0)
117 return; 129 return;
118 } else {
119 // TODO: Consider A check for degenerate triangles ("SignedArea == 0")
120 } 130 }
121 131
122 // TODO: Proper scissor rect test! 132 // TODO: Proper scissor rect test!
@@ -695,6 +705,12 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
695 } 705 }
696} 706}
697 707
708void ProcessTriangle(const VertexShader::OutputVertex& v0,
709 const VertexShader::OutputVertex& v1,
710 const VertexShader::OutputVertex& v2) {
711 ProcessTriangleInternal(v0, v1, v2);
712}
713
698} // namespace Rasterizer 714} // namespace Rasterizer
699 715
700} // namespace Pica 716} // namespace Pica