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

Add byte z-buffer

This commit is contained in:
Miloslav Číž 2019-05-22 19:34:07 +02:00
parent 4c4ced2d77
commit 7fff6fc9bb
2 changed files with 44 additions and 16 deletions

48
s3l.h
View file

@ -163,18 +163,36 @@ typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
typedef int16_t S3L_ScreenCoord; typedef int16_t S3L_ScreenCoord;
typedef uint16_t S3L_Index; typedef uint16_t S3L_Index;
#ifndef S3L_USE_Z_BUFFER #define S3L_Z_BUFFER_NONE 0 /**< Don't use z-buffer. This saves a lot of
#define S3L_USE_Z_BUFFER 1 /**< Whether to use z-buffer (depth buffer) for memory, but visibility checking won't be
visibility determination. This is accurate pixel-accurate and has to mostly be done by
and can be fast, but requires a lot of other means (typically sorting). */
memory. */ #define S3L_Z_BUFFER_FULL 1 /**< Use full z-buffer (of S3L_Units) for
visibiltiy determination. This is the most
accurate option (and also a fast one), but
requires a big amount of memory. */
#define S3L_Z_BUFFER_BYTE 2 /**< Use reduced-size z-buffer (of bytes). This is
fast and somewhat accurate, but inaccuracies
can occur and a considerable amount of memory
is needed. */
#ifndef S3L_Z_BUFFER
#define S3L_Z_BUFFER S3L_Z_BUFFER_NONE /**< What type of z-buffer (depth
buffer) to use for visibility
determination. See
S3L_Z_BUFFER_*. */
#endif #endif
#define S3L_MAX_DEPTH 2147483647 #if S3L_Z_BUFFER == S3L_Z_BUFFER_FULL
#if S3L_USE_Z_BUFFER
#define S3L_COMPUTE_DEPTH 1 #define S3L_COMPUTE_DEPTH 1
#define S3L_MAX_DEPTH 2147483647
S3L_Unit S3L_zBuffer[S3L_RESOLUTION_X * S3L_RESOLUTION_Y]; S3L_Unit S3L_zBuffer[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
#define S3L_zBufferFormat(depth) (depth)
#elif S3L_Z_BUFFER == S3L_Z_BUFFER_BYTE
#define S3L_COMPUTE_DEPTH 1
#define S3L_MAX_DEPTH 255
uint8_t S3L_zBuffer[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
#define S3L_zBufferFormat(depth) (((depth) >> 5) & 0x000000FF)
#endif #endif
#ifndef S3L_NEAR #ifndef S3L_NEAR
@ -479,6 +497,7 @@ void S3L_drawTriangle(
S3L_Vec4 point2, S3L_Vec4 point2,
const S3L_DrawConfig *config, const S3L_DrawConfig *config,
const S3L_Camera *camera, const S3L_Camera *camera,
S3L_Index modelID,
S3L_Index triangleID); S3L_Index triangleID);
void S3L_zBufferClear(); void S3L_zBufferClear();
@ -1145,8 +1164,11 @@ static inline int8_t S3L_zTest(
S3L_ScreenCoord y, S3L_ScreenCoord y,
S3L_Unit depth) S3L_Unit depth)
{ {
#if S3L_Z_BUFFER
uint32_t index = y * S3L_RESOLUTION_X + x; uint32_t index = y * S3L_RESOLUTION_X + x;
depth = S3L_zBufferFormat(depth);
if (depth < S3L_zBuffer[index]) if (depth < S3L_zBuffer[index])
{ {
S3L_zBuffer[index] = depth; S3L_zBuffer[index] = depth;
@ -1154,11 +1176,12 @@ static inline int8_t S3L_zTest(
} }
return 0; return 0;
#endif
} }
void S3L_zBufferClear() void S3L_zBufferClear()
{ {
#if S3L_USE_Z_BUFFER #if S3L_Z_BUFFER
for (uint32_t i = 0; i < S3L_RESOLUTION_X * S3L_RESOLUTION_Y; ++i) for (uint32_t i = 0; i < S3L_RESOLUTION_X * S3L_RESOLUTION_Y; ++i)
S3L_zBuffer[i] = S3L_MAX_DEPTH; S3L_zBuffer[i] = S3L_MAX_DEPTH;
#endif #endif
@ -1496,7 +1519,7 @@ void _S3L_drawFilledTriangle(
#endif #endif
#endif #endif
#if S3L_USE_Z_BUFFER #if S3L_Z_BUFFER
if (!S3L_zTest(p->x,p->y,p->depth)) if (!S3L_zTest(p->x,p->y,p->depth))
continue; continue;
#endif #endif
@ -1544,6 +1567,7 @@ void S3L_drawTriangle(
S3L_Vec4 point2, S3L_Vec4 point2,
const S3L_DrawConfig *config, const S3L_DrawConfig *config,
const S3L_Camera *camera, const S3L_Camera *camera,
S3L_Index modelID,
S3L_Index triangleID) S3L_Index triangleID)
{ {
#define clipTest(c,cmp,v)\ #define clipTest(c,cmp,v)\
@ -1574,6 +1598,7 @@ void S3L_drawTriangle(
S3L_PixelInfo p; S3L_PixelInfo p;
S3L_initPixelInfo(&p); S3L_initPixelInfo(&p);
p.modelID = modelID;
p.triangleID = triangleID; p.triangleID = triangleID;
if (config->mode == S3L_MODE_TRIANGLES) // triangle mode if (config->mode == S3L_MODE_TRIANGLES) // triangle mode
@ -1780,7 +1805,8 @@ void S3L_drawScene(S3L_Scene scene)
#undef project #undef project
S3L_drawTriangle(transformed0,transformed1,transformed2, S3L_drawTriangle(transformed0,transformed1,transformed2,
&(scene.models[modelIndex].config),&(scene.camera),triangleIndex); &(scene.models[modelIndex].config),&(scene.camera),modelIndex,
triangleIndex);
++triangleIndex; ++triangleIndex;
} }

View file

@ -7,7 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#define S3L_USE_Z_BUFFER 1 #define S3L_Z_BUFFER S3L_Z_BUFFER_BYTE
#define S3L_PIXEL_FUNCTION drawPixel #define S3L_PIXEL_FUNCTION drawPixel
@ -126,7 +126,9 @@ void drawPixel(S3L_PixelInfo *p)
uint8_t sss = (p->depth / 5000.0) * 255 ; uint8_t sss = (p->depth / 5000.0) * 255 ;
setPixel(p->x,p->y,sss,sss,sss); //setPixel(p->x,p->y,sss,sss,sss);
setPixel(p->x,p->y,p->modelID * 64,p->modelID * 128,255);
// setPixel(p->x,p->y,p->barycentric0 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,p->barycentric1 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,p->barycentric2 / ((float) S3L_FRACTIONS_PER_UNIT) * 255); // setPixel(p->x,p->y,p->barycentric0 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,p->barycentric1 / ((float) S3L_FRACTIONS_PER_UNIT) * 255,p->barycentric2 / ((float) S3L_FRACTIONS_PER_UNIT) * 255);
} }
@ -176,7 +178,7 @@ int main()
scene.models[0].transform.translation.x = S3L_FRACTIONS_PER_UNIT; scene.models[0].transform.translation.x = S3L_FRACTIONS_PER_UNIT;
scene.models[1] = scene.models[0]; scene.models[1] = scene.models[0];
scene.models[1].transform.translation.x = -1 * S3L_FRACTIONS_PER_UNIT; scene.models[1].transform.translation.x = 0.5 * S3L_FRACTIONS_PER_UNIT;
// scene.camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT; // scene.camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT;
// scene.camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT; // scene.camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT;