mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-02 03:32:17 +00:00
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:
parent
1c19bce514
commit
11a8857a7e
@ -176,10 +176,10 @@ void ProcessRect(const VertexData& v0, const VertexData& v1)
|
||||
}
|
||||
|
||||
// Four triangles to do backfaces as well. Two of them will get backface culled.
|
||||
ProcessTriangle(*topleft, *topright, *bottomright);
|
||||
ProcessTriangle(*bottomright, *topright, *topleft);
|
||||
ProcessTriangle(*bottomright, *bottomleft, *topleft);
|
||||
ProcessTriangle(*topleft, *bottomleft, *bottomright);
|
||||
ProcessTriangle(*topleft, *topright, *bottomright, buf[3]);
|
||||
ProcessTriangle(*bottomright, *topright, *topleft, buf[3]);
|
||||
ProcessTriangle(*bottomright, *bottomleft, *topleft, buf[3]);
|
||||
ProcessTriangle(*topleft, *bottomleft, *bottomright, buf[3]);
|
||||
} else {
|
||||
// through mode handling
|
||||
VertexData buf[4];
|
||||
@ -271,10 +271,17 @@ void ProcessLine(VertexData& v0, VertexData& v1)
|
||||
Rasterizer::DrawLine(data[0], data[1]);
|
||||
}
|
||||
|
||||
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2)
|
||||
{
|
||||
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking) {
|
||||
if (gstate.isModeThrough()) {
|
||||
Rasterizer::DrawTriangle(v0, v1, v2);
|
||||
// In case of cull reordering, make sure the right color is on the final vertex.
|
||||
if (gstate.getShadeMode() == GE_SHADE_FLAT) {
|
||||
VertexData corrected2 = v2;
|
||||
corrected2.color0 = provoking.color0;
|
||||
corrected2.color1 = provoking.color1;
|
||||
Rasterizer::DrawTriangle(v0, v1, corrected2);
|
||||
} else {
|
||||
Rasterizer::DrawTriangle(v0, v1, v2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,14 +346,19 @@ void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i+3 <= numIndices; i+=3)
|
||||
{
|
||||
if(indices[i] != SKIP_FLAG)
|
||||
{
|
||||
for (int i = 0; i + 3 <= numIndices; i += 3) {
|
||||
if (indices[i] != SKIP_FLAG) {
|
||||
VertexData data[3] = { *Vertices[indices[i]], *Vertices[indices[i+1]], *Vertices[indices[i+2]] };
|
||||
data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos);
|
||||
data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos);
|
||||
data[2].screenpos = TransformUnit::ClipToScreen(data[2].clippos);
|
||||
|
||||
if (gstate.getShadeMode() == GE_SHADE_FLAT) {
|
||||
// So that the order of clipping doesn't matter...
|
||||
data[2].color0 = provoking.color0;
|
||||
data[2].color1 = provoking.color1;
|
||||
}
|
||||
|
||||
Rasterizer::DrawTriangle(data[0], data[1], data[2]);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace Clipper {
|
||||
|
||||
void ProcessPoint(VertexData& v0);
|
||||
void ProcessLine(VertexData& v0, VertexData& v1);
|
||||
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2);
|
||||
void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking);
|
||||
void ProcessRect(const VertexData& v0, const VertexData& v1);
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user