mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- Make the relationship between TriMatrix, TriVertex and ShadedTriVertex more clean
This commit is contained in:
parent
b6b78176d2
commit
59ee89b622
10 changed files with 82 additions and 74 deletions
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue