summaryrefslogtreecommitdiffstats
path: root/src/video_core/swrasterizer/clipper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/swrasterizer/clipper.cpp')
-rw-r--r--src/video_core/swrasterizer/clipper.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/video_core/swrasterizer/clipper.cpp b/src/video_core/swrasterizer/clipper.cpp
index 6fb923756..cdbc71502 100644
--- a/src/video_core/swrasterizer/clipper.cpp
+++ b/src/video_core/swrasterizer/clipper.cpp
@@ -95,6 +95,17 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
static const size_t MAX_VERTICES = 9;
static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2};
static_vector<Vertex, MAX_VERTICES> buffer_b;
+
+ auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) {
+ if (Math::Dot(a, b) < float24::Zero())
+ a = -a;
+ };
+
+ // Flip the quaternions if they are opposite to prevent interpolating them over the wrong
+ // direction.
+ FlipQuaternionIfOpposite(buffer_a[1].quat, buffer_a[0].quat);
+ FlipQuaternionIfOpposite(buffer_a[2].quat, buffer_a[0].quat);
+
auto* output_list = &buffer_a;
auto* input_list = &buffer_b;
@@ -114,10 +125,6 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
{Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
}};
- // TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii)
- // drop the whole primitive instead of clipping the primitive properly. We should test if
- // this happens on the 3DS, too.
-
// Simple implementation of the Sutherland-Hodgman clipping algorithm.
// TODO: Make this less inefficient (currently lots of useless buffering overhead happens here)
for (auto edge : clipping_edges) {