aboutsummaryrefslogtreecommitdiff
path: root/src/GPU3D_OpenGL.cpp
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-08-19 14:53:42 +0200
committerArisotura <thetotalworm@gmail.com>2020-08-19 14:53:42 +0200
commit00f33343e4b2b58eacba46238928fc7c870063ad (patch)
treeea68eb1777a62d9191889b8a11ef29ea68d39f31 /src/GPU3D_OpenGL.cpp
parentde19ce6250dcdcaae8a5a67d2e88694b771eafad (diff)
3D/GL: experimental attempt at reducing warping on quads, pentagons, etc...
Diffstat (limited to 'src/GPU3D_OpenGL.cpp')
-rw-r--r--src/GPU3D_OpenGL.cpp124
1 files changed, 114 insertions, 10 deletions
diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp
index b47f0b5..1abc1de 100644
--- a/src/GPU3D_OpenGL.cpp
+++ b/src/GPU3D_OpenGL.cpp
@@ -641,26 +641,130 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
*iptr++ = vidx - 1;
rp->NumIndices += 3;
}
- else
+ else // quad, pentagon, etc
{
rp->PrimType = GL_TRIANGLES;
- for (int j = 0; j < poly->NumVertices; j++)
+ if (false)
{
- Vertex* vtx = poly->Vertices[j];
+ // regular triangle-splitting
- vptr = SetupVertex(poly, j, vtx, vtxattr, vptr);
+ for (int j = 0; j < poly->NumVertices; j++)
+ {
+ Vertex* vtx = poly->Vertices[j];
+
+ vptr = SetupVertex(poly, j, vtx, vtxattr, vptr);
- if (j >= 2)
+ if (j >= 2)
+ {
+ // build a triangle
+ *iptr++ = vidx_first;
+ *iptr++ = vidx - 1;
+ *iptr++ = vidx;
+ rp->NumIndices += 3;
+ }
+
+ vidx++;
+ }
+ }
+ else
+ {
+ // attempt at 'better' splitting
+ // this doesn't get rid of the error while splitting a bigger polygon into triangles
+ // but we can attempt to reduce it
+
+ u32 cX = 0, cY = 0;
+ float cZ = 0;
+ float cW = 0;
+
+ float cR = 0, cG = 0, cB = 0;
+ float cS = 0, cT = 0;
+
+ for (int j = 0; j < poly->NumVertices; j++)
{
- // build a triangle
- *iptr++ = vidx_first;
- *iptr++ = vidx - 1;
- *iptr++ = vidx;
- rp->NumIndices += 3;
+ Vertex* vtx = poly->Vertices[j];
+
+ cX += vtx->HiresPosition[0];
+ cY += vtx->HiresPosition[1];
+
+ float fw = (float)poly->FinalW[j] * poly->NumVertices;
+ cW += 1.0f / fw;
+
+ if (poly->WBuffer) cZ += poly->FinalZ[j] / fw;
+ else cZ += poly->FinalZ[j];
+
+ cR += (vtx->FinalColor[0] >> 1) / fw;
+ cG += (vtx->FinalColor[1] >> 1) / fw;
+ cB += (vtx->FinalColor[2] >> 1) / fw;
+
+ cS += vtx->TexCoords[0] / fw;
+ cT += vtx->TexCoords[1] / fw;
}
+ cX /= poly->NumVertices;
+ cY /= poly->NumVertices;
+
+ cW = 1.0f / cW;
+
+ if (poly->WBuffer) cZ *= cW;
+ else cZ /= poly->NumVertices;
+
+ cR *= cW;
+ cG *= cW;
+ cB *= cW;
+
+ cS *= cW;
+ cT *= cW;
+
+ cX = (cX * ScaleFactor) >> 4;
+ cY = (cY * ScaleFactor) >> 4;
+
+ u32 w = (u32)cW;
+
+ u32 z = (u32)cZ;
+ u32 zshift = 0;
+ while (z > 0xFFFF) { z >>= 1; zshift++; }
+
+ // build center vertex
+ *vptr++ = cX | (cY << 16);
+ *vptr++ = z | (w << 16);
+
+ *vptr++ = (u32)cR |
+ ((u32)cG << 8) |
+ ((u32)cB << 16) |
+ (alpha << 24);
+
+ *vptr++ = (u16)cS | ((u16)cT << 16);
+
+ *vptr++ = vtxattr | (zshift << 16);
+ *vptr++ = poly->TexParam;
+ *vptr++ = poly->TexPalette;
+
vidx++;
+
+ // build the final polygon
+ for (int j = 0; j < poly->NumVertices; j++)
+ {
+ Vertex* vtx = poly->Vertices[j];
+
+ vptr = SetupVertex(poly, j, vtx, vtxattr, vptr);
+
+ if (j >= 1)
+ {
+ // build a triangle
+ *iptr++ = vidx_first;
+ *iptr++ = vidx - 1;
+ *iptr++ = vidx;
+ rp->NumIndices += 3;
+ }
+
+ vidx++;
+ }
+
+ *iptr++ = vidx_first;
+ *iptr++ = vidx - 1;
+ *iptr++ = vidx_first + 1;
+ rp->NumIndices += 3;
}
}