GFX3D: Obsolete and remove the VERT struct, since OpenGL, and SoftRasterizer are now both receiving their vertex data in fixed-point.

- Also remove the unused NDSVertexf struct. There shall be only one representation of the NDS vertex data, and that shall be the fixed-point values of NDSVertex.
This commit is contained in:
rogerman 2023-03-06 22:19:09 -08:00
parent 952585eaae
commit ab17945377
4 changed files with 54 additions and 440 deletions

View File

@ -370,30 +370,34 @@ void GFX3D_SaveStateVertex(const NDSVertex &vtx, EMUFILE &os)
void GFX3D_LoadStateVertex(NDSVertex &vtx, EMUFILE &is) void GFX3D_LoadStateVertex(NDSVertex &vtx, EMUFILE &is)
{ {
// Read the legacy vertex format. // Read the legacy vertex format.
VERT legacyVtx; Vector4f32 legacyPosition;
is.read_floatLE(legacyVtx.x); Vector2f32 legacyTexCoord;
is.read_floatLE(legacyVtx.y); Color4u8 legacyColor;
is.read_floatLE(legacyVtx.z); Color3f32 legacyColorFloat;
is.read_floatLE(legacyVtx.w);
is.read_floatLE(legacyVtx.u); is.read_floatLE(legacyPosition.x);
is.read_floatLE(legacyVtx.v); is.read_floatLE(legacyPosition.y);
is.read_u8(legacyVtx.color[0]); is.read_floatLE(legacyPosition.z);
is.read_u8(legacyVtx.color[1]); is.read_floatLE(legacyPosition.w);
is.read_u8(legacyVtx.color[2]); is.read_floatLE(legacyTexCoord.u);
is.read_floatLE(legacyVtx.fcolor[0]); is.read_floatLE(legacyTexCoord.v);
is.read_floatLE(legacyVtx.fcolor[1]); is.read_u8(legacyColor.r);
is.read_floatLE(legacyVtx.fcolor[2]); is.read_u8(legacyColor.g);
is.read_u8(legacyColor.b);
is.read_floatLE(legacyColorFloat.r);
is.read_floatLE(legacyColorFloat.g);
is.read_floatLE(legacyColorFloat.b);
// Convert the legacy vertex format to the new one. // Convert the legacy vertex format to the new one.
vtx.position.x = (s32)( (legacyVtx.x * 4096.0f) + 0.5f ); vtx.position.x = (s32)( (legacyPosition.x * 4096.0f) + 0.5f );
vtx.position.y = (s32)( (legacyVtx.y * 4096.0f) + 0.5f ); vtx.position.y = (s32)( (legacyPosition.y * 4096.0f) + 0.5f );
vtx.position.z = (s32)( (legacyVtx.z * 4096.0f) + 0.5f ); vtx.position.z = (s32)( (legacyPosition.z * 4096.0f) + 0.5f );
vtx.position.w = (s32)( (legacyVtx.w * 4096.0f) + 0.5f ); vtx.position.w = (s32)( (legacyPosition.w * 4096.0f) + 0.5f );
vtx.texCoord.s = (s32)( (legacyVtx.u * 16.0f) + 0.5f ); vtx.texCoord.s = (s32)( (legacyTexCoord.u * 16.0f) + 0.5f );
vtx.texCoord.t = (s32)( (legacyVtx.v * 16.0f) + 0.5f ); vtx.texCoord.t = (s32)( (legacyTexCoord.v * 16.0f) + 0.5f );
vtx.color.r = legacyVtx.r; vtx.color.r = legacyColor.r;
vtx.color.g = legacyVtx.g; vtx.color.g = legacyColor.g;
vtx.color.b = legacyVtx.b; vtx.color.b = legacyColor.b;
vtx.color.a = 0; vtx.color.a = 0;
} }
@ -3271,8 +3275,7 @@ size_t gfx3d_PerformClipping(const GFX3D_GeometryList &gList, CPoly *outCPolyUns
for (size_t j = 0; j < (size_t)cPoly.type; j++) for (size_t j = 0; j < (size_t)cPoly.type; j++)
{ {
NDSVertex &vtx = cPoly.clipVtxFixed[j]; NDSVertex &vtx = cPoly.vtx[j];
VERT &vert = cPoly.clipVerts[j];
Vector4s64 vtx64 = { Vector4s64 vtx64 = {
(s64)vtx.position.x, (s64)vtx.position.x,
(s64)vtx.position.y, (s64)vtx.position.y,
@ -3311,49 +3314,15 @@ size_t gfx3d_PerformClipping(const GFX3D_GeometryList &gList, CPoly *outCPolyUns
vtx64.y = (192LL << 16) - vtx64.y; vtx64.y = (192LL << 16) - vtx64.y;
vtx64.y *= hScalar; vtx64.y *= hScalar;
// At the very least, we need to save the transformed position so that
// we can use it to calculate the polygon facing later.
vtx.position.x = (s32)vtx64.x; vtx.position.x = (s32)vtx64.x;
vtx.position.y = (s32)vtx64.y; vtx.position.y = (s32)vtx64.y;
vtx.position.z = (s32)vtx64.z; vtx.position.z = (s32)vtx64.z;
vtx.position.w = (s32)vtx64.w; vtx.position.w = (s32)vtx64.w;
// TODO: Remove these floating-point conversions.
//here is a hack which needs to be removed.
//at some point our shape engine needs these to be converted to "fixed point"
//which is currently just a float
vert.x = (float)((double)vtx64.x / 4096.0);
vert.y = (float)((double)vtx64.y / 4096.0);
vert.z = (float)((double)vtx64.z / 4096.0);
vert.w = (float)((double)vtx64.w / 4096.0);
vert.x = (float)iround(vert.x);
vert.y = (float)iround(vert.y);
if (CLIPPERMODE != ClipperMode_DetermineClipOnly)
{
if (vtx.position.w != 0)
{
const float invWTC = 256.0f / (float)vtx.position.w;
const float invW = 4096.0f / (float)vtx.position.w;
// Texture coordinates
vert.u = (float)vtx.texCoord.u * invWTC;
vert.v = (float)vtx.texCoord.v * invWTC;
// Vertex color
vert.rf = (float)vtx.color.r * invW;
vert.gf = (float)vtx.color.g * invW;
vert.bf = (float)vtx.color.b * invW;
}
else
{
vert.u = (float)vtx.texCoord.u / 16.0f;
vert.v = (float)vtx.texCoord.v / 16.0f;
}
vert.color32 = vtx.color.value;
}
} }
// Perform face culling. // Determine the polygon facing.
//an older approach //an older approach
//(not good enough for quads and other shapes) //(not good enough for quads and other shapes)
@ -3364,7 +3333,7 @@ size_t gfx3d_PerformClipping(const GFX3D_GeometryList &gList, CPoly *outCPolyUns
// we have to support somewhat non-convex polygons (see NSMB world map 1st screen). // we have to support somewhat non-convex polygons (see NSMB world map 1st screen).
// this version should handle those cases better. // this version should handle those cases better.
const NDSVertex *vtx = cPoly.clipVtxFixed; const NDSVertex *vtx = cPoly.vtx;
const size_t n = cPoly.type - 1; const size_t n = cPoly.type - 1;
s64 facing = ((s64)vtx[0].position.y + (s64)vtx[n].position.y) * ((s64)vtx[0].position.x - (s64)vtx[n].position.x) + s64 facing = ((s64)vtx[0].position.y + (s64)vtx[n].position.y) * ((s64)vtx[0].position.x - (s64)vtx[n].position.x) +
((s64)vtx[1].position.y + (s64)vtx[0].position.y) * ((s64)vtx[1].position.x - (s64)vtx[0].position.x) + ((s64)vtx[1].position.y + (s64)vtx[0].position.y) * ((s64)vtx[1].position.x - (s64)vtx[0].position.x) +
@ -3377,6 +3346,7 @@ size_t gfx3d_PerformClipping(const GFX3D_GeometryList &gList, CPoly *outCPolyUns
cPoly.isPolyBackFacing = (facing < 0); cPoly.isPolyBackFacing = (facing < 0);
// Perform face culling.
static const bool visibleFunction[2][4] = { static const bool visibleFunction[2][4] = {
//always false, backfacing, !backfacing, always true //always false, backfacing, !backfacing, always true
{ false, false, true, true }, { false, false, true, true },
@ -4289,57 +4259,6 @@ static T GFX3D_LerpUnsigned(const u64 ratio_20_12, const u64 x0, const u64 x1)
} }
//http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as6/discussion.shtml //http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as6/discussion.shtml
template <ClipperMode CLIPPERMODE, int COORD, int WHICH>
static FORCEINLINE void GFX3D_ClipPoint(const VERT &insideVtx, const VERT &outsideVtx, VERT &outClippedVtx)
{
const float coord_inside = insideVtx.coord[COORD];
const float coord_outside = outsideVtx.coord[COORD];
const float w_inside = (WHICH == -1) ? -insideVtx.coord[3] : insideVtx.coord[3];
const float w_outside = (WHICH == -1) ? -outsideVtx.coord[3] : outsideVtx.coord[3];
const float t = (coord_inside - w_inside) / ((w_outside-w_inside) - (coord_outside-coord_inside));
outClippedVtx.x = GFX3D_LerpFloat<float>(t, insideVtx.x, outsideVtx.x);
outClippedVtx.y = GFX3D_LerpFloat<float>(t, insideVtx.y, outsideVtx.y);
outClippedVtx.z = GFX3D_LerpFloat<float>(t, insideVtx.z, outsideVtx.z);
outClippedVtx.w = GFX3D_LerpFloat<float>(t, insideVtx.w, outsideVtx.w);
switch (CLIPPERMODE)
{
case ClipperMode_Full:
outClippedVtx.u = GFX3D_LerpFloat<float>(t, insideVtx.u, outsideVtx.u);
outClippedVtx.v = GFX3D_LerpFloat<float>(t, insideVtx.v, outsideVtx.v);
outClippedVtx.r = GFX3D_LerpFloat<u8>(t, insideVtx.r, outsideVtx.r);
outClippedVtx.g = GFX3D_LerpFloat<u8>(t, insideVtx.g, outsideVtx.g);
outClippedVtx.b = GFX3D_LerpFloat<u8>(t, insideVtx.b, outsideVtx.b);
outClippedVtx.rf = (float)outClippedVtx.r;
outClippedVtx.gf = (float)outClippedVtx.g;
outClippedVtx.bf = (float)outClippedVtx.b;
break;
case ClipperMode_FullColorInterpolate:
outClippedVtx.u = GFX3D_LerpFloat<float>(t, insideVtx.u, outsideVtx.u);
outClippedVtx.v = GFX3D_LerpFloat<float>(t, insideVtx.v, outsideVtx.v);
outClippedVtx.rf = GFX3D_LerpFloat<float>(t, insideVtx.rf, outsideVtx.rf);
outClippedVtx.gf = GFX3D_LerpFloat<float>(t, insideVtx.gf, outsideVtx.gf);
outClippedVtx.bf = GFX3D_LerpFloat<float>(t, insideVtx.bf, outsideVtx.bf);
break;
case ClipperMode_DetermineClipOnly:
// Do nothing.
break;
}
//this seems like a prudent measure to make sure that math doesnt make a point pop back out
//of the clip volume through interpolation
if (WHICH == -1)
outClippedVtx.coord[COORD] = -outClippedVtx.coord[3];
else
outClippedVtx.coord[COORD] = outClippedVtx.coord[3];
}
template <ClipperMode CLIPPERMODE, int COORD, int WHICH> template <ClipperMode CLIPPERMODE, int COORD, int WHICH>
static FORCEINLINE void GFX3D_ClipPoint(const NDSVertex &insideVtx, const NDSVertex &outsideVtx, NDSVertex &outClippedVtx) static FORCEINLINE void GFX3D_ClipPoint(const NDSVertex &insideVtx, const NDSVertex &outsideVtx, NDSVertex &outClippedVtx)
{ {
@ -4397,8 +4316,7 @@ static FORCEINLINE void GFX3D_ClipPoint(const NDSVertex &insideVtx, const NDSVer
} }
#define MAX_SCRATCH_CLIP_VERTS (4*6 + 40) #define MAX_SCRATCH_CLIP_VERTS (4*6 + 40)
static VERT scratchClipVerts[MAX_SCRATCH_CLIP_VERTS]; static NDSVertex scratchClipVerts[MAX_SCRATCH_CLIP_VERTS];
static NDSVertex scratchClipVertsFixed[MAX_SCRATCH_CLIP_VERTS];
static size_t numScratchClipVerts = 0; static size_t numScratchClipVerts = 0;
template <ClipperMode CLIPPERMODE, int COORD, int WHICH, class NEXT> template <ClipperMode CLIPPERMODE, int COORD, int WHICH, class NEXT>
@ -4406,117 +4324,44 @@ class ClipperPlane
{ {
public: public:
ClipperPlane(NEXT &next) : m_next(next) {} ClipperPlane(NEXT &next) : m_next(next) {}
void init(VERT *verts)
{
m_prevVert = NULL;
m_firstVert = NULL;
m_prevVertFixed = NULL;
m_firstVertFixed = NULL;
m_next.init(verts);
}
void init(NDSVertex *vtxList) void init(NDSVertex *vtxList)
{ {
m_prevVert = NULL; m_prevVert = NULL;
m_firstVert = NULL; m_firstVert = NULL;
m_prevVertFixed = NULL;
m_firstVertFixed = NULL;
m_next.init(vtxList); m_next.init(vtxList);
} }
void clipVert(const VERT &vtx)
{
if (m_prevVert)
this->clipSegmentVsPlane(*m_prevVert, vtx);
else
m_firstVert = (VERT *)&vtx;
m_prevVert = (VERT *)&vtx;
}
void clipVert(const NDSVertex &vtx) void clipVert(const NDSVertex &vtx)
{ {
if (m_prevVertFixed != NULL) if (m_prevVert != NULL)
{ {
this->clipSegmentVsPlane(*m_prevVertFixed, vtx); this->clipSegmentVsPlane(*m_prevVert, vtx);
} }
else else
{ {
m_firstVertFixed = (NDSVertex *)&vtx; m_firstVert = (NDSVertex *)&vtx;
} }
m_prevVertFixed = (NDSVertex *)&vtx; m_prevVert = (NDSVertex *)&vtx;
} }
// closes the loop and returns the number of clipped output verts // closes the loop and returns the number of clipped output verts
int finish() int finish()
{ {
if (m_firstVert != NULL) if (m_prevVert != NULL)
{ {
this->clipVert(*m_firstVert); this->clipVert(*m_firstVert);
} }
else if (m_prevVertFixed != NULL)
{
this->clipVert(*m_firstVertFixed);
}
return m_next.finish(); return m_next.finish();
} }
private: private:
VERT *m_prevVert; NDSVertex *m_prevVert;
VERT *m_firstVert; NDSVertex *m_firstVert;
NDSVertex *m_prevVertFixed;
NDSVertex *m_firstVertFixed;
NEXT &m_next; NEXT &m_next;
FORCEINLINE void clipSegmentVsPlane(const VERT &vert0, const VERT &vert1)
{
const float *vert0coord = vert0.coord;
const float *vert1coord = vert1.coord;
const bool out0 = (WHICH == -1) ? (vert0coord[COORD] < -vert0coord[3]) : (vert0coord[COORD] > vert0coord[3]);
const bool out1 = (WHICH == -1) ? (vert1coord[COORD] < -vert1coord[3]) : (vert1coord[COORD] > vert1coord[3]);
//CONSIDER: should we try and clip things behind the eye? does this code even successfully do it? not sure.
//if(coord==2 && which==1) {
// out0 = vert0coord[2] < 0;
// out1 = vert1coord[2] < 0;
//}
//both outside: insert no points
if (out0 && out1)
{
CLIPLOG(" both outside\n");
}
//both inside: insert the next point
if (!out0 && !out1)
{
CLIPLOG(" both inside\n");
m_next.clipVert(vert1);
}
//exiting volume: insert the clipped point
if (!out0 && out1)
{
CLIPLOG(" exiting\n");
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vert0, vert1, scratchClipVerts[numScratchClipVerts]);
m_next.clipVert(scratchClipVerts[numScratchClipVerts++]);
}
//entering volume: insert clipped point and the next (interior) point
if (out0 && !out1)
{
CLIPLOG(" entering\n");
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vert1, vert0, scratchClipVerts[numScratchClipVerts]);
m_next.clipVert(scratchClipVerts[numScratchClipVerts++]);
m_next.clipVert(vert1);
}
}
FORCEINLINE void clipSegmentVsPlane(const NDSVertex &vtx0, const NDSVertex &vtx1) FORCEINLINE void clipSegmentVsPlane(const NDSVertex &vtx0, const NDSVertex &vtx1)
{ {
const bool out0 = (WHICH == -1) ? (vtx0.position.coord[COORD] < -vtx0.position.coord[3]) : (vtx0.position.coord[COORD] > vtx0.position.coord[3]); const bool out0 = (WHICH == -1) ? (vtx0.position.coord[COORD] < -vtx0.position.coord[3]) : (vtx0.position.coord[COORD] > vtx0.position.coord[3]);
@ -4546,8 +4391,8 @@ private:
{ {
CLIPLOG(" exiting\n"); CLIPLOG(" exiting\n");
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS); assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vtx0, vtx1, scratchClipVertsFixed[numScratchClipVerts]); GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vtx0, vtx1, scratchClipVerts[numScratchClipVerts]);
m_next.clipVert(scratchClipVertsFixed[numScratchClipVerts++]); m_next.clipVert(scratchClipVerts[numScratchClipVerts++]);
} }
//entering volume: insert clipped point and the next (interior) point //entering volume: insert clipped point and the next (interior) point
@ -4555,8 +4400,8 @@ private:
{ {
CLIPLOG(" entering\n"); CLIPLOG(" entering\n");
assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS); assert((u32)numScratchClipVerts < MAX_SCRATCH_CLIP_VERTS);
GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vtx1, vtx0, scratchClipVertsFixed[numScratchClipVerts]); GFX3D_ClipPoint<CLIPPERMODE, COORD, WHICH>(vtx1, vtx0, scratchClipVerts[numScratchClipVerts]);
m_next.clipVert(scratchClipVertsFixed[numScratchClipVerts++]); m_next.clipVert(scratchClipVerts[numScratchClipVerts++]);
m_next.clipVert(vtx1); m_next.clipVert(vtx1);
} }
} }
@ -4565,31 +4410,16 @@ private:
class ClipperOutput class ClipperOutput
{ {
public: public:
void init(VERT *verts)
{
m_nextDestVert = verts;
m_nextDestVertFixed = NULL;
m_numVerts = 0;
}
void init(NDSVertex *vtxList) void init(NDSVertex *vtxList)
{ {
m_nextDestVert = NULL; m_nextDestVert = vtxList;
m_nextDestVertFixed = vtxList;
m_numVerts = 0; m_numVerts = 0;
} }
void clipVert(const VERT &vert)
{
assert((u32)m_numVerts < MAX_CLIPPED_VERTS);
*m_nextDestVert++ = vert;
m_numVerts++;
}
void clipVert(const NDSVertex &vtx) void clipVert(const NDSVertex &vtx)
{ {
assert((u32)m_numVerts < MAX_CLIPPED_VERTS); assert((u32)m_numVerts < MAX_CLIPPED_VERTS);
*m_nextDestVertFixed++ = vtx; *m_nextDestVert++ = vtx;
m_numVerts++; m_numVerts++;
} }
@ -4599,8 +4429,7 @@ public:
} }
private: private:
VERT *m_nextDestVert; NDSVertex *m_nextDestVert;
NDSVertex *m_nextDestVertFixed;
int m_numVerts; int m_numVerts;
}; };
@ -4634,61 +4463,6 @@ typedef ClipperPlane<ClipperMode_DetermineClipOnly, 1,-1,Stage4d> Stage3d;
typedef ClipperPlane<ClipperMode_DetermineClipOnly, 0, 1,Stage3d> Stage2d; static Stage2d clipper2d (clipper3d); // right plane typedef ClipperPlane<ClipperMode_DetermineClipOnly, 0, 1,Stage3d> Stage2d; static Stage2d clipper2d (clipper3d); // right plane
typedef ClipperPlane<ClipperMode_DetermineClipOnly, 0,-1,Stage2d> Stage1d; static Stage1d clipper1d (clipper2d); // left plane typedef ClipperPlane<ClipperMode_DetermineClipOnly, 0,-1,Stage2d> Stage1d; static Stage1d clipper1d (clipper2d); // left plane
template <ClipperMode CLIPPERMODE>
PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const VERT *(&rawVtx)[4], CPoly &outCPoly)
{
CLIPLOG("==Begin poly==\n");
PolygonType outClippedType;
numScratchClipVerts = 0;
switch (CLIPPERMODE)
{
case ClipperMode_Full:
{
clipper1.init(outCPoly.clipVerts);
for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1.clipVert(*rawVtx[i]);
outClippedType = (PolygonType)clipper1.finish();
break;
}
case ClipperMode_FullColorInterpolate:
{
clipper1i.init(outCPoly.clipVerts);
for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1i.clipVert(*rawVtx[i]);
outClippedType = (PolygonType)clipper1i.finish();
break;
}
case ClipperMode_DetermineClipOnly:
{
clipper1d.init(outCPoly.clipVerts);
for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1d.clipVert(*rawVtx[i]);
outClippedType = (PolygonType)clipper1d.finish();
break;
}
}
assert((u32)outClippedType < MAX_CLIPPED_VERTS);
if (outClippedType < POLYGON_TYPE_TRIANGLE)
{
//a totally clipped poly. discard it.
//or, a degenerate poly. we're not handling these right now
return POLYGON_TYPE_UNDEFINED;
}
outCPoly.index = rawPolyIndex;
outCPoly.type = outClippedType;
return outClippedType;
}
template <ClipperMode CLIPPERMODE> template <ClipperMode CLIPPERMODE>
PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const NDSVertex *(&rawVtx)[4], CPoly &outCPoly) PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const NDSVertex *(&rawVtx)[4], CPoly &outCPoly)
{ {
@ -4701,7 +4475,7 @@ PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType
{ {
case ClipperMode_Full: case ClipperMode_Full:
{ {
clipper1.init(outCPoly.clipVtxFixed); clipper1.init(outCPoly.vtx);
for (size_t i = 0; i < (size_t)rawPolyType; i++) for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1.clipVert(*rawVtx[i]); clipper1.clipVert(*rawVtx[i]);
@ -4711,7 +4485,7 @@ PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType
case ClipperMode_FullColorInterpolate: case ClipperMode_FullColorInterpolate:
{ {
clipper1i.init(outCPoly.clipVtxFixed); clipper1i.init(outCPoly.vtx);
for (size_t i = 0; i < (size_t)rawPolyType; i++) for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1i.clipVert(*rawVtx[i]); clipper1i.clipVert(*rawVtx[i]);
@ -4721,7 +4495,7 @@ PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType
case ClipperMode_DetermineClipOnly: case ClipperMode_DetermineClipOnly:
{ {
clipper1d.init(outCPoly.clipVtxFixed); clipper1d.init(outCPoly.vtx);
for (size_t i = 0; i < (size_t)rawPolyType; i++) for (size_t i = 0; i < (size_t)rawPolyType; i++)
clipper1d.clipVert(*rawVtx[i]); clipper1d.clipVert(*rawVtx[i]);

View File

@ -565,55 +565,6 @@ bool GFX3D_IsPolyTranslucent(const POLY &p);
#define CLIPPED_POLYLIST_SIZE (POLYLIST_SIZE * 2) #define CLIPPED_POLYLIST_SIZE (POLYLIST_SIZE * 2)
#define VERTLIST_SIZE (POLYLIST_SIZE * 4) #define VERTLIST_SIZE (POLYLIST_SIZE * 4)
#include "PACKED.h"
// This struct is padded in such a way so that each component can be accessed with a 16-byte alignment.
struct VERT
{
union
{
float coord[4];
struct
{
float x, y, z, w;
};
};
union
{
float texcoord[4];
struct
{
float u, v, tcPad2, tcPad3;
};
};
union
{
float fcolor[4];
struct
{
float rf, gf, bf, af; // The alpha value is unused and only exists for padding purposes.
};
};
union
{
u32 color32;
u8 color[4];
struct
{
u8 r, g, b, a; // The alpha value is unused and only exists for padding purposes.
};
};
u8 padFinal[12]; // Final padding to bring the struct to exactly 64 bytes.
};
typedef struct VERT VERT;
#include "PACKED_END.h"
struct NDSVertex struct NDSVertex
{ {
Vector4s32 position; Vector4s32 position;
@ -622,14 +573,6 @@ struct NDSVertex
}; };
typedef struct NDSVertex NDSVertex; typedef struct NDSVertex NDSVertex;
struct NDSVertexf
{
Vector4f32 position;
Vector2f32 texCoord;
Color4f32 color;
};
typedef struct NDSVertexf NDSVertexf;
//ok, imagine the plane that cuts diagonally across a cube such that it clips //ok, imagine the plane that cuts diagonally across a cube such that it clips
//out to be a hexagon. within that plane, draw a quad such that it cuts off //out to be a hexagon. within that plane, draw a quad such that it cuts off
//four corners of the hexagon, and you will observe a decagon //four corners of the hexagon, and you will observe a decagon
@ -647,8 +590,7 @@ struct CPoly
u16 index; // The index number of this polygon in the full polygon list. u16 index; // The index number of this polygon in the full polygon list.
PolygonType type; //otherwise known as "count" of verts PolygonType type; //otherwise known as "count" of verts
bool isPolyBackFacing; bool isPolyBackFacing;
VERT clipVerts[MAX_CLIPPED_VERTS]; NDSVertex vtx[MAX_CLIPPED_VERTS];
NDSVertex clipVtxFixed[MAX_CLIPPED_VERTS];
}; };
typedef struct CPoly CPoly; typedef struct CPoly CPoly;
@ -1067,7 +1009,6 @@ void GFX3D_HandleGeometryPowerOff();
u32 GFX3D_GetRender3DFrameCount(); u32 GFX3D_GetRender3DFrameCount();
void GFX3D_ResetRender3DFrameCount(); void GFX3D_ResetRender3DFrameCount();
template<ClipperMode CLIPPERMODE> PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const VERT *(&rawVtx)[4], CPoly &outCPoly);
template<ClipperMode CLIPPERMODE> PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const NDSVertex *(&rawVtx)[4], CPoly &outCPoly); template<ClipperMode CLIPPERMODE> PolygonType GFX3D_GenerateClippedPoly(const u16 rawPolyIndex, const PolygonType rawPolyType, const NDSVertex *(&rawVtx)[4], CPoly &outCPoly);
#endif //_GFX3D_H_ #endif //_GFX3D_H_

View File

@ -68,10 +68,6 @@
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/xbrz.h" #include "filter/xbrz.h"
// Enable this macro to allow SoftRasterizer to read in vertex data in
// the native fixed-point format rather than using our own normalized
// floating-point format.
#define USE_FIXED_POINT_VERTEX_DATA
using std::min; using std::min;
using std::max; using std::max;
@ -172,11 +168,9 @@ static FORCEINLINE s32 Ceil28_4(fixed28_4 Value)
struct edge_fx_fl struct edge_fx_fl
{ {
edge_fx_fl() {} edge_fx_fl() {}
edge_fx_fl(const s32 top, const s32 bottom, VERT **vert, bool &failure);
edge_fx_fl(const s32 top, const s32 bottom, NDSVertex **vtx, SoftRasterizerPrecalculation **precalc, bool &failure); edge_fx_fl(const s32 top, const s32 bottom, NDSVertex **vtx, SoftRasterizerPrecalculation **precalc, bool &failure);
FORCEINLINE s32 Step(); FORCEINLINE s32 Step();
VERT **vert;
NDSVertex **vtx; NDSVertex **vtx;
s32 x, xStep; // DDA info for x s32 x, xStep; // DDA info for x
@ -227,85 +221,6 @@ struct edge_fx_fl
void FORCEINLINE doStepExtraInterpolants() { for(int i=0;i<NUM_INTERPOLANTS;i++) interpolants[i].doStepExtra(); } void FORCEINLINE doStepExtraInterpolants() { for(int i=0;i<NUM_INTERPOLANTS;i++) interpolants[i].doStepExtra(); }
}; };
FORCEINLINE edge_fx_fl::edge_fx_fl(const s32 top, const s32 bottom, VERT **vert, bool &failure)
{
s64 x_64;
s64 y_64;
s64 xStep_64;
this->vert = vert;
this->y = Ceil28_4((fixed28_4)vert[top]->y); // "28.4" to 28.0
const s32 yEnd = Ceil28_4((fixed28_4)vert[bottom]->y); // "28.4" to 28.0
this->height = yEnd - this->y; // 28.0
y_64 = (s64)this->y; // 28.0
this->x = Ceil28_4((fixed28_4)vert[top]->x); // "28.4" to 28.0
const s32 xEnd = Ceil28_4((fixed28_4)vert[bottom]->x); // "28.4" to 28.0
const s32 width = xEnd - this->x; // 28.0, can be negative
x_64 = (s64)this->x; // 28.0
// even if Height == 0, give some info for horizontal line poly
if ( (this->height != 0) || (width != 0) )
{
s64 dN = (s64)(vert[bottom]->y - vert[top]->y); // "28.4"
s64 dM = (s64)(vert[bottom]->x - vert[top]->x); // "28.4"
if (dN != 0)
{
const s64 initialNumerator = (s64)(dM*16*y_64 - dM*vert[top]->y + dN*vert[top]->x - 1 + dN*16); // "32.8" - "56.8" + "56.8" - 0.8 + "32.8"
FloorDivMod(initialNumerator, dN*16, x_64, this->errorTerm, failure); // "56.8", "32.8"; floor is 52.4, mod is 56.8
FloorDivMod(dM*16, dN*16, xStep_64, this->numerator, failure); // "32.8", "32.8"; floor is 28.4, mod is 32.8
this->x = (s32)x_64; // 52.4 to 28.4
this->xStep = (s32)xStep_64; // 28.4
this->denominator = dN*16; // "28.4" to "32.8"
}
else
{
this->errorTerm = 0; // 0.8
this->xStep = width; // 28.0
this->numerator = 0; // 0.8
this->denominator = 1; // 0.8
dN = 1; // 0.4
}
const float yPrestep = Fixed28_4ToFloat((fixed28_4)(y_64*16 - vert[top]->y)); // 28.4, "28.4"; result is normalized
const float xPrestep = Fixed28_4ToFloat((fixed28_4)(x_64*16 - vert[top]->x)); // 28.4, "28.4"; result is normalized
const float dy = 1.0f / Fixed28_4ToFloat((s32)dN); // "28.4"; result is normalized
const float dx = 1.0f / Fixed28_4ToFloat((s32)dM); // "28.4"; result is normalized
invw.initialize(1.0f / vert[top]->w, 1.0f / vert[bottom]->w, dx, dy, (float)this->xStep, xPrestep, yPrestep);
u.initialize(vert[top]->u, vert[bottom]->u, dx, dy, (float)this->xStep, xPrestep, yPrestep);
v.initialize(vert[top]->v, vert[bottom]->v, dx, dy, (float)this->xStep, xPrestep, yPrestep);
z.initialize(vert[top]->z, vert[bottom]->z, dx, dy, (float)this->xStep, xPrestep, yPrestep);
for (size_t i = 0; i < 3; i++)
{
color[i].initialize(vert[top]->fcolor[i], vert[bottom]->fcolor[i], dx, dy, (float)this->xStep, xPrestep, yPrestep);
}
}
else
{
// even if Width == 0 && Height == 0, give some info for pixel poly
// example: Castlevania Portrait of Ruin, warp stone
this->xStep = 1;
this->numerator = 0;
this->denominator = 1;
this->errorTerm = 0;
invw.initialize(1.0f / vert[top]->w);
u.initialize(vert[top]->u);
v.initialize(vert[top]->v);
z.initialize(vert[top]->z);
for (size_t i = 0; i < 3; i++)
{
color[i].initialize(vert[top]->fcolor[i]);
}
}
}
FORCEINLINE edge_fx_fl::edge_fx_fl(const s32 top, const s32 bottom, NDSVertex **vtx, SoftRasterizerPrecalculation **precalc, bool &failure) FORCEINLINE edge_fx_fl::edge_fx_fl(const s32 top, const s32 bottom, NDSVertex **vtx, SoftRasterizerPrecalculation **precalc, bool &failure)
{ {
s64 x_64 = precalc[top]->positionCeil.x; s64 x_64 = precalc[top]->positionCeil.x;
@ -1276,11 +1191,6 @@ FORCEINLINE void RasterizerUnit<RENDERER>::_rot_verts()
ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9); ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9);
#undef ROTSWAP #undef ROTSWAP
#define ROTSWAP(X) if(TYPE>X) swap(this->_currentVert[X-1],this->_currentVert[X]);
ROTSWAP(1); ROTSWAP(2); ROTSWAP(3); ROTSWAP(4);
ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9);
#undef ROTSWAP
#define ROTSWAP(X) if(TYPE>X) swap(this->_currentPrecalc[X-1],this->_currentPrecalc[X]); #define ROTSWAP(X) if(TYPE>X) swap(this->_currentPrecalc[X-1],this->_currentPrecalc[X]);
ROTSWAP(1); ROTSWAP(2); ROTSWAP(3); ROTSWAP(4); ROTSWAP(1); ROTSWAP(2); ROTSWAP(3); ROTSWAP(4);
ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9); ROTSWAP(5); ROTSWAP(6); ROTSWAP(7); ROTSWAP(8); ROTSWAP(9);
@ -1303,7 +1213,6 @@ void RasterizerUnit<RENDERER>::_sort_verts()
for (size_t i = 0; i < TYPE/2; i++) for (size_t i = 0; i < TYPE/2; i++)
{ {
swap(this->_currentVtx[i], this->_currentVtx[TYPE-i-1]); swap(this->_currentVtx[i], this->_currentVtx[TYPE-i-1]);
swap(this->_currentVert[i], this->_currentVert[TYPE-i-1]);
swap(this->_currentPrecalc[i], this->_currentPrecalc[TYPE-i-1]); swap(this->_currentPrecalc[i], this->_currentPrecalc[TYPE-i-1]);
} }
} }
@ -1371,13 +1280,8 @@ void RasterizerUnit<RENDERER>::_shape_engine(const POLYGON_ATTR polyAttr, const
assert(rv != type); assert(rv != type);
int _lv = (lv == type) ? 0 : lv; //make sure that we ask for vert 0 when the variable contains the starting value int _lv = (lv == type) ? 0 : lv; //make sure that we ask for vert 0 when the variable contains the starting value
#ifdef USE_FIXED_POINT_VERTEX_DATA
if (step_left) left = edge_fx_fl(_lv, lv-1, (NDSVertex **)&this->_currentVtx, (SoftRasterizerPrecalculation **)&this->_currentPrecalc, failure); if (step_left) left = edge_fx_fl(_lv, lv-1, (NDSVertex **)&this->_currentVtx, (SoftRasterizerPrecalculation **)&this->_currentPrecalc, failure);
if (step_right) right = edge_fx_fl(rv, rv+1, (NDSVertex **)&this->_currentVtx, (SoftRasterizerPrecalculation **)&this->_currentPrecalc, failure); if (step_right) right = edge_fx_fl(rv, rv+1, (NDSVertex **)&this->_currentVtx, (SoftRasterizerPrecalculation **)&this->_currentPrecalc, failure);
#else
if (step_left) left = edge_fx_fl(_lv, lv-1, (VERT **)&this->_currentVert, failure);
if (step_right) right = edge_fx_fl(rv, rv+1, (VERT **)&this->_currentVert, failure);
#endif
step_left = step_right = false; step_left = step_right = false;
@ -1465,15 +1369,13 @@ FORCEINLINE void RasterizerUnit<RENDERER>::Render()
for (size_t j = 0; j < vertCount; j++) for (size_t j = 0; j < vertCount; j++)
{ {
this->_currentVtx[j] = &clippedPoly.clipVtxFixed[j]; this->_currentVtx[j] = &clippedPoly.vtx[j];
this->_currentVert[j] = &clippedPoly.clipVerts[j];
this->_currentPrecalc[j] = &softRastPrecalc[(i * MAX_CLIPPED_VERTS) + j]; this->_currentPrecalc[j] = &softRastPrecalc[(i * MAX_CLIPPED_VERTS) + j];
} }
for (size_t j = vertCount; j < MAX_CLIPPED_VERTS; j++) for (size_t j = vertCount; j < MAX_CLIPPED_VERTS; j++)
{ {
this->_currentVtx[j] = NULL; this->_currentVtx[j] = NULL;
this->_currentVert[j] = NULL;
this->_currentPrecalc[j] = NULL; this->_currentPrecalc[j] = NULL;
} }
@ -2064,7 +1966,6 @@ void SoftRasterizerRenderer::GetAndLoadAllTextures()
void SoftRasterizerRenderer::RasterizerPrecalculate() void SoftRasterizerRenderer::RasterizerPrecalculate()
{ {
#ifdef USE_FIXED_POINT_VERTEX_DATA
for (size_t i = 0, precalcIdx = 0; i < this->_clippedPolyCount; i++) for (size_t i = 0, precalcIdx = 0; i < this->_clippedPolyCount; i++)
{ {
const CPoly &cPoly = this->_clippedPolyList[i]; const CPoly &cPoly = this->_clippedPolyList[i];
@ -2074,7 +1975,7 @@ void SoftRasterizerRenderer::RasterizerPrecalculate()
for (size_t j = 0; j < polyType; j++) for (size_t j = 0; j < polyType; j++)
{ {
const NDSVertex &vtx = cPoly.clipVtxFixed[j]; const NDSVertex &vtx = cPoly.vtx[j];
SoftRasterizerPrecalculation &precalc = this->_precalc[precalcIdx]; SoftRasterizerPrecalculation &precalc = this->_precalc[precalcIdx];
const s32 x = Ceil16_16(vtx.position.x); const s32 x = Ceil16_16(vtx.position.x);
@ -2110,7 +2011,6 @@ void SoftRasterizerRenderer::RasterizerPrecalculate()
precalcIdx++; precalcIdx++;
} }
} }
#endif
} }
Render3DError SoftRasterizerRenderer::ApplyRenderingSettings(const GFX3D_State &renderState) Render3DError SoftRasterizerRenderer::ApplyRenderingSettings(const GFX3D_State &renderState)

View File

@ -116,7 +116,6 @@ protected:
SoftRasterizerRenderer *_softRender; SoftRasterizerRenderer *_softRender;
SoftRasterizerTexture *_currentTexture; SoftRasterizerTexture *_currentTexture;
const VERT *_currentVert[MAX_CLIPPED_VERTS];
const NDSVertex *_currentVtx[MAX_CLIPPED_VERTS]; const NDSVertex *_currentVtx[MAX_CLIPPED_VERTS];
const SoftRasterizerPrecalculation *_currentPrecalc[MAX_CLIPPED_VERTS]; const SoftRasterizerPrecalculation *_currentPrecalc[MAX_CLIPPED_VERTS];
u8 _textureWrapMode; u8 _textureWrapMode;