mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-12-02 22:29:57 +01:00
Add stencil buffer
This commit is contained in:
parent
6cdae481df
commit
bfff51d4d0
2 changed files with 85 additions and 24 deletions
103
small3dlib.h
103
small3dlib.h
|
@ -178,12 +178,25 @@ typedef uint16_t S3L_Index;
|
|||
S3L_Z_BUFFER_*. */
|
||||
#endif
|
||||
|
||||
#ifndef S3L_STENCIL_BUFFER
|
||||
#define S3L_STENCIL_BUFFER 0 /**< Whether to use stencil buffer for drawing --
|
||||
with this pixels that have already been
|
||||
rasterized will be discarded. This is mostly
|
||||
for front-to-back sorted drawing. */
|
||||
#endif
|
||||
|
||||
#define S3L_SORT_NONE 0 /**< Don't sort triangles. This is fastest. */
|
||||
#define S3L_SORT_BACK_TO_FRONT 1 /**< Sort triangles from back to front. This
|
||||
can in most cases solve visibility
|
||||
without requiring almost any extra
|
||||
memory compared to z-buffer. */
|
||||
#define S3L_SORT_FRONT_TO_BACK 2 /**< TODO */
|
||||
#define S3L_SORT_FRONT_TO_BACK 2 /**< Sort triangles from front to back. This
|
||||
can be faster than back to front, because
|
||||
we prevent computing pixels that will be
|
||||
overwritten by nearer ones, but we need
|
||||
a 1b stencil buffer for this (enable
|
||||
S3L_STENCIL_BUFFER), so a bit more memory
|
||||
is needed. */
|
||||
#ifndef S3L_SORT
|
||||
#define S3L_SORT S3L_SORT_NONE /**< Defines how to sort triangles before
|
||||
drawing a frame. This can be used to solve
|
||||
|
@ -510,7 +523,12 @@ void S3L_drawTriangle(
|
|||
S3L_Index modelID,
|
||||
S3L_Index triangleID);
|
||||
|
||||
/** This should be called before rendering each frame. The function clears
|
||||
buffers and does potentially other things needed for the frame. */
|
||||
void S3L_newFrame();
|
||||
|
||||
void S3L_zBufferClear();
|
||||
void S3L_stencilBufferClear();
|
||||
|
||||
static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle);
|
||||
|
||||
|
@ -529,6 +547,50 @@ static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle);
|
|||
#define S3L_zBufferFormat(depth) (((depth) >> 5) & 0x000000FF)
|
||||
#endif
|
||||
|
||||
#if S3L_Z_BUFFER
|
||||
static inline int8_t S3L_zTest(
|
||||
S3L_ScreenCoord x,
|
||||
S3L_ScreenCoord y,
|
||||
S3L_Unit depth)
|
||||
{
|
||||
uint32_t index = y * S3L_RESOLUTION_X + x;
|
||||
|
||||
depth = S3L_zBufferFormat(depth);
|
||||
|
||||
if (depth < S3L_zBuffer[index])
|
||||
{
|
||||
S3L_zBuffer[index] = depth;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if S3L_STENCIL_BUFFER
|
||||
#define S3L_STENCIL_BUFFER_SIZE\
|
||||
((S3L_RESOLUTION_X * S3L_RESOLUTION_Y - 1) / 8 + 1)
|
||||
uint8_t S3L_stencilBuffer[S3L_STENCIL_BUFFER_SIZE];
|
||||
|
||||
static inline int8_t S3L_stencilTest(
|
||||
S3L_ScreenCoord x,
|
||||
S3L_ScreenCoord y)
|
||||
{
|
||||
uint32_t index = y * S3L_RESOLUTION_X + x;
|
||||
uint32_t bit = (index & 0x00000007);
|
||||
index = index >> 3;
|
||||
|
||||
uint8_t val = S3L_stencilBuffer[index];
|
||||
|
||||
if ((val >> bit) & 0x1)
|
||||
return 0;
|
||||
|
||||
S3L_stencilBuffer[index] = val | (0x1 << bit);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define S3L_COMPUTE_LERP_DEPTH\
|
||||
(S3L_COMPUTE_DEPTH && (S3L_PERSPECTIVE_CORRECTION != 1))
|
||||
|
||||
|
@ -1181,27 +1243,6 @@ void S3L_mapProjectionPlaneToScreen(
|
|||
(point.y * S3L_HALF_RESOLUTION_X) / S3L_FRACTIONS_PER_UNIT;
|
||||
}
|
||||
|
||||
static inline int8_t S3L_zTest(
|
||||
S3L_ScreenCoord x,
|
||||
S3L_ScreenCoord y,
|
||||
S3L_Unit depth)
|
||||
{
|
||||
#if S3L_Z_BUFFER
|
||||
uint32_t index = y * S3L_RESOLUTION_X + x;
|
||||
|
||||
depth = S3L_zBufferFormat(depth);
|
||||
|
||||
if (depth < S3L_zBuffer[index])
|
||||
{
|
||||
S3L_zBuffer[index] = depth;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void S3L_zBufferClear()
|
||||
{
|
||||
#if S3L_Z_BUFFER
|
||||
|
@ -1210,6 +1251,20 @@ void S3L_zBufferClear()
|
|||
#endif
|
||||
}
|
||||
|
||||
void S3L_stencilBufferClear()
|
||||
{
|
||||
#if S3L_STENCIL_BUFFER
|
||||
for (uint32_t i = 0; i < S3L_STENCIL_BUFFER_SIZE; ++i)
|
||||
S3L_stencilBuffer[i] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void S3L_newFrame()
|
||||
{
|
||||
S3L_zBufferClear();
|
||||
S3L_stencilBufferClear();
|
||||
}
|
||||
|
||||
void _S3L_drawFilledTriangle(
|
||||
S3L_Vec4 point0,
|
||||
S3L_Vec4 point1,
|
||||
|
@ -1525,6 +1580,10 @@ void _S3L_drawFilledTriangle(
|
|||
|
||||
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||
{
|
||||
#if S3L_STENCIL_BUFFER
|
||||
if (!S3L_stencilTest(x,p->y))
|
||||
continue;
|
||||
#endif
|
||||
p->x = x;
|
||||
|
||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
|
||||
#define S3L_Z_BUFFER 0
|
||||
|
||||
#define S3L_SORT S3L_SORT_BACK_TO_FRONT
|
||||
#define S3L_STENCIL_BUFFER 1
|
||||
|
||||
#define S3L_SORT S3L_SORT_FRONT_TO_BACK
|
||||
|
||||
#define S3L_PIXEL_FUNCTION drawPixel
|
||||
|
||||
|
@ -143,7 +145,7 @@ S3L_DrawConfig conf;
|
|||
|
||||
void draw()
|
||||
{
|
||||
S3L_zBufferClear();
|
||||
S3L_newFrame();
|
||||
|
||||
offScreenPixels = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue