1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/small3dlib.git synced 2024-11-21 20:39:57 +01:00

Fix PC bug

This commit is contained in:
Miloslav Číž 2019-06-12 00:03:23 +02:00
parent d63b23c6d9
commit 0deafc2da6

View file

@ -1990,36 +1990,72 @@ void S3L_drawTriangle(
#elif S3L_PERSPECTIVE_CORRECTION == 2 #elif S3L_PERSPECTIVE_CORRECTION == 2
if (rowCount >= S3L_PC_APPROX_LENGTH) if (rowCount >= S3L_PC_APPROX_LENGTH)
{ {
// init the linear interpolation to the next PC correct value
rowCount = 0; rowCount = 0;
S3L_Unit nextI = i + S3L_PC_APPROX_LENGTH; S3L_Unit nextI = i + S3L_PC_APPROX_LENGTH;
S3L_Unit nextDepth = if (nextI >= rowLength)
( {
(S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) / /* A special case where we'd be interpolating outside the triangle.
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,nextI,rowLength)) It seems like a valid approach at first, but it creates a bug
) << S3L_FAST_LERP_QUALITY; in a case when the rasaterized triangle is near screen 0 and can
actually never reach the extrapolated screen position. So we
have to clamp to the actual end of the triangle here. */
depthPC.stepScaled = S3L_Unit maxI = S3L_nonZero(rowLength - i);
(nextDepth - depthPC.valueScaled) / S3L_PC_APPROX_LENGTH;
S3L_Unit nextValue = S3L_Unit nextDepthScaled =
( (
S3L_interpolateFrom0(rOverZ,nextI,rowLength) (S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
* nextDepth S3L_nonZero(rRecipZ)
) / S3L_FRACTIONS_PER_UNIT; ) << S3L_FAST_LERP_QUALITY;
b0PC.stepScaled = depthPC.stepScaled =
(nextValue - b0PC.valueScaled) / S3L_PC_APPROX_LENGTH; (nextDepthScaled - depthPC.valueScaled) / maxI;
nextValue = S3L_Unit nextValue =
( (
(lOverZ - S3L_interpolateFrom0(lOverZ,nextI,rowLength)) rOverZ
* nextDepth * nextDepthScaled
) / S3L_FRACTIONS_PER_UNIT; ) / S3L_FRACTIONS_PER_UNIT;
b1PC.stepScaled = b0PC.stepScaled =
(nextValue - b1PC.valueScaled) / S3L_PC_APPROX_LENGTH; (nextValue - b0PC.valueScaled) / maxI;
b1PC.stepScaled =
-1 * b1PC.valueScaled / maxI;
}
else
{
S3L_Unit nextDepthScaled =
(
(S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,nextI,rowLength))
) << S3L_FAST_LERP_QUALITY;
depthPC.stepScaled =
(nextDepthScaled - depthPC.valueScaled) / S3L_PC_APPROX_LENGTH;
S3L_Unit nextValue =
(
S3L_interpolateFrom0(rOverZ,nextI,rowLength)
* nextDepthScaled
) / S3L_FRACTIONS_PER_UNIT;
b0PC.stepScaled =
(nextValue - b0PC.valueScaled) / S3L_PC_APPROX_LENGTH;
nextValue =
(
(lOverZ - S3L_interpolateFrom0(lOverZ,nextI,rowLength))
* nextDepthScaled
) / S3L_FRACTIONS_PER_UNIT;
b1PC.stepScaled =
(nextValue - b1PC.valueScaled) / S3L_PC_APPROX_LENGTH;
}
} }
p.depth = S3L_getFastLerpValue(depthPC); p.depth = S3L_getFastLerpValue(depthPC);