mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-24 21:09:57 +01:00
Add fast ler state
This commit is contained in:
parent
4784993e63
commit
aba0c82426
1 changed files with 37 additions and 29 deletions
66
s3l.h
66
s3l.h
|
@ -883,6 +883,18 @@ typedef struct
|
||||||
int16_t minorDiff;
|
int16_t minorDiff;
|
||||||
} S3L_BresenhamState; ///< State of drawing a line with Bresenham algorithm.
|
} S3L_BresenhamState; ///< State of drawing a line with Bresenham algorithm.
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
S3L_Unit valueScaled;
|
||||||
|
S3L_Unit stepScaled;
|
||||||
|
} S3L_FastLerpState;
|
||||||
|
|
||||||
|
#define S3L_getFastLerpValue(state)\
|
||||||
|
(state.valueScaled >> S3L_FAST_LERP_QUALITY)
|
||||||
|
|
||||||
|
#define S3L_stepFastLerp(state)\
|
||||||
|
state.valueScaled += state.stepScaled
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
S3L_ScreenCoord p0[2]; ///< 2D coordinates of the 1st point projection
|
S3L_ScreenCoord p0[2]; ///< 2D coordinates of the 1st point projection
|
||||||
|
@ -1198,11 +1210,8 @@ void _S3L_drawFilledTriangle(
|
||||||
lErrAdd, rErrAdd, // error value to add in each Bresenham cycle
|
lErrAdd, rErrAdd, // error value to add in each Bresenham cycle
|
||||||
lErrSub, rErrSub; // error value to substract when moving in x direction
|
lErrSub, rErrSub; // error value to substract when moving in x direction
|
||||||
|
|
||||||
S3L_Unit
|
S3L_FastLerpState
|
||||||
lSideStep, rSideStep, lSideUnitPosScaled, rSideUnitPosScaled;
|
lSideFLS, rSideFLS;
|
||||||
/* ^ These are helper vars for faster linear iterpolation (we scale the
|
|
||||||
S3L_FRACTIONS_PER_UNIT up by shifting to the right by
|
|
||||||
S3L_FAST_LERP_QUALITY and simply increment by steps. */
|
|
||||||
|
|
||||||
/* init side for the algorithm, params:
|
/* init side for the algorithm, params:
|
||||||
s - which side (l or r)
|
s - which side (l or r)
|
||||||
|
@ -1213,13 +1222,13 @@ void _S3L_drawFilledTriangle(
|
||||||
s##X = p1##PointSx;\
|
s##X = p1##PointSx;\
|
||||||
s##Dx = p2##PointSx - p1##PointSx;\
|
s##Dx = p2##PointSx - p1##PointSx;\
|
||||||
s##Dy = p2##PointSy - p1##PointSy;\
|
s##Dy = p2##PointSy - p1##PointSy;\
|
||||||
s##SideStep = (S3L_FRACTIONS_PER_UNIT << S3L_FAST_LERP_QUALITY)\
|
s##SideFLS.stepScaled = (S3L_FRACTIONS_PER_UNIT << S3L_FAST_LERP_QUALITY)\
|
||||||
/ (s##Dy != 0 ? s##Dy : 1);\
|
/ (s##Dy != 0 ? s##Dy : 1);\
|
||||||
s##SideUnitPosScaled = 0;\
|
s##SideFLS.valueScaled = 0;\
|
||||||
if (!down)\
|
if (!down)\
|
||||||
{\
|
{\
|
||||||
s##SideUnitPosScaled = S3L_FRACTIONS_PER_UNIT << S3L_FAST_LERP_QUALITY;\
|
s##SideFLS.valueScaled = S3L_FRACTIONS_PER_UNIT << S3L_FAST_LERP_QUALITY;\
|
||||||
s##SideStep *= -1;\
|
s##SideFLS.stepScaled *= -1;\
|
||||||
}\
|
}\
|
||||||
s##Inc = s##Dx >= 0 ? 1 : -1;\
|
s##Inc = s##Dx >= 0 ? 1 : -1;\
|
||||||
if (s##Dx < 0)\
|
if (s##Dx < 0)\
|
||||||
|
@ -1277,9 +1286,9 @@ void _S3L_drawFilledTriangle(
|
||||||
S3L_Unit *tmp = barycentric##b0;\
|
S3L_Unit *tmp = barycentric##b0;\
|
||||||
barycentric##b0 = barycentric##b1;\
|
barycentric##b0 = barycentric##b1;\
|
||||||
barycentric##b1 = tmp;\
|
barycentric##b1 = tmp;\
|
||||||
s##SideUnitPosScaled = (S3L_FRACTIONS_PER_UNIT\
|
s##SideFLS.valueScaled = (S3L_FRACTIONS_PER_UNIT\
|
||||||
<< S3L_FAST_LERP_QUALITY) - s##SideUnitPosScaled;\
|
<< S3L_FAST_LERP_QUALITY) - s##SideFLS.valueScaled;\
|
||||||
s##SideStep *= -1;
|
s##SideFLS.stepScaled *= -1;
|
||||||
|
|
||||||
if (splitOnLeft)
|
if (splitOnLeft)
|
||||||
{
|
{
|
||||||
|
@ -1322,11 +1331,8 @@ void _S3L_drawFilledTriangle(
|
||||||
lDepth, rDepth,
|
lDepth, rDepth,
|
||||||
lT, rT; // perspective-corrected position along either side
|
lT, rT; // perspective-corrected position along either side
|
||||||
|
|
||||||
lT = S3L_correctPerspective(lSideUnitPosScaled >> S3L_FAST_LERP_QUALITY,
|
lT = S3L_correctPerspective(S3L_getFastLerpValue(lSideFLS),&lPC);
|
||||||
&lPC);
|
rT = S3L_correctPerspective(S3L_getFastLerpValue(rSideFLS),&rPC);
|
||||||
|
|
||||||
rT = S3L_correctPerspective(rSideUnitPosScaled >> S3L_FAST_LERP_QUALITY,
|
|
||||||
&rPC);
|
|
||||||
|
|
||||||
lDepth = S3L_interpolateByUnit(lPC.a[2],lPC.b[2],lT);
|
lDepth = S3L_interpolateByUnit(lPC.a[2],lPC.b[2],lT);
|
||||||
rDepth = S3L_interpolateByUnit(rPC.a[2],rPC.b[2],rT);
|
rDepth = S3L_interpolateByUnit(rPC.a[2],rPC.b[2],rT);
|
||||||
|
@ -1342,11 +1348,13 @@ void _S3L_drawFilledTriangle(
|
||||||
&rowPC
|
&rowPC
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
S3L_Unit b0 = 0;
|
S3L_FastLerpState b0FLS, b1FLS;
|
||||||
S3L_Unit b1 = lSideUnitPosScaled;
|
|
||||||
|
|
||||||
S3L_Unit b0Step = rSideUnitPosScaled / rowLength;
|
b0FLS.valueScaled = 0;
|
||||||
S3L_Unit b1Step = lSideUnitPosScaled / rowLength;
|
b1FLS.valueScaled = lSideFLS.valueScaled;
|
||||||
|
|
||||||
|
b0FLS.stepScaled = rSideFLS.valueScaled / rowLength;
|
||||||
|
b1FLS.stepScaled = -1 * lSideFLS.valueScaled / rowLength;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clip to the screen in x dimension:
|
// clip to the screen in x dimension:
|
||||||
|
@ -1359,8 +1367,8 @@ void _S3L_drawFilledTriangle(
|
||||||
lXClipped = 0;
|
lXClipped = 0;
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION != 1
|
#if S3L_PERSPECTIVE_CORRECTION != 1
|
||||||
b0 -= lX * b0Step;
|
b0FLS.valueScaled -= lX * b0FLS.stepScaled;
|
||||||
b1 += lX * b1Step;
|
b1FLS.valueScaled -= lX * b1FLS.stepScaled;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,11 +1388,11 @@ void _S3L_drawFilledTriangle(
|
||||||
*barycentric1 =
|
*barycentric1 =
|
||||||
S3L_interpolateByUnitFrom0(lT,S3L_FRACTIONS_PER_UNIT - rowT);
|
S3L_interpolateByUnitFrom0(lT,S3L_FRACTIONS_PER_UNIT - rowT);
|
||||||
#else
|
#else
|
||||||
*barycentric0 = b0 >> S3L_FAST_LERP_QUALITY;
|
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
||||||
*barycentric1 = b1 >> S3L_FAST_LERP_QUALITY;
|
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
||||||
|
|
||||||
b0 += b0Step;
|
S3L_stepFastLerp(b0FLS);
|
||||||
b1 -= b1Step;
|
S3L_stepFastLerp(b1FLS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
||||||
|
@ -1394,8 +1402,8 @@ void _S3L_drawFilledTriangle(
|
||||||
}
|
}
|
||||||
} // y clipping
|
} // y clipping
|
||||||
|
|
||||||
lSideUnitPosScaled += lSideStep;
|
S3L_stepFastLerp(lSideFLS);
|
||||||
rSideUnitPosScaled += rSideStep;
|
S3L_stepFastLerp(rSideFLS);
|
||||||
|
|
||||||
++currentY;
|
++currentY;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue