mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-12 23:54:17 +00:00
Fix sky transition
This commit is contained in:
parent
90f5eee6c6
commit
bb64b178e1
6 changed files with 141 additions and 96 deletions
|
@ -98,20 +98,17 @@ void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *v
|
||||||
if ((UseVertexData & 1) == 0)
|
if ((UseVertexData & 1) == 0)
|
||||||
{
|
{
|
||||||
const auto &c = thread->mainVertexShader.Data.uVertexColor;
|
const auto &c = thread->mainVertexShader.Data.uVertexColor;
|
||||||
thread->mainVertexShader.aColor = MAKEARGB(
|
thread->mainVertexShader.aColor.X = c.X;
|
||||||
static_cast<uint32_t>(c.W * 255.0f + 0.5f),
|
thread->mainVertexShader.aColor.Y = c.Y;
|
||||||
static_cast<uint32_t>(c.X * 255.0f + 0.5f),
|
thread->mainVertexShader.aColor.Z = c.Z;
|
||||||
static_cast<uint32_t>(c.Y * 255.0f + 0.5f),
|
thread->mainVertexShader.aColor.W = c.W;
|
||||||
static_cast<uint32_t>(c.Z * 255.0f + 0.5f)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t r = attrColor[0];
|
thread->mainVertexShader.aColor.X = attrColor[0] * (1.0f / 255.0f);
|
||||||
uint32_t g = attrColor[1];
|
thread->mainVertexShader.aColor.Y = attrColor[1] * (1.0f / 255.0f);
|
||||||
uint32_t b = attrColor[2];
|
thread->mainVertexShader.aColor.Z = attrColor[2] * (1.0f / 255.0f);
|
||||||
uint32_t a = attrColor[3];
|
thread->mainVertexShader.aColor.W = attrColor[3] * (1.0f / 255.0f);
|
||||||
thread->mainVertexShader.aColor = MAKEARGB(a, r, g, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((UseVertexData & 2) == 0)
|
if ((UseVertexData & 2) == 0)
|
||||||
|
|
|
@ -414,8 +414,6 @@ void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode dra
|
||||||
|
|
||||||
elements += index;
|
elements += index;
|
||||||
|
|
||||||
TriDrawTriangleArgs args;
|
|
||||||
|
|
||||||
ShadedTriVertex vertbuffer[3];
|
ShadedTriVertex vertbuffer[3];
|
||||||
ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] };
|
ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] };
|
||||||
if (drawmode == PolyDrawMode::Triangles)
|
if (drawmode == PolyDrawMode::Triangles)
|
||||||
|
@ -424,7 +422,7 @@ void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode dra
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
*vert[j] = ShadeVertex(*(elements++));
|
*vert[j] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawmode == PolyDrawMode::TriangleFan)
|
else if (drawmode == PolyDrawMode::TriangleFan)
|
||||||
|
@ -434,7 +432,7 @@ void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode dra
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
*vert[2] = ShadeVertex(*(elements++));
|
*vert[2] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw);
|
||||||
std::swap(vert[1], vert[2]);
|
std::swap(vert[1], vert[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,7 +444,7 @@ void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode dra
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
*vert[2] = ShadeVertex(*(elements++));
|
*vert[2] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, toggleccw, &args);
|
DrawShadedTriangle(vert, toggleccw);
|
||||||
ShadedTriVertex *vtmp = vert[0];
|
ShadedTriVertex *vtmp = vert[0];
|
||||||
vert[0] = vert[1];
|
vert[0] = vert[1];
|
||||||
vert[1] = vert[2];
|
vert[1] = vert[2];
|
||||||
|
@ -478,8 +476,6 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode)
|
||||||
if (vcount < 3)
|
if (vcount < 3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TriDrawTriangleArgs args;
|
|
||||||
|
|
||||||
int vinput = index;
|
int vinput = index;
|
||||||
|
|
||||||
ShadedTriVertex vertbuffer[3];
|
ShadedTriVertex vertbuffer[3];
|
||||||
|
@ -490,7 +486,7 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
*vert[j] = ShadeVertex(vinput++);
|
*vert[j] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawmode == PolyDrawMode::TriangleFan)
|
else if (drawmode == PolyDrawMode::TriangleFan)
|
||||||
|
@ -500,7 +496,7 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode)
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
*vert[2] = ShadeVertex(vinput++);
|
*vert[2] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw);
|
||||||
std::swap(vert[1], vert[2]);
|
std::swap(vert[1], vert[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,7 +508,7 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode)
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
*vert[2] = ShadeVertex(vinput++);
|
*vert[2] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, toggleccw, &args);
|
DrawShadedTriangle(vert, toggleccw);
|
||||||
ShadedTriVertex *vtmp = vert[0];
|
ShadedTriVertex *vtmp = vert[0];
|
||||||
vert[0] = vert[1];
|
vert[0] = vert[1];
|
||||||
vert[1] = vert[2];
|
vert[1] = vert[2];
|
||||||
|
@ -623,11 +619,6 @@ void PolyTriangleThreadData::DrawShadedLine(const ShadedTriVertex *const* vert)
|
||||||
v.y += vert[w]->gl_Position.Y * weight;
|
v.y += vert[w]->gl_Position.Y * weight;
|
||||||
v.z += vert[w]->gl_Position.Z * weight;
|
v.z += vert[w]->gl_Position.Z * weight;
|
||||||
v.w += vert[w]->gl_Position.W * weight;
|
v.w += vert[w]->gl_Position.W * weight;
|
||||||
v.u += vert[w]->vTexCoord.X * weight;
|
|
||||||
v.v += vert[w]->vTexCoord.Y * weight;
|
|
||||||
v.worldX += vert[w]->pixelpos.X * weight;
|
|
||||||
v.worldY += vert[w]->pixelpos.Y * weight;
|
|
||||||
v.worldZ += vert[w]->pixelpos.Z * weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate normalized device coordinates:
|
// Calculate normalized device coordinates:
|
||||||
|
@ -641,7 +632,11 @@ void PolyTriangleThreadData::DrawShadedLine(const ShadedTriVertex *const* vert)
|
||||||
v.y = viewport_y + viewport_height * (1.0f - v.y) * 0.5f;
|
v.y = viewport_y + viewport_height * (1.0f - v.y) * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t color = vert[0]->vColor;
|
uint32_t vColorA = (int)(vert[0]->vColor.W * 255.0f + 0.5f);
|
||||||
|
uint32_t vColorR = (int)(vert[0]->vColor.X * 255.0f + 0.5f);
|
||||||
|
uint32_t vColorG = (int)(vert[0]->vColor.Y * 255.0f + 0.5f);
|
||||||
|
uint32_t vColorB = (int)(vert[0]->vColor.Z * 255.0f + 0.5f);
|
||||||
|
uint32_t color = MAKEARGB(vColorA, vColorR, vColorG, vColorB);
|
||||||
|
|
||||||
// Slow and naive implementation. Hopefully fast enough..
|
// Slow and naive implementation. Hopefully fast enough..
|
||||||
|
|
||||||
|
@ -679,7 +674,7 @@ void PolyTriangleThreadData::DrawShadedLine(const ShadedTriVertex *const* vert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* vert, bool ccw, TriDrawTriangleArgs *args)
|
void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* vert, bool ccw)
|
||||||
{
|
{
|
||||||
// Reject triangle if degenerate
|
// Reject triangle if degenerate
|
||||||
if (IsDegenerate(vert))
|
if (IsDegenerate(vert))
|
||||||
|
@ -706,6 +701,11 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* ve
|
||||||
v.worldX += vert[w]->pixelpos.X * weight;
|
v.worldX += vert[w]->pixelpos.X * weight;
|
||||||
v.worldY += vert[w]->pixelpos.Y * weight;
|
v.worldY += vert[w]->pixelpos.Y * weight;
|
||||||
v.worldZ += vert[w]->pixelpos.Z * weight;
|
v.worldZ += vert[w]->pixelpos.Z * weight;
|
||||||
|
v.a += vert[w]->vColor.W * weight;
|
||||||
|
v.r += vert[w]->vColor.X * weight;
|
||||||
|
v.g += vert[w]->vColor.Y * weight;
|
||||||
|
v.b += vert[w]->vColor.Z * weight;
|
||||||
|
v.gradientdistZ += vert[w]->gradientdist.Z * weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,27 +759,14 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* ve
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
TriDrawTriangleArgs args;
|
||||||
// Keep varyings in -128 to 128 range if possible
|
|
||||||
// But don't do this for the skycap mode since the V texture coordinate is used for blending
|
|
||||||
if (numclipvert > 0 && drawargs.BlendMode() != TriBlendMode::Skycap)
|
|
||||||
{
|
|
||||||
float newOriginU = floorf(clippedvert[0].u * 0.1f) * 10.0f;
|
|
||||||
float newOriginV = floorf(clippedvert[0].v * 0.1f) * 10.0f;
|
|
||||||
for (int i = 0; i < numclipvert; i++)
|
|
||||||
{
|
|
||||||
clippedvert[i].u -= newOriginU;
|
|
||||||
clippedvert[i].v -= newOriginV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (twosided && numclipvert > 2)
|
if (twosided && numclipvert > 2)
|
||||||
{
|
{
|
||||||
args->v1 = &clippedvert[0];
|
args.v1 = &clippedvert[0];
|
||||||
args->v2 = &clippedvert[1];
|
args.v2 = &clippedvert[1];
|
||||||
args->v3 = &clippedvert[2];
|
args.v3 = &clippedvert[2];
|
||||||
ccw = !IsFrontfacing(args);
|
ccw = !IsFrontfacing(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw screen triangles
|
// Draw screen triangles
|
||||||
|
@ -787,12 +774,12 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* ve
|
||||||
{
|
{
|
||||||
for (int i = numclipvert - 1; i > 1; i--)
|
for (int i = numclipvert - 1; i > 1; i--)
|
||||||
{
|
{
|
||||||
args->v1 = &clippedvert[numclipvert - 1];
|
args.v1 = &clippedvert[numclipvert - 1];
|
||||||
args->v2 = &clippedvert[i - 1];
|
args.v2 = &clippedvert[i - 1];
|
||||||
args->v3 = &clippedvert[i - 2];
|
args.v3 = &clippedvert[i - 2];
|
||||||
if (IsFrontfacing(args) == ccw && args->CalculateGradients())
|
if (IsFrontfacing(&args) == ccw && args.CalculateGradients())
|
||||||
{
|
{
|
||||||
ScreenTriangle::Draw(args, this);
|
ScreenTriangle::Draw(&args, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,12 +787,12 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* ve
|
||||||
{
|
{
|
||||||
for (int i = 2; i < numclipvert; i++)
|
for (int i = 2; i < numclipvert; i++)
|
||||||
{
|
{
|
||||||
args->v1 = &clippedvert[0];
|
args.v1 = &clippedvert[0];
|
||||||
args->v2 = &clippedvert[i - 1];
|
args.v2 = &clippedvert[i - 1];
|
||||||
args->v3 = &clippedvert[i];
|
args.v3 = &clippedvert[i];
|
||||||
if (IsFrontfacing(args) != ccw && args->CalculateGradients())
|
if (IsFrontfacing(&args) != ccw && args.CalculateGradients())
|
||||||
{
|
{
|
||||||
ScreenTriangle::Draw(args, this);
|
ScreenTriangle::Draw(&args, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,11 +196,18 @@ public:
|
||||||
struct Scanline
|
struct Scanline
|
||||||
{
|
{
|
||||||
float W[MAXWIDTH];
|
float W[MAXWIDTH];
|
||||||
|
float WeightV1[MAXWIDTH];
|
||||||
|
float WeightV2[MAXWIDTH];
|
||||||
uint16_t U[MAXWIDTH];
|
uint16_t U[MAXWIDTH];
|
||||||
uint16_t V[MAXWIDTH];
|
uint16_t V[MAXWIDTH];
|
||||||
float WorldX[MAXWIDTH];
|
float WorldX[MAXWIDTH];
|
||||||
float WorldY[MAXWIDTH];
|
float WorldY[MAXWIDTH];
|
||||||
float WorldZ[MAXWIDTH];
|
float WorldZ[MAXWIDTH];
|
||||||
|
uint8_t vColorA[MAXWIDTH];
|
||||||
|
uint8_t vColorR[MAXWIDTH];
|
||||||
|
uint8_t vColorG[MAXWIDTH];
|
||||||
|
uint8_t vColorB[MAXWIDTH];
|
||||||
|
float GradientdistZ[MAXWIDTH];
|
||||||
uint32_t FragColor[MAXWIDTH];
|
uint32_t FragColor[MAXWIDTH];
|
||||||
uint16_t lightarray[MAXWIDTH];
|
uint16_t lightarray[MAXWIDTH];
|
||||||
uint32_t dynlights[MAXWIDTH];
|
uint32_t dynlights[MAXWIDTH];
|
||||||
|
@ -263,7 +270,7 @@ private:
|
||||||
ShadedTriVertex ShadeVertex(int index);
|
ShadedTriVertex ShadeVertex(int index);
|
||||||
void DrawShadedPoint(const ShadedTriVertex *const* vertex);
|
void DrawShadedPoint(const ShadedTriVertex *const* vertex);
|
||||||
void DrawShadedLine(const ShadedTriVertex *const* vertices);
|
void DrawShadedLine(const ShadedTriVertex *const* vertices);
|
||||||
void DrawShadedTriangle(const ShadedTriVertex *const* vertices, bool ccw, TriDrawTriangleArgs *args);
|
void DrawShadedTriangle(const ShadedTriVertex *const* vertices, bool ccw);
|
||||||
static bool IsDegenerate(const ShadedTriVertex *const* vertices);
|
static bool IsDegenerate(const ShadedTriVertex *const* vertices);
|
||||||
static bool IsFrontfacing(TriDrawTriangleArgs *args);
|
static bool IsFrontfacing(TriDrawTriangleArgs *args);
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,11 @@ public:
|
||||||
Vec4f gl_Position;
|
Vec4f gl_Position;
|
||||||
float gl_ClipDistance[5];
|
float gl_ClipDistance[5];
|
||||||
Vec4f vTexCoord;
|
Vec4f vTexCoord;
|
||||||
uint32_t vColor;
|
Vec4f vColor;
|
||||||
Vec4f pixelpos;
|
Vec4f pixelpos;
|
||||||
|
//Vec3f glowdist;
|
||||||
|
Vec3f gradientdist;
|
||||||
|
//Vec4f vEyeNormal;
|
||||||
Vec4f vWorldNormal;
|
Vec4f vWorldNormal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,16 +29,11 @@ public:
|
||||||
// Input
|
// Input
|
||||||
Vec4f aPosition;
|
Vec4f aPosition;
|
||||||
Vec2f aTexCoord;
|
Vec2f aTexCoord;
|
||||||
uint32_t aColor;
|
Vec4f aColor;
|
||||||
Vec4f aVertex2;
|
Vec4f aVertex2;
|
||||||
Vec4f aNormal;
|
Vec4f aNormal;
|
||||||
Vec4f aNormal2;
|
Vec4f aNormal2;
|
||||||
|
|
||||||
// Output
|
|
||||||
Vec3f glowdist;
|
|
||||||
Vec3f gradientdist;
|
|
||||||
Vec4f vEyeNormal;
|
|
||||||
|
|
||||||
// Defines
|
// Defines
|
||||||
bool SIMPLE = false;
|
bool SIMPLE = false;
|
||||||
bool SPHEREMAP = false;
|
bool SPHEREMAP = false;
|
||||||
|
@ -70,14 +68,14 @@ public:
|
||||||
pixelpos.Z = worldcoord.Z;
|
pixelpos.Z = worldcoord.Z;
|
||||||
pixelpos.W = -eyeCoordPos.Z / eyeCoordPos.W;
|
pixelpos.W = -eyeCoordPos.Z / eyeCoordPos.W;
|
||||||
|
|
||||||
if (Data.uGlowTopColor.W > 0 || Data.uGlowBottomColor.W > 0)
|
/*if (Data.uGlowTopColor.W > 0 || Data.uGlowBottomColor.W > 0)
|
||||||
{
|
{
|
||||||
float topatpoint = (Data.uGlowTopPlane.W + Data.uGlowTopPlane.X * worldcoord.X + Data.uGlowTopPlane.Y * worldcoord.Z) * Data.uGlowTopPlane.Z;
|
float topatpoint = (Data.uGlowTopPlane.W + Data.uGlowTopPlane.X * worldcoord.X + Data.uGlowTopPlane.Y * worldcoord.Z) * Data.uGlowTopPlane.Z;
|
||||||
float bottomatpoint = (Data.uGlowBottomPlane.W + Data.uGlowBottomPlane.X * worldcoord.X + Data.uGlowBottomPlane.Y * worldcoord.Z) * Data.uGlowBottomPlane.Z;
|
float bottomatpoint = (Data.uGlowBottomPlane.W + Data.uGlowBottomPlane.X * worldcoord.X + Data.uGlowBottomPlane.Y * worldcoord.Z) * Data.uGlowBottomPlane.Z;
|
||||||
glowdist.X = topatpoint - worldcoord.Y;
|
glowdist.X = topatpoint - worldcoord.Y;
|
||||||
glowdist.Y = worldcoord.Y - bottomatpoint;
|
glowdist.Y = worldcoord.Y - bottomatpoint;
|
||||||
glowdist.Z = clamp(glowdist.X / (topatpoint - bottomatpoint), 0.0f, 1.0f);
|
glowdist.Z = clamp(glowdist.X / (topatpoint - bottomatpoint), 0.0f, 1.0f);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (Data.uObjectColor2.a != 0)
|
if (Data.uObjectColor2.a != 0)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +93,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
vWorldNormal = mul(NormalModelMatrix, Vec4f(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
|
vWorldNormal = mul(NormalModelMatrix, Vec4f(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
|
||||||
vEyeNormal = mul(Viewpoint->mNormalViewMatrix, vWorldNormal);
|
//vEyeNormal = mul(Viewpoint->mNormalViewMatrix, vWorldNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SPHEREMAP)
|
if (!SPHEREMAP)
|
||||||
|
|
|
@ -371,6 +371,42 @@ static void WriteVaryingWrap(float pos, float step, int x0, int x1, const float*
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_SSE
|
||||||
|
static void WriteVaryingColor(float pos, float step, int x0, int x1, const float* w, uint8_t* varying)
|
||||||
|
{
|
||||||
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
varying[x] = (int)(pos * w[x] * 255.0f);
|
||||||
|
pos += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void WriteVaryingColor(float pos, float step, int x0, int x1, const float* w, uint8_t* varying)
|
||||||
|
{
|
||||||
|
int ssecount = ((x1 - x0) & ~3);
|
||||||
|
int sseend = x0 + ssecount;
|
||||||
|
|
||||||
|
__m128 mstep = _mm_set1_ps(step * 4.0f);
|
||||||
|
__m128 mpos = _mm_setr_ps(pos, pos + step, pos + step + step, pos + step + step + step);
|
||||||
|
|
||||||
|
for (int x = x0; x < sseend; x += 4)
|
||||||
|
{
|
||||||
|
__m128i value = _mm_cvttps_epi32(_mm_mul_ps(_mm_mul_ps(mpos, _mm_loadu_ps(w + x)), _mm_set1_ps(255.0f)));
|
||||||
|
value = _mm_packs_epi32(value, value);
|
||||||
|
value = _mm_packus_epi16(value, value);
|
||||||
|
*(uint32_t*)(varying + x) = _mm_cvtsi128_si32(value);
|
||||||
|
mpos = _mm_add_ps(mpos, mstep);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += ssecount * step;
|
||||||
|
for (int x = sseend; x < x1; x++)
|
||||||
|
{
|
||||||
|
varying[x] = (int)(pos * w[x] * 255.0f);
|
||||||
|
pos += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
|
static void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
float startX = x0 + (0.5f - args->v1->x);
|
float startX = x0 + (0.5f - args->v1->x);
|
||||||
|
@ -381,6 +417,11 @@ static void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args
|
||||||
WriteVarying(args->v1->worldX * args->v1->w + args->gradientX.WorldX * startX + args->gradientY.WorldX * startY, args->gradientX.WorldX, x0, x1, thread->scanline.W, thread->scanline.WorldX);
|
WriteVarying(args->v1->worldX * args->v1->w + args->gradientX.WorldX * startX + args->gradientY.WorldX * startY, args->gradientX.WorldX, x0, x1, thread->scanline.W, thread->scanline.WorldX);
|
||||||
WriteVarying(args->v1->worldY * args->v1->w + args->gradientX.WorldY * startX + args->gradientY.WorldY * startY, args->gradientX.WorldY, x0, x1, thread->scanline.W, thread->scanline.WorldY);
|
WriteVarying(args->v1->worldY * args->v1->w + args->gradientX.WorldY * startX + args->gradientY.WorldY * startY, args->gradientX.WorldY, x0, x1, thread->scanline.W, thread->scanline.WorldY);
|
||||||
WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ);
|
WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ);
|
||||||
|
WriteVarying(args->v1->gradientdistZ * args->v1->w + args->gradientX.GradientdistZ * startX + args->gradientY.GradientdistZ * startY, args->gradientX.GradientdistZ, x0, x1, thread->scanline.W, thread->scanline.GradientdistZ);
|
||||||
|
WriteVaryingColor(args->v1->a * args->v1->w + args->gradientX.A * startX + args->gradientY.A * startY, args->gradientX.A, x0, x1, thread->scanline.W, thread->scanline.vColorA);
|
||||||
|
WriteVaryingColor(args->v1->r * args->v1->w + args->gradientX.R * startX + args->gradientY.R * startY, args->gradientX.R, x0, x1, thread->scanline.W, thread->scanline.vColorR);
|
||||||
|
WriteVaryingColor(args->v1->g * args->v1->w + args->gradientX.G * startX + args->gradientY.G * startY, args->gradientX.G, x0, x1, thread->scanline.W, thread->scanline.vColorG);
|
||||||
|
WriteVaryingColor(args->v1->b * args->v1->w + args->gradientX.B * startX + args->gradientY.B * startY, args->gradientX.B, x0, x1, thread->scanline.W, thread->scanline.vColorB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int shiftTable[] = {
|
static const int shiftTable[] = {
|
||||||
|
@ -621,17 +662,17 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
const void* tex2Pixels = thread->textures[1].pixels;
|
const void* tex2Pixels = thread->textures[1].pixels;
|
||||||
bool tex2Bgra = thread->textures[1].bgra;
|
bool tex2Bgra = thread->textures[1].bgra;
|
||||||
|
|
||||||
uint32_t frag = thread->mainVertexShader.vColor;
|
|
||||||
uint32_t frag_r = RPART(frag);
|
|
||||||
uint32_t frag_g = GPART(frag);
|
|
||||||
uint32_t frag_b = BPART(frag);
|
|
||||||
uint32_t frag_a = APART(frag);
|
|
||||||
frag_r += frag_r >> 7; // 255 -> 256
|
|
||||||
frag_g += frag_g >> 7; // 255 -> 256
|
|
||||||
frag_b += frag_b >> 7; // 255 -> 256
|
|
||||||
frag_a += frag_a >> 7; // 255 -> 256
|
|
||||||
for (int x = x0; x < x1; x++)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
|
uint32_t frag_r = thread->scanline.vColorR[x];
|
||||||
|
uint32_t frag_g = thread->scanline.vColorG[x];
|
||||||
|
uint32_t frag_b = thread->scanline.vColorB[x];
|
||||||
|
uint32_t frag_a = thread->scanline.vColorA[x];
|
||||||
|
frag_r += frag_r >> 7; // 255 -> 256
|
||||||
|
frag_g += frag_g >> 7; // 255 -> 256
|
||||||
|
frag_b += frag_b >> 7; // 255 -> 256
|
||||||
|
frag_a += frag_a >> 7; // 255 -> 256
|
||||||
|
|
||||||
uint32_t t1 = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra);
|
uint32_t t1 = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra);
|
||||||
uint32_t t2 = SampleTexture(u[x], 0xffff - v[x], tex2Pixels, tex2Width, tex2Height, tex2Bgra);
|
uint32_t t2 = SampleTexture(u[x], 0xffff - v[x], tex2Pixels, tex2Width, tex2Height, tex2Bgra);
|
||||||
|
|
||||||
|
@ -797,13 +838,15 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float t = thread->mainVertexShader.gradientdist.Z;
|
float* gradientdistZ = thread->scanline.GradientdistZ;
|
||||||
float inv_t = 1.0f - t;
|
|
||||||
uint32_t r = (int)((streamdata.uObjectColor.r * inv_t + streamdata.uObjectColor2.r * t) * 256.0f);
|
|
||||||
uint32_t g = (int)((streamdata.uObjectColor.g * inv_t + streamdata.uObjectColor2.g * t) * 256.0f);
|
|
||||||
uint32_t b = (int)((streamdata.uObjectColor.b * inv_t + streamdata.uObjectColor2.b * t) * 256.0f);
|
|
||||||
for (int x = x0; x < x1; x++)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
|
float t = gradientdistZ[x];
|
||||||
|
float inv_t = 1.0f - t;
|
||||||
|
uint32_t r = (int)((streamdata.uObjectColor.r * inv_t + streamdata.uObjectColor2.r * t) * 256.0f);
|
||||||
|
uint32_t g = (int)((streamdata.uObjectColor.g * inv_t + streamdata.uObjectColor2.g * t) * 256.0f);
|
||||||
|
uint32_t b = (int)((streamdata.uObjectColor.b * inv_t + streamdata.uObjectColor2.b * t) * 256.0f);
|
||||||
|
|
||||||
uint32_t texel = fragcolor[x];
|
uint32_t texel = fragcolor[x];
|
||||||
fragcolor[x] = MAKEARGB(
|
fragcolor[x] = MAKEARGB(
|
||||||
APART(texel),
|
APART(texel),
|
||||||
|
@ -831,25 +874,24 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread->mainVertexShader.vColor != 0xffffffff)
|
for (int x = x0; x < x1; x++)
|
||||||
{
|
{
|
||||||
uint32_t a = APART(thread->mainVertexShader.vColor);
|
uint32_t r = thread->scanline.vColorR[x];
|
||||||
uint32_t r = RPART(thread->mainVertexShader.vColor);
|
uint32_t g = thread->scanline.vColorG[x];
|
||||||
uint32_t g = GPART(thread->mainVertexShader.vColor);
|
uint32_t b = thread->scanline.vColorB[x];
|
||||||
uint32_t b = BPART(thread->mainVertexShader.vColor);
|
uint32_t a = thread->scanline.vColorA[x];
|
||||||
|
|
||||||
a += a >> 7;
|
a += a >> 7;
|
||||||
r += r >> 7;
|
r += r >> 7;
|
||||||
g += g >> 7;
|
g += g >> 7;
|
||||||
b += b >> 7;
|
b += b >> 7;
|
||||||
for (int x = x0; x < x1; x++)
|
|
||||||
{
|
uint32_t texel = fragcolor[x];
|
||||||
uint32_t texel = fragcolor[x];
|
fragcolor[x] = MAKEARGB(
|
||||||
fragcolor[x] = MAKEARGB(
|
(APART(texel) * a + 127) >> 8,
|
||||||
(APART(texel) * a + 127) >> 8,
|
(RPART(texel) * r + 127) >> 8,
|
||||||
(RPART(texel) * r + 127) >> 8,
|
(GPART(texel) * g + 127) >> 8,
|
||||||
(GPART(texel) * g + 127) >> 8,
|
(BPART(texel) * b + 127) >> 8);
|
||||||
(BPART(texel) * b + 127) >> 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constants->uLightLevel >= 0.0f && thread->numPolyLights > 0)
|
if (constants->uLightLevel >= 0.0f && thread->numPolyLights > 0)
|
||||||
|
|
|
@ -35,12 +35,16 @@ struct ScreenTriVertex
|
||||||
float x, y, z, w;
|
float x, y, z, w;
|
||||||
float u, v;
|
float u, v;
|
||||||
float worldX, worldY, worldZ;
|
float worldX, worldY, worldZ;
|
||||||
|
float a, r, g, b;
|
||||||
|
float gradientdistZ;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScreenTriangleStepVariables
|
struct ScreenTriangleStepVariables
|
||||||
{
|
{
|
||||||
float W, U, V;
|
float W, U, V;
|
||||||
float WorldX, WorldY, WorldZ, Padding; // Padding so it can be loaded directly into a XMM register
|
float WorldX, WorldY, WorldZ;
|
||||||
|
float A, R, G, B;
|
||||||
|
float GradientdistZ;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TriDrawTriangleArgs
|
struct TriDrawTriangleArgs
|
||||||
|
@ -64,6 +68,11 @@ struct TriDrawTriangleArgs
|
||||||
gradientX.WorldX = FindGradientX(bottomX, v1->worldX, v2->worldX, v3->worldX);
|
gradientX.WorldX = FindGradientX(bottomX, v1->worldX, v2->worldX, v3->worldX);
|
||||||
gradientX.WorldY = FindGradientX(bottomX, v1->worldY, v2->worldY, v3->worldY);
|
gradientX.WorldY = FindGradientX(bottomX, v1->worldY, v2->worldY, v3->worldY);
|
||||||
gradientX.WorldZ = FindGradientX(bottomX, v1->worldZ, v2->worldZ, v3->worldZ);
|
gradientX.WorldZ = FindGradientX(bottomX, v1->worldZ, v2->worldZ, v3->worldZ);
|
||||||
|
gradientX.A = FindGradientX(bottomX, v1->a, v2->a, v3->a);
|
||||||
|
gradientX.R = FindGradientX(bottomX, v1->r, v2->r, v3->r);
|
||||||
|
gradientX.G = FindGradientX(bottomX, v1->g, v2->g, v3->g);
|
||||||
|
gradientX.B = FindGradientX(bottomX, v1->b, v2->b, v3->b);
|
||||||
|
gradientX.GradientdistZ = FindGradientX(bottomX, v1->gradientdistZ, v2->gradientdistZ, v3->gradientdistZ);
|
||||||
|
|
||||||
gradientY.W = FindGradientY(bottomY, 1.0f, 1.0f, 1.0f);
|
gradientY.W = FindGradientY(bottomY, 1.0f, 1.0f, 1.0f);
|
||||||
gradientY.U = FindGradientY(bottomY, v1->u, v2->u, v3->u);
|
gradientY.U = FindGradientY(bottomY, v1->u, v2->u, v3->u);
|
||||||
|
@ -71,6 +80,11 @@ struct TriDrawTriangleArgs
|
||||||
gradientY.WorldX = FindGradientY(bottomY, v1->worldX, v2->worldX, v3->worldX);
|
gradientY.WorldX = FindGradientY(bottomY, v1->worldX, v2->worldX, v3->worldX);
|
||||||
gradientY.WorldY = FindGradientY(bottomY, v1->worldY, v2->worldY, v3->worldY);
|
gradientY.WorldY = FindGradientY(bottomY, v1->worldY, v2->worldY, v3->worldY);
|
||||||
gradientY.WorldZ = FindGradientY(bottomY, v1->worldZ, v2->worldZ, v3->worldZ);
|
gradientY.WorldZ = FindGradientY(bottomY, v1->worldZ, v2->worldZ, v3->worldZ);
|
||||||
|
gradientY.A = FindGradientY(bottomY, v1->a, v2->a, v3->a);
|
||||||
|
gradientY.R = FindGradientY(bottomY, v1->r, v2->r, v3->r);
|
||||||
|
gradientY.G = FindGradientY(bottomY, v1->g, v2->g, v3->g);
|
||||||
|
gradientY.B = FindGradientY(bottomY, v1->b, v2->b, v3->b);
|
||||||
|
gradientY.GradientdistZ = FindGradientY(bottomY, v1->gradientdistZ, v2->gradientdistZ, v3->gradientdistZ);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue