diff options
| author | 2014-12-13 21:39:42 +0100 | |
|---|---|---|
| committer | 2014-12-31 16:32:55 +0100 | |
| commit | 0f494240228e24e21c88bf9f3178aaa68db4fb45 (patch) | |
| tree | b23513ade2000339485bf9585a988aece11c1019 /src/video_core/rasterizer.cpp | |
| parent | Pica/Rasterizer: Textures seem to be laid out flipped vertically. (diff) | |
| download | yuzu-0f494240228e24e21c88bf9f3178aaa68db4fb45.tar.gz yuzu-0f494240228e24e21c88bf9f3178aaa68db4fb45.tar.xz yuzu-0f494240228e24e21c88bf9f3178aaa68db4fb45.zip | |
Pica/Rasterizer: Implement backface culling.
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 08b649fb6..9148745dc 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -82,10 +82,31 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 82 | auto ScreenToRasterizerCoordinates = [FloatToFix](const Math::Vec3<float24> vec) { | 82 | auto ScreenToRasterizerCoordinates = [FloatToFix](const Math::Vec3<float24> vec) { |
| 83 | return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)}; | 83 | return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)}; |
| 84 | }; | 84 | }; |
| 85 | static auto orient2d = [](const Math::Vec2<Fix12P4>& vtx1, | ||
| 86 | const Math::Vec2<Fix12P4>& vtx2, | ||
| 87 | const Math::Vec2<Fix12P4>& vtx3) { | ||
| 88 | const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0); | ||
| 89 | const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0); | ||
| 90 | // TODO: There is a very small chance this will overflow for sizeof(int) == 4 | ||
| 91 | return Math::Cross(vec1, vec2).z; | ||
| 92 | }; | ||
| 93 | |||
| 85 | Math::Vec3<Fix12P4> vtxpos[3]{ ScreenToRasterizerCoordinates(v0.screenpos), | 94 | Math::Vec3<Fix12P4> vtxpos[3]{ ScreenToRasterizerCoordinates(v0.screenpos), |
| 86 | ScreenToRasterizerCoordinates(v1.screenpos), | 95 | ScreenToRasterizerCoordinates(v1.screenpos), |
| 87 | ScreenToRasterizerCoordinates(v2.screenpos) }; | 96 | ScreenToRasterizerCoordinates(v2.screenpos) }; |
| 88 | 97 | ||
| 98 | if (registers.cull_mode == Regs::CullMode::KeepClockWise) { | ||
| 99 | // Reverse vertex order and use the CCW code path. | ||
| 100 | std::swap(vtxpos[1], vtxpos[2]); | ||
| 101 | } | ||
| 102 | |||
| 103 | if (registers.cull_mode != Regs::CullMode::KeepAll) { | ||
| 104 | // Cull away triangles which are wound clockwise. | ||
| 105 | // TODO: A check for degenerate triangles ("== 0") should be considered for CullMode::KeepAll | ||
| 106 | if (orient2d(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | |||
| 89 | // TODO: Proper scissor rect test! | 110 | // TODO: Proper scissor rect test! |
| 90 | u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); | 111 | u16 min_x = std::min({vtxpos[0].x, vtxpos[1].x, vtxpos[2].x}); |
| 91 | u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); | 112 | u16 min_y = std::min({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); |
| @@ -128,15 +149,6 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 128 | for (u16 x = min_x; x < max_x; x += 0x10) { | 149 | for (u16 x = min_x; x < max_x; x += 0x10) { |
| 129 | 150 | ||
| 130 | // Calculate the barycentric coordinates w0, w1 and w2 | 151 | // Calculate the barycentric coordinates w0, w1 and w2 |
| 131 | auto orient2d = [](const Math::Vec2<Fix12P4>& vtx1, | ||
| 132 | const Math::Vec2<Fix12P4>& vtx2, | ||
| 133 | const Math::Vec2<Fix12P4>& vtx3) { | ||
| 134 | const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0); | ||
| 135 | const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0); | ||
| 136 | // TODO: There is a very small chance this will overflow for sizeof(int) == 4 | ||
| 137 | return Math::Cross(vec1, vec2).z; | ||
| 138 | }; | ||
| 139 | |||
| 140 | int w0 = bias0 + orient2d(vtxpos[1].xy(), vtxpos[2].xy(), {x, y}); | 152 | int w0 = bias0 + orient2d(vtxpos[1].xy(), vtxpos[2].xy(), {x, y}); |
| 141 | int w1 = bias1 + orient2d(vtxpos[2].xy(), vtxpos[0].xy(), {x, y}); | 153 | int w1 = bias1 + orient2d(vtxpos[2].xy(), vtxpos[0].xy(), {x, y}); |
| 142 | int w2 = bias2 + orient2d(vtxpos[0].xy(), vtxpos[1].xy(), {x, y}); | 154 | int w2 = bias2 + orient2d(vtxpos[0].xy(), vtxpos[1].xy(), {x, y}); |