summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Src/IndexGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/Src/IndexGenerator.cpp')
-rw-r--r--Source/Core/VideoCommon/Src/IndexGenerator.cpp364
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;
}