diff options
Diffstat (limited to 'Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp | 476 |
1 files changed, 239 insertions, 237 deletions
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp index c4755b50bf..283056cdb7 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp @@ -12,7 +12,7 @@ // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ -// Official SVN repository and contact information can be found at +// Official Git repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ /* @@ -62,8 +62,8 @@ namespace Clipper float m_ViewOffset[2]; - OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES]; - OutputVertexData *Vertices[NUM_INDICES]; + OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES]; + OutputVertexData *Vertices[NUM_INDICES]; void DoState(PointerWrap &p) { @@ -72,94 +72,94 @@ namespace Clipper ClippedVertices[i].DoState(p); } - void Init() - { - for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i) - Vertices[i+3] = &ClippedVertices[i]; - } - - void SetViewOffset() - { - m_ViewOffset[0] = swxfregs.viewport.xOrig - 342; - m_ViewOffset[1] = swxfregs.viewport.yOrig - 342; - } - - - enum { - SKIP_FLAG = -1, - CLIP_POS_X_BIT = 0x01, - CLIP_NEG_X_BIT = 0x02, - CLIP_POS_Y_BIT = 0x04, - CLIP_NEG_Y_BIT = 0x08, - CLIP_POS_Z_BIT = 0x10, - CLIP_NEG_Z_BIT = 0x20 - }; - - static inline int CalcClipMask(OutputVertexData *v) - { - int cmask = 0; - Vec4 pos = v->projectedPosition; - if (pos.w - pos.x < 0) cmask |= CLIP_POS_X_BIT; - if (pos.x + pos.w < 0) cmask |= CLIP_NEG_X_BIT; - if (pos.w - pos.y < 0) cmask |= CLIP_POS_Y_BIT; - if (pos.y + pos.w < 0) cmask |= CLIP_NEG_Y_BIT; - if (pos.w * pos.z > 0) cmask |= CLIP_POS_Z_BIT; - if (pos.z + pos.w < 0) cmask |= CLIP_NEG_Z_BIT; - return cmask; - } - - static inline void AddInterpolatedVertex(float t, int out, int in, int& numVertices) - { - Vertices[numVertices]->Lerp(t, Vertices[out], Vertices[in]); - numVertices++; - } - - #define DIFFERENT_SIGNS(x,y) ((x <= 0 && y > 0) || (x > 0 && y <= 0)) - - #define CLIP_DOTPROD(I, A, B, C, D) \ - (Vertices[I]->projectedPosition.x * A + Vertices[I]->projectedPosition.y * B + Vertices[I]->projectedPosition.z * C + Vertices[I]->projectedPosition.w * D) - - #define POLY_CLIP( PLANE_BIT, A, B, C, D ) \ - { \ - if (mask & PLANE_BIT) { \ - int idxPrev = inlist[0]; \ - float dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ - int outcount = 0; \ - \ - inlist[n] = inlist[0]; \ - for (int j = 1; j <= n; j++) { \ - int idx = inlist[j]; \ - float dp = CLIP_DOTPROD(idx, A, B, C, D ); \ - if (dpPrev >= 0) { \ - outlist[outcount++] = idxPrev; \ - } \ - \ - if (DIFFERENT_SIGNS(dp, dpPrev)) { \ - if (dp < 0) { \ - float t = dp / (dp - dpPrev); \ - AddInterpolatedVertex(t, idx, idxPrev, numVertices); \ - } else { \ - float t = dpPrev / (dpPrev - dp); \ - AddInterpolatedVertex(t, idxPrev, idx, numVertices); \ - } \ - outlist[outcount++] = numVertices - 1; \ - } \ - \ - idxPrev = idx; \ - dpPrev = dp; \ - } \ - \ - if (outcount < 3) \ - continue; \ - \ - { \ - int *tmp = inlist; \ - inlist = outlist; \ - outlist = tmp; \ - n = outcount; \ - } \ - } \ - } + void Init() + { + for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i) + Vertices[i+3] = &ClippedVertices[i]; + } + + void SetViewOffset() + { + m_ViewOffset[0] = swxfregs.viewport.xOrig - 342; + m_ViewOffset[1] = swxfregs.viewport.yOrig - 342; + } + + + enum { + SKIP_FLAG = -1, + CLIP_POS_X_BIT = 0x01, + CLIP_NEG_X_BIT = 0x02, + CLIP_POS_Y_BIT = 0x04, + CLIP_NEG_Y_BIT = 0x08, + CLIP_POS_Z_BIT = 0x10, + CLIP_NEG_Z_BIT = 0x20 + }; + + static inline int CalcClipMask(OutputVertexData *v) + { + int cmask = 0; + Vec4 pos = v->projectedPosition; + if (pos.w - pos.x < 0) cmask |= CLIP_POS_X_BIT; + if (pos.x + pos.w < 0) cmask |= CLIP_NEG_X_BIT; + if (pos.w - pos.y < 0) cmask |= CLIP_POS_Y_BIT; + if (pos.y + pos.w < 0) cmask |= CLIP_NEG_Y_BIT; + if (pos.w * pos.z > 0) cmask |= CLIP_POS_Z_BIT; + if (pos.z + pos.w < 0) cmask |= CLIP_NEG_Z_BIT; + return cmask; + } + + static inline void AddInterpolatedVertex(float t, int out, int in, int& numVertices) + { + Vertices[numVertices]->Lerp(t, Vertices[out], Vertices[in]); + numVertices++; + } + + #define DIFFERENT_SIGNS(x,y) ((x <= 0 && y > 0) || (x > 0 && y <= 0)) + + #define CLIP_DOTPROD(I, A, B, C, D) \ + (Vertices[I]->projectedPosition.x * A + Vertices[I]->projectedPosition.y * B + Vertices[I]->projectedPosition.z * C + Vertices[I]->projectedPosition.w * D) + + #define POLY_CLIP( PLANE_BIT, A, B, C, D ) \ + { \ + if (mask & PLANE_BIT) { \ + int idxPrev = inlist[0]; \ + float dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ + int outcount = 0; \ + \ + inlist[n] = inlist[0]; \ + for (int j = 1; j <= n; j++) { \ + int idx = inlist[j]; \ + float dp = CLIP_DOTPROD(idx, A, B, C, D ); \ + if (dpPrev >= 0) { \ + outlist[outcount++] = idxPrev; \ + } \ + \ + if (DIFFERENT_SIGNS(dp, dpPrev)) { \ + if (dp < 0) { \ + float t = dp / (dp - dpPrev); \ + AddInterpolatedVertex(t, idx, idxPrev, numVertices); \ + } else { \ + float t = dpPrev / (dpPrev - dp); \ + AddInterpolatedVertex(t, idxPrev, idx, numVertices); \ + } \ + outlist[outcount++] = numVertices - 1; \ + } \ + \ + idxPrev = idx; \ + dpPrev = dp; \ + } \ + \ + if (outcount < 3) \ + continue; \ + \ + { \ + int *tmp = inlist; \ + inlist = outlist; \ + outlist = tmp; \ + n = outcount; \ + } \ + } \ + } #define LINE_CLIP(PLANE_BIT, A, B, C, D ) \ { \ @@ -173,63 +173,63 @@ namespace Clipper return; \ \ if (neg_dp1) { \ - float t = dp1 / (dp1 - dp0); \ + float t = dp1 / (dp1 - dp0); \ if (t > t1) t1 = t; \ } else if (neg_dp0) { \ - float t = dp0 / (dp0 - dp1); \ + float t = dp0 / (dp0 - dp1); \ if (t > t0) t0 = t; \ } \ } \ } - void ClipTriangle(int *indices, int &numIndices) - { - int mask = 0; - - mask |= CalcClipMask(Vertices[0]); - mask |= CalcClipMask(Vertices[1]); - mask |= CalcClipMask(Vertices[2]); - - if (mask != 0) - { - for(int i = 0; i < 3; i += 3) - { - int vlist[2][2*6+1]; - int *inlist = vlist[0], *outlist = vlist[1]; - int n = 3; - int numVertices = 3; - - inlist[0] = 0; - inlist[1] = 1; - inlist[2] = 2; - - // mark this triangle as unused in case it should be completely - // clipped - indices[0] = SKIP_FLAG; - indices[1] = SKIP_FLAG; - indices[2] = SKIP_FLAG; - - POLY_CLIP(CLIP_POS_X_BIT, -1, 0, 0, 1); - POLY_CLIP(CLIP_NEG_X_BIT, 1, 0, 0, 1); - POLY_CLIP(CLIP_POS_Y_BIT, 0, -1, 0, 1); - POLY_CLIP(CLIP_NEG_Y_BIT, 0, 1, 0, 1); - POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1); - POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1); - - INCSTAT(swstats.thisFrame.numTrianglesClipped); - - // transform the poly in inlist into triangles - indices[0] = inlist[0]; - indices[1] = inlist[1]; - indices[2] = inlist[2]; - for (int j = 3; j < n; ++j) { - indices[numIndices++] = inlist[0]; - indices[numIndices++] = inlist[j - 1]; - indices[numIndices++] = inlist[j]; - } - } - } - } + void ClipTriangle(int *indices, int &numIndices) + { + int mask = 0; + + mask |= CalcClipMask(Vertices[0]); + mask |= CalcClipMask(Vertices[1]); + mask |= CalcClipMask(Vertices[2]); + + if (mask != 0) + { + for(int i = 0; i < 3; i += 3) + { + int vlist[2][2*6+1]; + int *inlist = vlist[0], *outlist = vlist[1]; + int n = 3; + int numVertices = 3; + + inlist[0] = 0; + inlist[1] = 1; + inlist[2] = 2; + + // mark this triangle as unused in case it should be completely + // clipped + indices[0] = SKIP_FLAG; + indices[1] = SKIP_FLAG; + indices[2] = SKIP_FLAG; + + POLY_CLIP(CLIP_POS_X_BIT, -1, 0, 0, 1); + POLY_CLIP(CLIP_NEG_X_BIT, 1, 0, 0, 1); + POLY_CLIP(CLIP_POS_Y_BIT, 0, -1, 0, 1); + POLY_CLIP(CLIP_NEG_Y_BIT, 0, 1, 0, 1); + POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1); + POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1); + + INCSTAT(swstats.thisFrame.numTrianglesClipped); + + // transform the poly in inlist into triangles + indices[0] = inlist[0]; + indices[1] = inlist[1]; + indices[2] = inlist[2]; + for (int j = 3; j < n; ++j) { + indices[numIndices++] = inlist[0]; + indices[numIndices++] = inlist[j - 1]; + indices[numIndices++] = inlist[j]; + } + } + } + } void ClipLine(int *indices) { @@ -267,59 +267,61 @@ namespace Clipper int numVertices = 2; - if (clip_mask[0]) { + if (clip_mask[0]) + { indices[0] = numVertices; AddInterpolatedVertex(t0, 0, 1, numVertices); } - if (clip_mask[1]) { + if (clip_mask[1]) + { indices[1] = numVertices; AddInterpolatedVertex(t1, 1, 0, numVertices); } } - void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) - { - INCSTAT(swstats.thisFrame.numTrianglesIn) - - bool backface; - - if(!CullTest(v0, v1, v2, backface)) - return; - - int indices[NUM_INDICES] = { 0, 1, 2, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, - SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, - SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG }; - int numIndices = 3; - - if (backface) - { - Vertices[0] = v0; - Vertices[1] = v2; - Vertices[2] = v1; - } - else - { - Vertices[0] = v0; - Vertices[1] = v1; - Vertices[2] = v2; - } - - ClipTriangle(indices, numIndices); - - for(int i = 0; i+3 <= numIndices; i+=3) - { + void ProcessTriangle(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) + { + INCSTAT(swstats.thisFrame.numTrianglesIn) + + bool backface; + + if(!CullTest(v0, v1, v2, backface)) + return; + + int indices[NUM_INDICES] = { 0, 1, 2, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, + SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, + SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG, SKIP_FLAG }; + int numIndices = 3; + + if (backface) + { + Vertices[0] = v0; + Vertices[1] = v2; + Vertices[2] = v1; + } + else + { + Vertices[0] = v0; + Vertices[1] = v1; + Vertices[2] = v2; + } + + ClipTriangle(indices, numIndices); + + for(int i = 0; i+3 <= numIndices; i+=3) + { _assert_(i < NUM_INDICES); if(indices[i] != SKIP_FLAG) - { - PerspectiveDivide(Vertices[indices[i]]); - PerspectiveDivide(Vertices[indices[i+1]]); - PerspectiveDivide(Vertices[indices[i+2]]); + { + PerspectiveDivide(Vertices[indices[i]]); + PerspectiveDivide(Vertices[indices[i+1]]); + PerspectiveDivide(Vertices[indices[i+2]]); - Rasterizer::DrawTriangleFrontFace(Vertices[indices[i]], Vertices[indices[i+1]], Vertices[indices[i+2]]); - } - } - } + Rasterizer::DrawTriangleFrontFace(Vertices[indices[i]], Vertices[indices[i+1]], Vertices[indices[i+2]]); + } + } + } void CopyVertex(OutputVertexData *dst, OutputVertexData *src, float dx, float dy, unsigned int sOffset) { @@ -343,7 +345,7 @@ namespace Clipper int indices[4] = { 0, 1, SKIP_FLAG, SKIP_FLAG }; Vertices[0] = lineV0; - Vertices[1] = lineV1; + Vertices[1] = lineV1; // point to a valid vertex to store to when clipping Vertices[2] = &ClippedVertices[17]; @@ -356,7 +358,7 @@ namespace Clipper OutputVertexData *v1 = Vertices[indices[1]]; PerspectiveDivide(v0); - PerspectiveDivide(v1); + PerspectiveDivide(v1); float dx = v1->screenPosition.x - v0->screenPosition.x; float dy = v1->screenPosition.y - v0->screenPosition.y; @@ -393,57 +395,57 @@ namespace Clipper Rasterizer::DrawTriangleFrontFace(&triangle[0], &triangle[1], &triangle[2]); } } - - bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface) - { - int mask = CalcClipMask(v0); - mask &= CalcClipMask(v1); - mask &= CalcClipMask(v2); - - if(mask) - { - INCSTAT(swstats.thisFrame.numTrianglesRejected) - return false; - } - - float x0 = v0->projectedPosition.x; - float x1 = v1->projectedPosition.x; - float x2 = v2->projectedPosition.x; - float y1 = v1->projectedPosition.y; - float y0 = v0->projectedPosition.y; - float y2 = v2->projectedPosition.y; - float w0 = v0->projectedPosition.w; - float w1 = v1->projectedPosition.w; - float w2 = v2->projectedPosition.w; - - float normalZDir = (x0*w2 - x2*w0)*y1 + (x2*y0 - x0*y2)*w1 + (y2*w0 - y0*w2)*x1; - - backface = normalZDir <= 0.0f; - - if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing - { - INCSTAT(swstats.thisFrame.numTrianglesCulled) - return false; - } - - if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing - { - INCSTAT(swstats.thisFrame.numTrianglesCulled) - return false; - } - - return true; - } - - void PerspectiveDivide(OutputVertexData *vertex) - { - Vec4 &projected = vertex->projectedPosition; - Vec3 &screen = vertex->screenPosition; - - float wInverse = 1.0f/projected.w; - screen.x = projected.x * wInverse * swxfregs.viewport.wd + m_ViewOffset[0]; - screen.y = projected.y * wInverse * swxfregs.viewport.ht + m_ViewOffset[1]; - screen.z = projected.z * wInverse * swxfregs.viewport.zRange + swxfregs.viewport.farZ; - } - + + bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface) + { + int mask = CalcClipMask(v0); + mask &= CalcClipMask(v1); + mask &= CalcClipMask(v2); + + if(mask) + { + INCSTAT(swstats.thisFrame.numTrianglesRejected) + return false; + } + + float x0 = v0->projectedPosition.x; + float x1 = v1->projectedPosition.x; + float x2 = v2->projectedPosition.x; + float y1 = v1->projectedPosition.y; + float y0 = v0->projectedPosition.y; + float y2 = v2->projectedPosition.y; + float w0 = v0->projectedPosition.w; + float w1 = v1->projectedPosition.w; + float w2 = v2->projectedPosition.w; + + float normalZDir = (x0*w2 - x2*w0)*y1 + (x2*y0 - x0*y2)*w1 + (y2*w0 - y0*w2)*x1; + + backface = normalZDir <= 0.0f; + + if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing + { + INCSTAT(swstats.thisFrame.numTrianglesCulled) + return false; + } + + if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing + { + INCSTAT(swstats.thisFrame.numTrianglesCulled) + return false; + } + + return true; + } + + void PerspectiveDivide(OutputVertexData *vertex) + { + Vec4 &projected = vertex->projectedPosition; + Vec3 &screen = vertex->screenPosition; + + float wInverse = 1.0f/projected.w; + screen.x = projected.x * wInverse * swxfregs.viewport.wd + m_ViewOffset[0]; + screen.y = projected.y * wInverse * swxfregs.viewport.ht + m_ViewOffset[1]; + screen.z = projected.z * wInverse * swxfregs.viewport.zRange + swxfregs.viewport.farZ; + } + } |
