SoftGPU: Correct clipping for flat shading.

It needs to use the provoking color, regardless of culling or clipping.

Fixes Blade Dancer lighting (see #4140.)
This commit is contained in:
Unknown W. Brackets 2018-11-22 17:48:55 -08:00
parent 1c19bce514
commit 11a8857a7e
3 changed files with 40 additions and 26 deletions

View file

@ -342,12 +342,12 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
case GE_PRIM_TRIANGLES:
{
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]);
} else if (!gstate.getCullMode()) {
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]);
}
break;
}
@ -413,7 +413,8 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
vreader.Goto(vtx);
}
data[(data_index++) % 3] = ReadVertex(vreader);
int provoking_index = (data_index++) % 3;
data[provoking_index] = ReadVertex(vreader);
if (outside_range_flag) {
// Drop all primitives containing the current vertex
skip_count = 2;
@ -427,14 +428,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]);
} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]);
}
}
break;
@ -466,7 +467,8 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
vreader.Goto(vtx);
}
data[2 - ((data_index++) % 2)] = ReadVertex(vreader);
int provoking_index = 2 - ((data_index++) % 2);
data[provoking_index] = ReadVertex(vreader);
if (outside_range_flag) {
// Drop all primitives containing the current vertex
skip_count = 2;
@ -480,14 +482,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]);
} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0]);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]);
}
}
break;