From 59ee89b622040f504ecd3aa59a63c6dc1a2c7b00 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 21 Sep 2017 01:21:21 +0200 Subject: [PATCH] - Make the relationship between TriMatrix, TriVertex and ShadedTriVertex more clean --- src/polyrenderer/drawers/poly_draw_args.h | 9 +++ src/polyrenderer/drawers/poly_drawer32.h | 2 +- src/polyrenderer/drawers/poly_drawer32_sse2.h | 2 +- src/polyrenderer/drawers/poly_drawer8.h | 2 +- src/polyrenderer/drawers/poly_triangle.cpp | 57 +++++++++++-------- src/polyrenderer/drawers/poly_triangle.h | 8 +-- src/polyrenderer/drawers/screen_triangle.cpp | 18 +++--- src/polyrenderer/drawers/screen_triangle.h | 30 +++++----- src/polyrenderer/math/tri_matrix.cpp | 26 ++++----- src/polyrenderer/math/tri_matrix.h | 2 +- 10 files changed, 82 insertions(+), 74 deletions(-) diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 69b89a053..c53b0260f 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -46,6 +46,15 @@ public: float A, B, C, D; }; +struct TriVertex +{ + TriVertex() { } + TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w), u(u), v(v) { } + + float x, y, z, w; + float u, v; +}; + class PolyDrawArgs { public: diff --git a/src/polyrenderer/drawers/poly_drawer32.h b/src/polyrenderer/drawers/poly_drawer32.h index 571d6a8ad..2c85e257d 100644 --- a/src/polyrenderer/drawers/poly_drawer32.h +++ b/src/polyrenderer/drawers/poly_drawer32.h @@ -323,7 +323,7 @@ private: int fuzzpos = (ScreenTriangle::FuzzStart + destX * 123 + destY) % FUZZTABLE; // Calculate gradients - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; ScreenTriangleStepVariables gradientX = args->gradientX; ScreenTriangleStepVariables gradientY = args->gradientY; ScreenTriangleStepVariables blockPosY; diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index 67bac9aad..a88b92bd6 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -334,7 +334,7 @@ private: int fuzzpos = (ScreenTriangle::FuzzStart + destX * 123 + destY) % FUZZTABLE; // Calculate gradients - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; ScreenTriangleStepVariables gradientX = args->gradientX; ScreenTriangleStepVariables gradientY = args->gradientY; ScreenTriangleStepVariables blockPosY; diff --git a/src/polyrenderer/drawers/poly_drawer8.h b/src/polyrenderer/drawers/poly_drawer8.h index c54513b9c..f78d2a31c 100644 --- a/src/polyrenderer/drawers/poly_drawer8.h +++ b/src/polyrenderer/drawers/poly_drawer8.h @@ -231,7 +231,7 @@ public: int fuzzpos = (ScreenTriangle::FuzzStart + destX * 123 + destY) % FUZZTABLE; // Calculate gradients - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; ScreenTriangleStepVariables gradientX = args->gradientX; ScreenTriangleStepVariables gradientY = args->gradientY; ScreenTriangleStepVariables blockPosY; diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index 408b16c12..2448e2544 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -146,8 +146,15 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const PolyDrawArgs &drawargs, c const TriMatrix &objectToClip = *drawargs.ObjectToClip(); // Apply transform to get clip coordinates: + FVector4 position = objectToClip * FVector4(v.x, v.y, v.z, v.w); + ShadedTriVertex sv; - sv.position = objectToClip * v; + sv.x = position.X; + sv.y = position.Y; + sv.z = position.Z; + sv.w = position.W; + sv.u = v.u; + sv.v = v.v; // Calculate gl_ClipDistance[i] for (int i = 0; i < 3; i++) @@ -162,12 +169,12 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const PolyDrawArgs &drawargs, c bool PolyTriangleDrawer::is_degenerate(const ShadedTriVertex *vert) { // A degenerate triangle has a zero cross product for two of its sides. - float ax = vert[1].position.x - vert[0].position.x; - float ay = vert[1].position.y - vert[0].position.y; - float az = vert[1].position.w - vert[0].position.w; - float bx = vert[2].position.x - vert[0].position.x; - float by = vert[2].position.y - vert[0].position.y; - float bz = vert[2].position.w - vert[0].position.w; + float ax = vert[1].x - vert[0].x; + float ay = vert[1].y - vert[0].y; + float az = vert[1].w - vert[0].w; + float bx = vert[2].x - vert[0].x; + float by = vert[2].y - vert[0].y; + float bz = vert[2].w - vert[0].w; float crossx = ay * bz - az * by; float crossy = az * bx - ax * bz; float crossz = ax * by - ay * bx; @@ -182,7 +189,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool return; // Cull, clip and generate additional vertices as needed - TriVertex clippedvert[max_additional_vertices]; + ShadedTriVertex clippedvert[max_additional_vertices]; int numclipvert = clipedge(vert, clippedvert); #ifdef NO_SSE @@ -273,7 +280,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool } } -int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert) +int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, ShadedTriVertex *clippedvert) { // Clip and cull so that the following is true for all vertices: // -v.w <= v.x <= v.w @@ -288,16 +295,16 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe float *clipd = clipdistance; for (int i = 0; i < 3; i++) { - const auto &v = verts[i].position; + const auto &v = verts[i]; clipd[0] = v.x + v.w; clipd[1] = v.w - v.x; clipd[2] = v.y + v.w; clipd[3] = v.w - v.y; clipd[4] = v.z + v.w; clipd[5] = v.w - v.z; - clipd[6] = verts[i].clipDistance[0]; - clipd[7] = verts[i].clipDistance[1]; - clipd[8] = verts[i].clipDistance[2]; + clipd[6] = v.clipDistance[0]; + clipd[7] = v.clipDistance[1]; + clipd[8] = v.clipDistance[2]; for (int j = 0; j < 9; j++) needsclipping = needsclipping || clipd[i]; clipd += numclipdistances; @@ -308,14 +315,14 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe { for (int i = 0; i < 3; i++) { - memcpy(clippedvert + i, &verts[i].position, sizeof(TriVertex)); + memcpy(clippedvert + i, &verts[i], sizeof(ShadedTriVertex)); } return 3; } #else - __m128 mx = _mm_loadu_ps(&verts[0].position.x); - __m128 my = _mm_loadu_ps(&verts[1].position.x); - __m128 mz = _mm_loadu_ps(&verts[2].position.x); + __m128 mx = _mm_loadu_ps(&verts[0].x); + __m128 my = _mm_loadu_ps(&verts[1].x); + __m128 mz = _mm_loadu_ps(&verts[2].x); __m128 mw = _mm_setzero_ps(); _MM_TRANSPOSE4_PS(mx, my, mz, mw); __m128 clipd0 = _mm_add_ps(mx, mw); @@ -340,7 +347,7 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe { for (int i = 0; i < 3; i++) { - memcpy(clippedvert + i, &verts[i].position, sizeof(TriVertex)); + memcpy(clippedvert + i, &verts[i], sizeof(ShadedTriVertex)); } return 3; } @@ -429,16 +436,16 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe for (int i = 0; i < inputverts; i++) { auto &v = clippedvert[i]; - memset(&v, 0, sizeof(TriVertex)); + memset(&v, 0, sizeof(ShadedTriVertex)); for (int w = 0; w < 3; w++) { float weight = input[i * 3 + w]; - v.x += verts[w].position.x * weight; - v.y += verts[w].position.y * weight; - v.z += verts[w].position.z * weight; - v.w += verts[w].position.w * weight; - v.u += verts[w].position.u * weight; - v.v += verts[w].position.v * weight; + v.x += verts[w].x * weight; + v.y += verts[w].y * weight; + v.z += verts[w].z * weight; + v.w += verts[w].w * weight; + v.u += verts[w].u * weight; + v.v += verts[w].v * weight; } } return inputverts; diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 04d26c7ea..4992f6972 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -29,12 +29,6 @@ #include "polyrenderer/drawers/poly_buffer.h" #include "polyrenderer/drawers/poly_draw_args.h" -struct ShadedTriVertex -{ - TriVertex position; - float clipDistance[3]; -}; - typedef void(*PolyDrawFuncPtr)(const TriDrawTriangleArgs *, WorkerThreadData *); class PolyTriangleDrawer @@ -50,7 +44,7 @@ private: static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread); static bool is_degenerate(const ShadedTriVertex *vertices); - static int clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert); + static int clipedge(const ShadedTriVertex *verts, ShadedTriVertex *clippedvert); static int viewport_x, viewport_y, viewport_width, viewport_height, dest_pitch, dest_width, dest_height; static bool dest_bgra; diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index e7646c838..c0e4104fc 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -140,9 +140,9 @@ private: TriangleBlock::TriangleBlock(const TriDrawTriangleArgs *args, WorkerThreadData *thread) : args(args), thread(thread) { - const TriVertex &v1 = *args->v1; - const TriVertex &v2 = *args->v2; - const TriVertex &v3 = *args->v3; + const ShadedTriVertex &v1 = *args->v1; + const ShadedTriVertex &v2 = *args->v2; + const ShadedTriVertex &v3 = *args->v3; clipright = args->clipright; clipbottom = args->clipbottom; @@ -368,7 +368,7 @@ void TriangleBlock::DepthTest(const TriDrawTriangleArgs *args) int block = (X >> 3) + (Y >> 3) * zbufferPitch; float *depth = zbuffer + block * 64; - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; float stepXW = args->gradientX.W; float stepYW = args->gradientY.W; @@ -416,7 +416,7 @@ void TriangleBlock::DepthTest(const TriDrawTriangleArgs *args) int block = (X >> 3) + (Y >> 3) * zbufferPitch; float *depth = zbuffer + block * 64; - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; float stepXW = args->gradientX.W; float stepYW = args->gradientY.W; @@ -962,7 +962,7 @@ void TriangleBlock::DepthWrite(const TriDrawTriangleArgs *args) int block = (X >> 3) + (Y >> 3) * zbufferPitch; float *depth = zbuffer + block * 64; - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; float stepXW = args->gradientX.W; float stepYW = args->gradientY.W; @@ -1023,7 +1023,7 @@ void TriangleBlock::DepthWrite(const TriDrawTriangleArgs *args) int block = (X >> 3) + (Y >> 3) * zbufferPitch; float *depth = zbuffer + block * 64; - const TriVertex &v1 = *args->v1; + const ShadedTriVertex &v1 = *args->v1; float stepXW = args->gradientX.W; float stepYW = args->gradientY.W; @@ -1081,7 +1081,7 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, WorkerThreadData *thr #else -static void SortVertices(const TriDrawTriangleArgs *args, TriVertex **sortedVertices) +static void SortVertices(const TriDrawTriangleArgs *args, ShadedTriVertex **sortedVertices) { sortedVertices[0] = args->v1; sortedVertices[1] = args->v2; @@ -1098,7 +1098,7 @@ static void SortVertices(const TriDrawTriangleArgs *args, TriVertex **sortedVert void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread) { // Sort vertices by Y position - TriVertex *sortedVertices[3]; + ShadedTriVertex *sortedVertices[3]; SortVertices(args, sortedVertices); int clipright = args->clipright; diff --git a/src/polyrenderer/drawers/screen_triangle.h b/src/polyrenderer/drawers/screen_triangle.h index 6dfccbc06..d51c8b63e 100644 --- a/src/polyrenderer/drawers/screen_triangle.h +++ b/src/polyrenderer/drawers/screen_triangle.h @@ -41,13 +41,11 @@ struct WorkerThreadData } }; -struct TriVertex +struct ShadedTriVertex { - TriVertex() { } - TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w), u(u), v(v) { } - float x, y, z, w; float u, v; + float clipDistance[3]; }; struct ScreenTriangleStepVariables @@ -59,9 +57,9 @@ struct TriDrawTriangleArgs { uint8_t *dest; int32_t pitch; - TriVertex *v1; - TriVertex *v2; - TriVertex *v3; + ShadedTriVertex *v1; + ShadedTriVertex *v2; + ShadedTriVertex *v3; int32_t clipright; int32_t clipbottom; uint8_t *stencilValues; @@ -80,23 +78,29 @@ struct TriDrawTriangleArgs if ((bottomX >= -FLT_EPSILON && bottomX <= FLT_EPSILON) || (bottomY >= -FLT_EPSILON && bottomY <= FLT_EPSILON)) return false; - gradientX.W = FindGradientX(bottomX, v1->w, v2->w, v3->w); - gradientY.W = FindGradientY(bottomY, v1->w, v2->w, v3->w); - gradientX.U = FindGradientX(bottomX, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); - gradientY.U = FindGradientY(bottomY, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w); - gradientX.V = FindGradientX(bottomX, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); - gradientY.V = FindGradientY(bottomY, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w); + gradientX.W = FindGradientX(bottomX, 1.0f, 1.0f, 1.0f); + gradientY.W = FindGradientY(bottomY, 1.0f, 1.0f, 1.0f); + gradientX.U = FindGradientX(bottomX, v1->u, v2->u, v3->u); + gradientY.U = FindGradientY(bottomY, v1->u, v2->u, v3->u); + gradientX.V = FindGradientX(bottomX, v1->v, v2->v, v3->v); + gradientY.V = FindGradientY(bottomY, v1->v, v2->v, v3->v); return true; } private: float FindGradientX(float bottomX, float c0, float c1, float c2) { + c0 *= v1->w; + c1 *= v2->w; + c2 *= v3->w; return ((c1 - c2) * (v1->y - v3->y) - (c0 - c2) * (v2->y - v3->y)) / bottomX; } float FindGradientY(float bottomY, float c0, float c1, float c2) { + c0 *= v1->w; + c1 *= v2->w; + c2 *= v3->w; return ((c1 - c2) * (v1->x - v3->x) - (c0 - c2) * (v2->x - v3->x)) / bottomY; } }; diff --git a/src/polyrenderer/math/tri_matrix.cpp b/src/polyrenderer/math/tri_matrix.cpp index 42343f601..df0e7d4e0 100644 --- a/src/polyrenderer/math/tri_matrix.cpp +++ b/src/polyrenderer/math/tri_matrix.cpp @@ -173,33 +173,27 @@ TriMatrix TriMatrix::operator*(const TriMatrix &mult) const return result; } -TriVertex TriMatrix::operator*(TriVertex v) const +FVector4 TriMatrix::operator*(const FVector4 &v) const { #ifdef NO_SSE - float vx = matrix[0 * 4 + 0] * v.x + matrix[1 * 4 + 0] * v.y + matrix[2 * 4 + 0] * v.z + matrix[3 * 4 + 0] * v.w; - float vy = matrix[0 * 4 + 1] * v.x + matrix[1 * 4 + 1] * v.y + matrix[2 * 4 + 1] * v.z + matrix[3 * 4 + 1] * v.w; - float vz = matrix[0 * 4 + 2] * v.x + matrix[1 * 4 + 2] * v.y + matrix[2 * 4 + 2] * v.z + matrix[3 * 4 + 2] * v.w; - float vw = matrix[0 * 4 + 3] * v.x + matrix[1 * 4 + 3] * v.y + matrix[2 * 4 + 3] * v.z + matrix[3 * 4 + 3] * v.w; - TriVertex sv; - sv.x = vx; - sv.y = vy; - sv.z = vz; - sv.w = vw; + float vx = matrix[0 * 4 + 0] * v.X + matrix[1 * 4 + 0] * v.Y + matrix[2 * 4 + 0] * v.Z + matrix[3 * 4 + 0] * v.W; + float vy = matrix[0 * 4 + 1] * v.X + matrix[1 * 4 + 1] * v.Y + matrix[2 * 4 + 1] * v.Z + matrix[3 * 4 + 1] * v.W; + float vz = matrix[0 * 4 + 2] * v.X + matrix[1 * 4 + 2] * v.Y + matrix[2 * 4 + 2] * v.Z + matrix[3 * 4 + 2] * v.W; + float vw = matrix[0 * 4 + 3] * v.X + matrix[1 * 4 + 3] * v.Y + matrix[2 * 4 + 3] * v.Z + matrix[3 * 4 + 3] * v.W; + return{ vx, vy, vz, vw }; #else __m128 m0 = _mm_loadu_ps(matrix); __m128 m1 = _mm_loadu_ps(matrix + 4); __m128 m2 = _mm_loadu_ps(matrix + 8); __m128 m3 = _mm_loadu_ps(matrix + 12); - __m128 mv = _mm_loadu_ps(&v.x); + __m128 mv = _mm_loadu_ps(&v.X); m0 = _mm_mul_ps(m0, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(0, 0, 0, 0))); m1 = _mm_mul_ps(m1, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(1, 1, 1, 1))); m2 = _mm_mul_ps(m2, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(2, 2, 2, 2))); m3 = _mm_mul_ps(m3, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(3, 3, 3, 3))); mv = _mm_add_ps(_mm_add_ps(_mm_add_ps(m0, m1), m2), m3); - TriVertex sv; - _mm_storeu_ps(&sv.x, mv); -#endif - sv.u = v.u; - sv.v = v.v; + FVector4 sv; + _mm_storeu_ps(&sv.X, mv); return sv; +#endif } diff --git a/src/polyrenderer/math/tri_matrix.h b/src/polyrenderer/math/tri_matrix.h index aa566a3f8..908ef247d 100644 --- a/src/polyrenderer/math/tri_matrix.h +++ b/src/polyrenderer/math/tri_matrix.h @@ -39,7 +39,7 @@ struct TriMatrix //static TriMatrix worldToView(const FRenderViewpoint &viewpoint); // Software renderer world to view space transform //static TriMatrix viewToClip(double focalTangent, double centerY, double invZtoScale); // Software renderer shearing projection - TriVertex operator*(TriVertex v) const; + FVector4 operator*(const FVector4 &v) const; TriMatrix operator*(const TriMatrix &m) const; float matrix[16];