diff options
Diffstat (limited to 'Source/Core/VideoCommon/Src/IndexGenerator.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/Src/IndexGenerator.cpp | 364 |
1 files changed, 98 insertions, 266 deletions
diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index 8053114fae..aa1a971687 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -15,6 +15,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include <cstddef> + +#include "Common.h" #include "IndexGenerator.h" /* @@ -27,24 +30,18 @@ QUAD simulator */ //Init -u16 *IndexGenerator::Tptr = 0; -u16 *IndexGenerator::BASETptr = 0; -u16 *IndexGenerator::Lptr = 0; -u16 *IndexGenerator::BASELptr = 0; -u16 *IndexGenerator::Pptr = 0; -u16 *IndexGenerator::BASEPptr = 0; -int IndexGenerator::numT = 0; -int IndexGenerator::numL = 0; -int IndexGenerator::numP = 0; -int IndexGenerator::index = 0; -int IndexGenerator::Tadds = 0; -int IndexGenerator::Ladds = 0; -int IndexGenerator::Padds = 0; -IndexGenerator::IndexPrimitiveType IndexGenerator::LastTPrimitive = Prim_None; -IndexGenerator::IndexPrimitiveType IndexGenerator::LastLPrimitive = Prim_None; -bool IndexGenerator::used = false; - -void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr) +u16 *IndexGenerator::Tptr; +u16 *IndexGenerator::BASETptr; +u16 *IndexGenerator::Lptr; +u16 *IndexGenerator::BASELptr; +u16 *IndexGenerator::Pptr; +u16 *IndexGenerator::BASEPptr; +u32 IndexGenerator::numT; +u32 IndexGenerator::numL; +u32 IndexGenerator::numP; +u32 IndexGenerator::index; + +void IndexGenerator::Start(u16* Triangleptr, u16* Lineptr, u16* Pointptr) { Tptr = Triangleptr; Lptr = Lineptr; @@ -56,288 +53,123 @@ void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr) numT = 0; numL = 0; numP = 0; - Tadds = 0; - Ladds = 0; - Padds = 0; - LastTPrimitive = Prim_None; - LastLPrimitive = Prim_None; } -// Triangles -void IndexGenerator::AddList(int numVerts) + +void IndexGenerator::AddIndices(int primitive, u32 numVerts) { - //if we have no vertices return - if(numVerts <= 0) return; - int numTris = numVerts / 3; - if (!numTris) + //switch (primitive) + //{ + //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVerts); break; + //case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVerts); break; + //case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVerts); break; + //case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVerts); break; + //case GX_DRAW_LINES: IndexGenerator::AddLineList(numVerts); break; + //case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVerts); break; + //case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVerts); break; + //} + + static void (*const primitive_table[])(u32) = { - //if we have less than 3 verts - if(numVerts == 1) - { - // discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; - } - } - else - { - for (int i = 0; i < numTris; i++) - { - *Tptr++ = index+i*3; - *Tptr++ = index+i*3+1; - *Tptr++ = index+i*3+2; - } - int baseRemainingverts = numVerts - numVerts % 3; - switch (numVerts % 3) - { - case 2: - //whe have 2 remaining verts use strip method - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - numTris++; - break; - case 1: - //whe have 1 remaining verts use strip method this is only a conjeture - *Tptr++ = index + baseRemainingverts - 2; - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - numTris++; - break; - default: - break; - }; - } + IndexGenerator::AddQuads, + NULL, + IndexGenerator::AddList, + IndexGenerator::AddStrip, + IndexGenerator::AddFan, + IndexGenerator::AddLineList, + IndexGenerator::AddLineStrip, + IndexGenerator::AddPoints, + }; + + primitive_table[primitive](numVerts); index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_List; } -void IndexGenerator::AddStrip(int numVerts) +// Triangles +__forceinline void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) { - if(numVerts <= 0) return; - int numTris = numVerts - 2; - if (numTris < 1) - { - //if we have less than 3 verts - if(numVerts == 1) - { - // discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; - } - } - else - { - bool wind = false; - for (int i = 0; i < numTris; i++) - { - *Tptr++ = index+i; - *Tptr++ = index+i+(wind?2:1); - *Tptr++ = index+i+(wind?1:2); - wind = !wind; - } - } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_Strip; + *Tptr++ = index1; + *Tptr++ = index2; + *Tptr++ = index3; + + ++numT; } -void IndexGenerator::AddFan(int numVerts) + +void IndexGenerator::AddList(u32 const numVerts) { - if(numVerts <= 0) return; - int numTris = numVerts - 2; - if (numTris < 1) + auto const numTris = numVerts / 3; + for (u32 i = 0; i != numTris; ++i) { - //if we have less than 3 verts - if(numVerts == 1) - { - //Discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; - } + WriteTriangle(index + i * 3, index + i * 3 + 1, index + i * 3 + 2); } - else - { - for (int i = 0; i < numTris; i++) - { - *Tptr++ = index; - *Tptr++ = index+i+1; - *Tptr++ = index+i+2; - } - } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_Fan; } -void IndexGenerator::AddQuads(int numVerts) +void IndexGenerator::AddStrip(u32 const numVerts) { - if(numVerts <= 0) return; - int numTris = (numVerts/4)*2; - if (numTris == 0) + bool wind = false; + for (u32 i = 2; i < numVerts; ++i) { - //if we have less than 3 verts - if(numVerts == 1) - { - //discard - index++; - return; - } - else - { - if(numVerts == 2) - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index + 1; - *Tptr++ = index; - } - else - { - //we have 3 verts render a full triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index + 1; - *Tptr++ = index + 2; - } - } + WriteTriangle( + index + i - 2, + index + i - !wind, + index + i - wind); + + wind ^= true; } - else +} + +void IndexGenerator::AddFan(u32 numVerts) +{ + for (u32 i = 2; i < numVerts; ++i) { - for (int i = 0; i < numTris / 2; i++) - { - *Tptr++ = index+i*4; - *Tptr++ = index+i*4+1; - *Tptr++ = index+i*4+2; - *Tptr++ = index+i*4; - *Tptr++ = index+i*4+2; - *Tptr++ = index+i*4+3; - } - int baseRemainingverts = numVerts - numVerts % 4; - switch (numVerts % 4) - { - case 3: - //whe have 3 remaining verts use strip method - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - *Tptr++ = index + baseRemainingverts + 2; - numTris++; - break; - case 2: - //whe have 2 remaining verts use strip method - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - numTris++; - break; - case 1: - //whe have 1 remaining verts use strip method this is only a conjeture - *Tptr++ = index + baseRemainingverts - 2; - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - numTris++; - break; - default: - break; - }; + WriteTriangle(index, index + i - 1, index + i); } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_List; } - -//Lines -void IndexGenerator::AddLineList(int numVerts) +void IndexGenerator::AddQuads(u32 numVerts) { - if(numVerts <= 0) return; - int numLines = numVerts / 2; - if (!numLines) + auto const numQuads = numVerts / 4; + for (u32 i = 0; i != numQuads; ++i) { - //Discard - index++; - return; + WriteTriangle(index + i * 4, index + i * 4 + 1, index + i * 4 + 2); + WriteTriangle(index + i * 4, index + i * 4 + 2, index + i * 4 + 3); } - else +} + +// Lines +void IndexGenerator::AddLineList(u32 numVerts) +{ + auto const numLines = numVerts / 2; + for (u32 i = 0; i != numLines; ++i) { - for (int i = 0; i < numLines; i++) - { - *Lptr++ = index+i*2; - *Lptr++ = index+i*2+1; - } - if((numVerts & 1) != 0) - { - //use line strip for remaining vert - *Lptr++ = index + numLines * 2 - 1; - *Lptr++ = index + numLines * 2; - } + *Lptr++ = index + i * 2; + *Lptr++ = index + i * 2 + 1; + ++numL; } - index += numVerts; - numL += numLines; - Ladds++; - LastLPrimitive = Prim_List; } -void IndexGenerator::AddLineStrip(int numVerts) +void IndexGenerator::AddLineStrip(u32 numVerts) { - int numLines = numVerts - 1; - if (numLines <= 0) + for (u32 i = 1; i < numVerts; ++i) { - if(numVerts == 1) - { - index++; - } - return; + *Lptr++ = index + i - 1; + *Lptr++ = index + i; + ++numL; } - for (int i = 0; i < numLines; i++) +} + +// Points +void IndexGenerator::AddPoints(u32 numVerts) +{ + for (u32 i = 0; i != numVerts; ++i) { - *Lptr++ = index+i; - *Lptr++ = index+i+1; + *Pptr++ = index + i; + ++numP; } - index += numVerts; - numL += numLines; - Ladds++; - LastLPrimitive = Prim_Strip; } - -//Points -void IndexGenerator::AddPoints(int numVerts) +u32 IndexGenerator::GetRemainingIndices() { - for (int i = 0; i < numVerts; i++) - { - *Pptr++ = index+i; - } - index += numVerts; - numP += numVerts; - Padds++; + u32 max_index = 65535; + return max_index - index; } |
