mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-23 20:59:58 +01:00
Add triangle clipping
This commit is contained in:
parent
78fe74caf3
commit
229c3f465a
2 changed files with 79 additions and 51 deletions
126
s3l.h
126
s3l.h
|
@ -1022,6 +1022,13 @@ void _S3L_drawFilledTriangle(
|
||||||
initPC(t,r,r)
|
initPC(t,r,r)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// clip to the screen in y dimension:
|
||||||
|
|
||||||
|
endY = S3L_min(endY,S3L_RESOLUTION_Y);
|
||||||
|
|
||||||
|
/* Clipping above the screen (y < 0) can't be easily done here, will be
|
||||||
|
handled inside the loop. */
|
||||||
|
|
||||||
while (currentY < endY) /* draw the triangle from top to bottom -- the
|
while (currentY < endY) /* draw the triangle from top to bottom -- the
|
||||||
bottom-most row is left out because, following
|
bottom-most row is left out because, following
|
||||||
from the rasterization rules (see top of the
|
from the rasterization rules (see top of the
|
||||||
|
@ -1062,64 +1069,85 @@ void _S3L_drawFilledTriangle(
|
||||||
stepSide(r)
|
stepSide(r)
|
||||||
stepSide(l)
|
stepSide(l)
|
||||||
|
|
||||||
p->y = currentY;
|
if (currentY >= 0) /* clipping of pixels whose y < 0 (can't be easily done
|
||||||
|
outside the loop) */
|
||||||
// draw the horizontal line
|
|
||||||
|
|
||||||
S3L_Unit rowLength = S3L_nonZero(rX - lX - 1); // prevent zero div
|
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
|
||||||
S3L_Unit
|
|
||||||
lDepth, rDepth,
|
|
||||||
lT, rT; // perspective-corrected position along either side
|
|
||||||
|
|
||||||
lT = S3L_correctPerspective(lSideUnitPosScaled >> S3L_LERP_QUALITY,&lPC);
|
|
||||||
rT = S3L_correctPerspective(rSideUnitPosScaled >> S3L_LERP_QUALITY,&rPC);
|
|
||||||
|
|
||||||
lDepth = S3L_interpolateByUnit(lPC.a[2],lPC.b[2],lT);
|
|
||||||
rDepth = S3L_interpolateByUnit(rPC.a[2],rPC.b[2],rT);
|
|
||||||
|
|
||||||
S3L_initPerspectiveCorrectionState(
|
|
||||||
S3L_interpolateByUnit(lPC.a[0],lPC.b[0],lT),
|
|
||||||
S3L_interpolateByUnit(lPC.a[1],lPC.b[1],lT),
|
|
||||||
lDepth,
|
|
||||||
S3L_interpolateByUnit(rPC.a[0],rPC.b[0],rT),
|
|
||||||
S3L_interpolateByUnit(rPC.a[1],rPC.b[1],rT),
|
|
||||||
rDepth,
|
|
||||||
camera->focalLength,
|
|
||||||
&rowPC
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
S3L_Unit b0 = 0;
|
|
||||||
S3L_Unit b1 = lSideUnitPosScaled;
|
|
||||||
|
|
||||||
S3L_Unit b0Step = rSideUnitPosScaled / rowLength;
|
|
||||||
S3L_Unit b1Step = lSideUnitPosScaled / rowLength;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (S3L_ScreenCoord x = lX; x < rX; ++x)
|
|
||||||
{
|
{
|
||||||
|
p->y = currentY;
|
||||||
|
|
||||||
|
// draw the horizontal line
|
||||||
|
|
||||||
|
S3L_Unit rowLength = S3L_nonZero(rX - lX - 1); // prevent zero div
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||||
S3L_Unit rowT =
|
S3L_Unit
|
||||||
S3L_correctPerspective(S3L_interpolateFrom0(S3L_FRACTIONS_PER_UNIT,
|
lDepth, rDepth,
|
||||||
x - lX,rowLength),&rowPC);
|
lT, rT; // perspective-corrected position along either side
|
||||||
|
|
||||||
*barycentric0 = S3L_interpolateByUnitFrom0(rT,rowT);
|
lT = S3L_correctPerspective(lSideUnitPosScaled >> S3L_LERP_QUALITY,&lPC);
|
||||||
*barycentric1 = S3L_interpolateByUnit(lT,0,rowT);
|
rT = S3L_correctPerspective(rSideUnitPosScaled >> S3L_LERP_QUALITY,&rPC);
|
||||||
|
|
||||||
|
lDepth = S3L_interpolateByUnit(lPC.a[2],lPC.b[2],lT);
|
||||||
|
rDepth = S3L_interpolateByUnit(rPC.a[2],rPC.b[2],rT);
|
||||||
|
|
||||||
|
S3L_initPerspectiveCorrectionState(
|
||||||
|
S3L_interpolateByUnit(lPC.a[0],lPC.b[0],lT),
|
||||||
|
S3L_interpolateByUnit(lPC.a[1],lPC.b[1],lT),
|
||||||
|
lDepth,
|
||||||
|
S3L_interpolateByUnit(rPC.a[0],rPC.b[0],rT),
|
||||||
|
S3L_interpolateByUnit(rPC.a[1],rPC.b[1],rT),
|
||||||
|
rDepth,
|
||||||
|
camera->focalLength,
|
||||||
|
&rowPC
|
||||||
|
);
|
||||||
#else
|
#else
|
||||||
*barycentric0 = b0 >> S3L_LERP_QUALITY;
|
S3L_Unit b0 = 0;
|
||||||
*barycentric1 = b1 >> S3L_LERP_QUALITY;
|
S3L_Unit b1 = lSideUnitPosScaled;
|
||||||
|
|
||||||
b0 += b0Step;
|
S3L_Unit b0Step = rSideUnitPosScaled / rowLength;
|
||||||
b1 -= b1Step;
|
S3L_Unit b1Step = lSideUnitPosScaled / rowLength;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
// clip to the screen in x dimension:
|
||||||
|
|
||||||
p->x = x;
|
S3L_ScreenCoord rXClipped = S3L_min(rX,S3L_RESOLUTION_X),
|
||||||
S3L_PIXEL_FUNCTION(p);
|
lXClipped = lX;
|
||||||
}
|
|
||||||
|
if (lXClipped < 0)
|
||||||
|
{
|
||||||
|
lXClipped = 0;
|
||||||
|
|
||||||
|
#if S3L_PERSPECTIVE_CORRECTION != 1
|
||||||
|
b0 -= lX * b0Step;
|
||||||
|
b1 += lX * b1Step;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the row:
|
||||||
|
|
||||||
|
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||||
|
S3L_Unit rowT =
|
||||||
|
S3L_correctPerspective(S3L_interpolateFrom0(S3L_FRACTIONS_PER_UNIT,
|
||||||
|
x - lX,rowLength),&rowPC);
|
||||||
|
|
||||||
|
*barycentric0 = S3L_interpolateByUnitFrom0(rT,rowT);
|
||||||
|
*barycentric1 = S3L_interpolateByUnit(lT,0,rowT);
|
||||||
|
#else
|
||||||
|
*barycentric0 = b0 >> S3L_LERP_QUALITY;
|
||||||
|
*barycentric1 = b1 >> S3L_LERP_QUALITY;
|
||||||
|
|
||||||
|
b0 += b0Step;
|
||||||
|
b1 -= b1Step;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
||||||
|
|
||||||
|
p->x = x;
|
||||||
|
S3L_PIXEL_FUNCTION(p);
|
||||||
|
}
|
||||||
|
} // y clipping
|
||||||
|
|
||||||
lSideUnitPosScaled += lSideStep;
|
lSideUnitPosScaled += lSideStep;
|
||||||
rSideUnitPosScaled += rSideStep;
|
rSideUnitPosScaled += rSideStep;
|
||||||
|
|
|
@ -132,8 +132,8 @@ void draw()
|
||||||
modelTransform.rotation.z = frame * 0.1;
|
modelTransform.rotation.z = frame * 0.1;
|
||||||
modelTransform.rotation.x = frame * 0.3;
|
modelTransform.rotation.x = frame * 0.3;
|
||||||
|
|
||||||
// modelTransform.translation.x = sin(frame >> 3) * 700;
|
modelTransform.translation.x = sin(frame >> 7) * 700;
|
||||||
// modelTransform.translation.y = sin(frame >> 4) * 600;
|
modelTransform.translation.y = sin(frame >> 8) * 600;
|
||||||
|
|
||||||
S3L_drawModelIndexed(ver,tri,12,modelTransform,&camera,&conf);
|
S3L_drawModelIndexed(ver,tri,12,modelTransform,&camera,&conf);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue