summaryrefslogtreecommitdiff
path: root/src/video_core/clipper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/clipper.cpp')
-rw-r--r--src/video_core/clipper.cpp68
1 files changed, 33 insertions, 35 deletions
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp
index db99ce666..747285866 100644
--- a/src/video_core/clipper.cpp
+++ b/src/video_core/clipper.cpp
@@ -27,14 +27,10 @@ namespace Clipper {
27 27
28struct ClippingEdge { 28struct ClippingEdge {
29public: 29public:
30 ClippingEdge(Math::Vec4<float24> coeffs, 30 ClippingEdge(Math::Vec4<float24> coeffs, Math::Vec4<float24> bias = Math::Vec4<float24>(
31 Math::Vec4<float24> bias = Math::Vec4<float24>(float24::FromFloat32(0), 31 float24::FromFloat32(0), float24::FromFloat32(0),
32 float24::FromFloat32(0), 32 float24::FromFloat32(0), float24::FromFloat32(0)))
33 float24::FromFloat32(0), 33 : coeffs(coeffs), bias(bias) {
34 float24::FromFloat32(0)))
35 : coeffs(coeffs),
36 bias(bias)
37 {
38 } 34 }
39 35
40 bool IsInside(const OutputVertex& vertex) const { 36 bool IsInside(const OutputVertex& vertex) const {
@@ -59,8 +55,7 @@ private:
59 Math::Vec4<float24> bias; 55 Math::Vec4<float24> bias;
60}; 56};
61 57
62static void InitScreenCoordinates(OutputVertex& vtx) 58static void InitScreenCoordinates(OutputVertex& vtx) {
63{
64 struct { 59 struct {
65 float24 halfsize_x; 60 float24 halfsize_x;
66 float24 offset_x; 61 float24 offset_x;
@@ -73,8 +68,8 @@ static void InitScreenCoordinates(OutputVertex& vtx)
73 const auto& regs = g_state.regs; 68 const auto& regs = g_state.regs;
74 viewport.halfsize_x = float24::FromRaw(regs.viewport_size_x); 69 viewport.halfsize_x = float24::FromRaw(regs.viewport_size_x);
75 viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y); 70 viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y);
76 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); 71 viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x));
77 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); 72 viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y));
78 73
79 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; 74 float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w;
80 vtx.color *= inv_w; 75 vtx.color *= inv_w;
@@ -85,12 +80,14 @@ static void InitScreenCoordinates(OutputVertex& vtx)
85 vtx.tc2 *= inv_w; 80 vtx.tc2 *= inv_w;
86 vtx.pos.w = inv_w; 81 vtx.pos.w = inv_w;
87 82
88 vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; 83 vtx.screenpos[0] =
89 vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; 84 (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x;
85 vtx.screenpos[1] =
86 (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y;
90 vtx.screenpos[2] = vtx.pos.z * inv_w; 87 vtx.screenpos[2] = vtx.pos.z * inv_w;
91} 88}
92 89
93void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) { 90void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) {
94 using boost::container::static_vector; 91 using boost::container::static_vector;
95 92
96 // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at 93 // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at
@@ -98,10 +95,10 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu
98 // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a 95 // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a
99 // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9. 96 // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9.
100 static const size_t MAX_VERTICES = 9; 97 static const size_t MAX_VERTICES = 9;
101 static_vector<OutputVertex, MAX_VERTICES> buffer_a = { v0, v1, v2 }; 98 static_vector<OutputVertex, MAX_VERTICES> buffer_a = {v0, v1, v2};
102 static_vector<OutputVertex, MAX_VERTICES> buffer_b; 99 static_vector<OutputVertex, MAX_VERTICES> buffer_b;
103 auto* output_list = &buffer_a; 100 auto* output_list = &buffer_a;
104 auto* input_list = &buffer_b; 101 auto* input_list = &buffer_b;
105 102
106 // NOTE: We clip against a w=epsilon plane to guarantee that the output has a positive w value. 103 // NOTE: We clip against a w=epsilon plane to guarantee that the output has a positive w value.
107 // TODO: Not sure if this is a valid approach. Also should probably instead use the smallest 104 // TODO: Not sure if this is a valid approach. Also should probably instead use the smallest
@@ -110,13 +107,13 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu
110 static const float24 f0 = float24::FromFloat32(0.0); 107 static const float24 f0 = float24::FromFloat32(0.0);
111 static const float24 f1 = float24::FromFloat32(1.0); 108 static const float24 f1 = float24::FromFloat32(1.0);
112 static const std::array<ClippingEdge, 7> clipping_edges = {{ 109 static const std::array<ClippingEdge, 7> clipping_edges = {{
113 { Math::MakeVec( f1, f0, f0, -f1) }, // x = +w 110 {Math::MakeVec(f1, f0, f0, -f1)}, // x = +w
114 { Math::MakeVec(-f1, f0, f0, -f1) }, // x = -w 111 {Math::MakeVec(-f1, f0, f0, -f1)}, // x = -w
115 { Math::MakeVec( f0, f1, f0, -f1) }, // y = +w 112 {Math::MakeVec(f0, f1, f0, -f1)}, // y = +w
116 { Math::MakeVec( f0, -f1, f0, -f1) }, // y = -w 113 {Math::MakeVec(f0, -f1, f0, -f1)}, // y = -w
117 { Math::MakeVec( f0, f0, f1, f0) }, // z = 0 114 {Math::MakeVec(f0, f0, f1, f0)}, // z = 0
118 { Math::MakeVec( f0, f0, -f1, -f1) }, // z = -w 115 {Math::MakeVec(f0, f0, -f1, -f1)}, // z = -w
119 { Math::MakeVec( f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON) }, // w = EPSILON 116 {Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON
120 }}; 117 }};
121 118
122 // TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii) 119 // TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii)
@@ -154,10 +151,10 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu
154 InitScreenCoordinates((*output_list)[0]); 151 InitScreenCoordinates((*output_list)[0]);
155 InitScreenCoordinates((*output_list)[1]); 152 InitScreenCoordinates((*output_list)[1]);
156 153
157 for (size_t i = 0; i < output_list->size() - 2; i ++) { 154 for (size_t i = 0; i < output_list->size() - 2; i++) {
158 OutputVertex& vtx0 = (*output_list)[0]; 155 OutputVertex& vtx0 = (*output_list)[0];
159 OutputVertex& vtx1 = (*output_list)[i+1]; 156 OutputVertex& vtx1 = (*output_list)[i + 1];
160 OutputVertex& vtx2 = (*output_list)[i+2]; 157 OutputVertex& vtx2 = (*output_list)[i + 2];
161 158
162 InitScreenCoordinates(vtx2); 159 InitScreenCoordinates(vtx2);
163 160
@@ -165,19 +162,20 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu
165 "Triangle %lu/%lu at position (%.3f, %.3f, %.3f, %.3f), " 162 "Triangle %lu/%lu at position (%.3f, %.3f, %.3f, %.3f), "
166 "(%.3f, %.3f, %.3f, %.3f), (%.3f, %.3f, %.3f, %.3f) and " 163 "(%.3f, %.3f, %.3f, %.3f), (%.3f, %.3f, %.3f, %.3f) and "
167 "screen position (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f)", 164 "screen position (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f)",
168 i + 1, output_list->size() - 2, 165 i + 1, output_list->size() - 2, vtx0.pos.x.ToFloat32(), vtx0.pos.y.ToFloat32(),
169 vtx0.pos.x.ToFloat32(), vtx0.pos.y.ToFloat32(), vtx0.pos.z.ToFloat32(), vtx0.pos.w.ToFloat32(), 166 vtx0.pos.z.ToFloat32(), vtx0.pos.w.ToFloat32(), vtx1.pos.x.ToFloat32(),
170 vtx1.pos.x.ToFloat32(), vtx1.pos.y.ToFloat32(), vtx1.pos.z.ToFloat32(), vtx1.pos.w.ToFloat32(), 167 vtx1.pos.y.ToFloat32(), vtx1.pos.z.ToFloat32(), vtx1.pos.w.ToFloat32(),
171 vtx2.pos.x.ToFloat32(), vtx2.pos.y.ToFloat32(), vtx2.pos.z.ToFloat32(), vtx2.pos.w.ToFloat32(), 168 vtx2.pos.x.ToFloat32(), vtx2.pos.y.ToFloat32(), vtx2.pos.z.ToFloat32(),
172 vtx0.screenpos.x.ToFloat32(), vtx0.screenpos.y.ToFloat32(), vtx0.screenpos.z.ToFloat32(), 169 vtx2.pos.w.ToFloat32(), vtx0.screenpos.x.ToFloat32(),
173 vtx1.screenpos.x.ToFloat32(), vtx1.screenpos.y.ToFloat32(), vtx1.screenpos.z.ToFloat32(), 170 vtx0.screenpos.y.ToFloat32(), vtx0.screenpos.z.ToFloat32(),
174 vtx2.screenpos.x.ToFloat32(), vtx2.screenpos.y.ToFloat32(), vtx2.screenpos.z.ToFloat32()); 171 vtx1.screenpos.x.ToFloat32(), vtx1.screenpos.y.ToFloat32(),
172 vtx1.screenpos.z.ToFloat32(), vtx2.screenpos.x.ToFloat32(),
173 vtx2.screenpos.y.ToFloat32(), vtx2.screenpos.z.ToFloat32());
175 174
176 Rasterizer::ProcessTriangle(vtx0, vtx1, vtx2); 175 Rasterizer::ProcessTriangle(vtx0, vtx1, vtx2);
177 } 176 }
178} 177}
179 178
180
181} // namespace 179} // namespace
182 180
183} // namespace 181} // namespace