Alpha test must be performed before vcolor is applied

This commit is contained in:
Magnus Norddahl 2019-12-08 02:39:42 +01:00
parent fdb93309fe
commit c97d02ae51
3 changed files with 18 additions and 8 deletions

View file

@ -257,6 +257,8 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu
PushConstants = &constants;
AlphaThreshold = clamp((int)(PushConstants->uAlphaThreshold * 255.0f + 0.5f), 0, 255) << 24;
numPolyLights = 0;
if (constants.uLightIndex >= 0)
{

View file

@ -214,6 +214,7 @@ public:
uint32_t FragColor[MAXWIDTH];
uint16_t lightarray[MAXWIDTH];
uint32_t dynlights[MAXWIDTH];
uint8_t discard[MAXWIDTH];
} scanline;
static PolyTriangleThreadData *Get(DrawerThread *thread);
@ -242,6 +243,7 @@ public:
int SpecialEffect = EFF_NONE;
int EffectState = 0;
bool AlphaTest = false;
uint32_t AlphaThreshold = 0x7f000000;
const PolyPushConstants* PushConstants = nullptr;
const void *vertices = nullptr;

View file

@ -451,6 +451,7 @@ static void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
uint32_t* dest = (uint32_t*)thread->dest;
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
uint32_t* fragcolor = thread->scanline.FragColor;
uint8_t* discard = thread->scanline.discard;
for (int x = x0; x < x1; x++)
{
@ -458,7 +459,7 @@ static void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
if (OptT::Flags & SWBLEND_AlphaTest)
{
if (fragcolor[x] <= 0x7f000000)
if (discard[x])
continue;
}
@ -540,9 +541,10 @@ static void WriteColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
}
else
{
uint8_t* discard = thread->scanline.discard;
for (int x = x0; x < x1; x++)
{
if (fragcolor[x] > 0x7f000000)
if (!discard[x])
line[x] = fragcolor[x];
}
}
@ -587,10 +589,11 @@ static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread)
}
else
{
uint8_t* discard = thread->scanline.discard;
uint32_t* fragcolor = thread->scanline.FragColor;
for (int x = x0; x < x1; x++)
{
if (fragcolor[x] > 0x7f000000)
if (!discard[x])
line[x] = w[x];
}
}
@ -610,10 +613,11 @@ static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread)
}
else
{
uint8_t* discard = thread->scanline.discard;
uint32_t* fragcolor = thread->scanline.FragColor;
for (int x = x0; x < x1; x++)
{
if (fragcolor[x] > 0x7f000000)
if (!discard[x])
line[x] = value;
}
}
@ -790,10 +794,9 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
case TM_CLAMPY:
for (int x = x0; x < x1; x++)
{
if (v[x] >= 0.0 && v[x] <= 1.0)
fragcolor[x] = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra);
else
fragcolor[x] = 0;
fragcolor[x] = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra);
if (v[x] < 0.0 || v[x] > 1.0)
fragcolor[x] &= 0x00ffffff;
}
break;
case TM_INVERTOPAQUE:
@ -878,6 +881,8 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
}
}
uint32_t alphaThreshold = thread->AlphaThreshold;
uint8_t* discard = thread->scanline.discard;
for (int x = x0; x < x1; x++)
{
uint32_t r = thread->scanline.vColorR[x];
@ -891,6 +896,7 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
b += b >> 7;
uint32_t texel = fragcolor[x];
discard[x] = texel <= alphaThreshold;
fragcolor[x] = MAKEARGB(
(APART(texel) * a + 127) >> 8,
(RPART(texel) * r + 127) >> 8,