mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 12:34:39 +08:00 
			
		
		
		
	Pica/Rasterizer: Clean up and fix backface culling.
This commit is contained in:
		
							parent
							
								
									365236fa4c
								
							
						
					
					
						commit
						638b370fb5
					
				@ -90,9 +90,14 @@ static int SignedArea (const Math::Vec2<Fix12P4>& vtx1,
 | 
				
			|||||||
    return Math::Cross(vec1, vec2).z;
 | 
					    return Math::Cross(vec1, vec2).z;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
					/**
 | 
				
			||||||
                     const VertexShader::OutputVertex& v1,
 | 
					 * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing
 | 
				
			||||||
                     const VertexShader::OutputVertex& v2)
 | 
					 * culling via recursion.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
 | 
				
			||||||
 | 
					                                    const VertexShader::OutputVertex& v1,
 | 
				
			||||||
 | 
					                                    const VertexShader::OutputVertex& v2,
 | 
				
			||||||
 | 
					                                    bool reversed = false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // vertex positions in rasterizer coordinates
 | 
					    // vertex positions in rasterizer coordinates
 | 
				
			||||||
    auto FloatToFix = [](float24 flt) {
 | 
					    auto FloatToFix = [](float24 flt) {
 | 
				
			||||||
@ -106,17 +111,22 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
                                   ScreenToRasterizerCoordinates(v1.screenpos),
 | 
					                                   ScreenToRasterizerCoordinates(v1.screenpos),
 | 
				
			||||||
                                   ScreenToRasterizerCoordinates(v2.screenpos) };
 | 
					                                   ScreenToRasterizerCoordinates(v2.screenpos) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (registers.cull_mode == Regs::CullMode::KeepCounterClockWise) {
 | 
					    if (registers.cull_mode == Regs::CullMode::KeepAll) {
 | 
				
			||||||
        // Reverse vertex order and use the CW code path.
 | 
					        // Make sure we always end up with a triangle wound counter-clockwise
 | 
				
			||||||
        std::swap(vtxpos[1], vtxpos[2]);
 | 
					        if (!reversed && SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0) {
 | 
				
			||||||
    }
 | 
					            ProcessTriangleInternal(v0, v2, v1, true);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (!reversed && registers.cull_mode == Regs::CullMode::KeepClockWise) {
 | 
				
			||||||
 | 
					            // Reverse vertex order and use the CCW code path.
 | 
				
			||||||
 | 
					            ProcessTriangleInternal(v0, v2, v1, true);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (registers.cull_mode != Regs::CullMode::KeepAll) {
 | 
					        // Cull away triangles which are wound clockwise.
 | 
				
			||||||
        // Cull away triangles which are wound counter-clockwise.
 | 
					 | 
				
			||||||
        if (SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0)
 | 
					        if (SignedArea(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) <= 0)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        // TODO: Consider A check for degenerate triangles ("SignedArea == 0")
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: Proper scissor rect test!
 | 
					    // TODO: Proper scissor rect test!
 | 
				
			||||||
@ -695,6 +705,12 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProcessTriangle(const VertexShader::OutputVertex& v0,
 | 
				
			||||||
 | 
					                     const VertexShader::OutputVertex& v1,
 | 
				
			||||||
 | 
					                     const VertexShader::OutputVertex& v2) {
 | 
				
			||||||
 | 
					    ProcessTriangleInternal(v0, v1, v2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Rasterizer
 | 
					} // namespace Rasterizer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Pica
 | 
					} // namespace Pica
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user