mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-24 21:09:57 +01:00
Implement approximate PC (ugly)
This commit is contained in:
parent
d1b20675d3
commit
15d17a9c02
2 changed files with 88 additions and 14 deletions
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#define S3L_FLAT 0
|
#define S3L_FLAT 0
|
||||||
#define S3L_STRICT_NEAR_CULLING 0
|
#define S3L_STRICT_NEAR_CULLING 0
|
||||||
#define S3L_PERSPECTIVE_CORRECTION 1
|
#define S3L_PERSPECTIVE_CORRECTION 2
|
||||||
#define S3L_SORT 2
|
#define S3L_SORT 2
|
||||||
#define S3L_STENCIL_BUFFER 1
|
#define S3L_STENCIL_BUFFER 1
|
||||||
#define S3L_Z_BUFFER 0
|
#define S3L_Z_BUFFER 0
|
||||||
|
|
100
small3dlib.h
100
small3dlib.h
|
@ -177,11 +177,16 @@ typedef uint16_t S3L_Index;
|
||||||
is an expensive operation! Possible values:
|
is an expensive operation! Possible values:
|
||||||
|
|
||||||
- 0: No perspective correction. Fastest, ugly.
|
- 0: No perspective correction. Fastest, ugly.
|
||||||
- 1: Per-pixel perspective correction, nice but very expensive.*/
|
- 1: Per-pixel perspective correction, nice but very expensive.
|
||||||
|
- 2: Approximation (computing only at every S3L_PC_APPROX_LENGTHth pixel). */
|
||||||
|
|
||||||
#define S3L_PERSPECTIVE_CORRECTION 0
|
#define S3L_PERSPECTIVE_CORRECTION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef S3L_PC_APPROX_LENGTH
|
||||||
|
#define S3L_PC_APPROX_LENGTH 32
|
||||||
|
#endif
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION
|
#if S3L_PERSPECTIVE_CORRECTION
|
||||||
#define S3L_COMPUTE_DEPTH 1 // PC inevitably computes depth, so enable it
|
#define S3L_COMPUTE_DEPTH 1 // PC inevitably computes depth, so enable it
|
||||||
#endif
|
#endif
|
||||||
|
@ -695,7 +700,7 @@ static inline int8_t S3L_stencilTest(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define S3L_COMPUTE_LERP_DEPTH\
|
#define S3L_COMPUTE_LERP_DEPTH\
|
||||||
(S3L_COMPUTE_DEPTH && (S3L_PERSPECTIVE_CORRECTION != 1))
|
(S3L_COMPUTE_DEPTH && (S3L_PERSPECTIVE_CORRECTION == 0))
|
||||||
|
|
||||||
#define S3L_SIN_TABLE_LENGTH 128
|
#define S3L_SIN_TABLE_LENGTH 128
|
||||||
|
|
||||||
|
@ -1758,7 +1763,7 @@ void S3L_drawTriangle(
|
||||||
initSide(r,t,r,1)
|
initSide(r,t,r,1)
|
||||||
initSide(l,t,l,1)
|
initSide(l,t,l,1)
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION != 0
|
||||||
/* PC is done by linearly interpolating reciprocals from which the corrected
|
/* PC is done by linearly interpolating reciprocals from which the corrected
|
||||||
velues can be computed. See
|
velues can be computed. See
|
||||||
http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ */
|
http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ */
|
||||||
|
@ -1842,7 +1847,7 @@ void S3L_drawTriangle(
|
||||||
#if !S3L_FLAT
|
#if !S3L_FLAT
|
||||||
S3L_Unit rowLength = S3L_nonZero(rX - lX - 1); // prevent zero div
|
S3L_Unit rowLength = S3L_nonZero(rX - lX - 1); // prevent zero div
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION != 0
|
||||||
S3L_Unit lOverZ, lRecipZ, rOverZ, rRecipZ, lT, rT;
|
S3L_Unit lOverZ, lRecipZ, rOverZ, rRecipZ, lT, rT;
|
||||||
|
|
||||||
lT = S3L_getFastLerpValue(lSideFLS);
|
lT = S3L_getFastLerpValue(lSideFLS);
|
||||||
|
@ -1869,6 +1874,7 @@ void S3L_drawTriangle(
|
||||||
|
|
||||||
b0FLS.stepScaled = rSideFLS.valueScaled / rowLength;
|
b0FLS.stepScaled = rSideFLS.valueScaled / rowLength;
|
||||||
b1FLS.stepScaled = -1 * lSideFLS.valueScaled / rowLength;
|
b1FLS.stepScaled = -1 * lSideFLS.valueScaled / rowLength;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1881,7 +1887,7 @@ void S3L_drawTriangle(
|
||||||
{
|
{
|
||||||
lXClipped = 0;
|
lXClipped = 0;
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION != 1 && !S3L_FLAT
|
#if S3L_PERSPECTIVE_CORRECTION == 0 && !S3L_FLAT
|
||||||
b0FLS.valueScaled -= lX * b0FLS.stepScaled;
|
b0FLS.valueScaled -= lX * b0FLS.stepScaled;
|
||||||
b1FLS.valueScaled -= lX * b1FLS.stepScaled;
|
b1FLS.valueScaled -= lX * b1FLS.stepScaled;
|
||||||
|
|
||||||
|
@ -1891,7 +1897,7 @@ void S3L_drawTriangle(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION != 0
|
||||||
S3L_ScreenCoord i = lXClipped - lX; /* helper var to save one
|
S3L_ScreenCoord i = lXClipped - lX; /* helper var to save one
|
||||||
substraction in the inner
|
substraction in the inner
|
||||||
loop */
|
loop */
|
||||||
|
@ -1912,6 +1918,29 @@ void S3L_drawTriangle(
|
||||||
|
|
||||||
// draw the row -- inner loop:
|
// draw the row -- inner loop:
|
||||||
|
|
||||||
|
#if S3L_PERSPECTIVE_CORRECTION == 2
|
||||||
|
S3L_FastLerpState depthPC, b0PC, b1PC;
|
||||||
|
|
||||||
|
depthPC.valueScaled =
|
||||||
|
((S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
|
||||||
|
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,i,rowLength)))
|
||||||
|
<< S3L_FAST_LERP_QUALITY;
|
||||||
|
|
||||||
|
b0PC.valueScaled =
|
||||||
|
(
|
||||||
|
S3L_interpolateFrom0(rOverZ,i,rowLength)
|
||||||
|
* depthPC.valueScaled
|
||||||
|
) / S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
|
b1PC.valueScaled =
|
||||||
|
(
|
||||||
|
(lOverZ - S3L_interpolateFrom0(lOverZ,i,rowLength))
|
||||||
|
* depthPC.valueScaled
|
||||||
|
) / S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
|
int8_t rowCount = S3L_PC_APPROX_LENGTH;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||||
{
|
{
|
||||||
int8_t testsPassed = 1;
|
int8_t testsPassed = 1;
|
||||||
|
@ -1926,6 +1955,42 @@ void S3L_drawTriangle(
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||||
p.depth = (S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
|
p.depth = (S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
|
||||||
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,i,rowLength));
|
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,i,rowLength));
|
||||||
|
#elif S3L_PERSPECTIVE_CORRECTION == 2
|
||||||
|
if (rowCount >= S3L_PC_APPROX_LENGTH)
|
||||||
|
{
|
||||||
|
rowCount = 0;
|
||||||
|
|
||||||
|
S3L_Unit nextI = i + S3L_PC_APPROX_LENGTH;
|
||||||
|
|
||||||
|
S3L_Unit nextDepth =
|
||||||
|
(
|
||||||
|
(S3L_FRACTIONS_PER_UNIT * S3L_FRACTIONS_PER_UNIT) /
|
||||||
|
S3L_nonZero(S3L_interpolate(lRecipZ,rRecipZ,nextI,rowLength))
|
||||||
|
) << S3L_FAST_LERP_QUALITY;
|
||||||
|
|
||||||
|
depthPC.stepScaled =
|
||||||
|
(nextDepth - depthPC.valueScaled) / S3L_PC_APPROX_LENGTH;
|
||||||
|
|
||||||
|
S3L_Unit nextValue =
|
||||||
|
(
|
||||||
|
S3L_interpolateFrom0(rOverZ,nextI,rowLength)
|
||||||
|
* nextDepth
|
||||||
|
) / S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
|
b0PC.stepScaled =
|
||||||
|
(nextValue - b0PC.valueScaled) / S3L_PC_APPROX_LENGTH;
|
||||||
|
|
||||||
|
nextValue =
|
||||||
|
(
|
||||||
|
(lOverZ - S3L_interpolateFrom0(lOverZ,nextI,rowLength))
|
||||||
|
* nextDepth
|
||||||
|
) / S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
|
b1PC.stepScaled =
|
||||||
|
(nextValue - b1PC.valueScaled) / S3L_PC_APPROX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.depth = S3L_getFastLerpValue(depthPC);
|
||||||
#else
|
#else
|
||||||
p.depth = S3L_getFastLerpValue(depthFLS);
|
p.depth = S3L_getFastLerpValue(depthFLS);
|
||||||
S3L_stepFastLerp(depthFLS);
|
S3L_stepFastLerp(depthFLS);
|
||||||
|
@ -1942,7 +2007,10 @@ void S3L_drawTriangle(
|
||||||
if (testsPassed)
|
if (testsPassed)
|
||||||
{
|
{
|
||||||
#if !S3L_FLAT
|
#if !S3L_FLAT
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION == 0
|
||||||
|
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
||||||
|
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
||||||
|
#elif S3L_PERSPECTIVE_CORRECTION == 1
|
||||||
*barycentric0 =
|
*barycentric0 =
|
||||||
(
|
(
|
||||||
S3L_interpolateFrom0(rOverZ,i,rowLength)
|
S3L_interpolateFrom0(rOverZ,i,rowLength)
|
||||||
|
@ -1954,21 +2022,27 @@ void S3L_drawTriangle(
|
||||||
(lOverZ - S3L_interpolateFrom0(lOverZ,i,rowLength))
|
(lOverZ - S3L_interpolateFrom0(lOverZ,i,rowLength))
|
||||||
* p.depth
|
* p.depth
|
||||||
) / S3L_FRACTIONS_PER_UNIT;
|
) / S3L_FRACTIONS_PER_UNIT;
|
||||||
#else
|
#elif S3L_PERSPECTIVE_CORRECTION == 2
|
||||||
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
*barycentric0 = S3L_getFastLerpValue(b0PC);
|
||||||
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
*barycentric1 = S3L_getFastLerpValue(b1PC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*barycentric2 =
|
*barycentric2 =
|
||||||
S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
S3L_PIXEL_FUNCTION(&p);
|
S3L_PIXEL_FUNCTION(&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !S3L_FLAT
|
#if !S3L_FLAT
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION != 0
|
||||||
i++;
|
i++;
|
||||||
|
#if S3L_PERSPECTIVE_CORRECTION == 2
|
||||||
|
rowCount++;
|
||||||
|
|
||||||
|
S3L_stepFastLerp(depthPC);
|
||||||
|
S3L_stepFastLerp(b0PC);
|
||||||
|
S3L_stepFastLerp(b1PC);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
S3L_stepFastLerp(b0FLS);
|
S3L_stepFastLerp(b0FLS);
|
||||||
S3L_stepFastLerp(b1FLS);
|
S3L_stepFastLerp(b1FLS);
|
||||||
|
|
Loading…
Reference in a new issue