mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-23 20:59:58 +01:00
Add z-buffer
This commit is contained in:
parent
c11cc70238
commit
4c4ced2d77
2 changed files with 60 additions and 99 deletions
92
s3l.h
92
s3l.h
|
@ -125,31 +125,6 @@
|
|||
on. */
|
||||
#endif
|
||||
|
||||
#ifndef S3L_RENDER_STRATEGY
|
||||
#define S3L_RENDER_STRATEGY S3L_STRATEGY_Z_BUFFER /**< Strategy used for
|
||||
visibility
|
||||
determination -- see
|
||||
S3L_STRATEGY_*
|
||||
consts. */
|
||||
#endif
|
||||
|
||||
#define S3L_STRATEGY_NONE 0 /**< No strategy -- can be sufficient in
|
||||
some cases. */
|
||||
#define S3L_STRATEGY_Z_BUFFER 1 /**< Use z-buffer (depth buffer).
|
||||
Accurate and fast, but requires a lot
|
||||
of memory. */
|
||||
#define S3L_STRATEGY_BACK_TO_FRONT 2 /**< Sort and draw triangles from back to
|
||||
front (painter's algorithm). Requires
|
||||
less memory, but can be slower than
|
||||
Z-buffer and can't handle
|
||||
intersecting triangles. */
|
||||
#define S3L_STRATEGY_FRONT_TO_BACK 3 /**< Sort and draw triangles from front to
|
||||
back (reverse painter's algorithm).
|
||||
Requires a bit more memory than back
|
||||
to front, but can also be faster
|
||||
(doesn't draw over already drawn
|
||||
pixels). */
|
||||
|
||||
#ifndef S3L_MAX_TRIANGES_DRAWN
|
||||
#define S3L_MAX_TRIANGES_DRAWN 128 /**< Maximum number of triangles that can
|
||||
be drawn in sorted modes. This
|
||||
|
@ -188,6 +163,20 @@ typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
|
|||
typedef int16_t S3L_ScreenCoord;
|
||||
typedef uint16_t S3L_Index;
|
||||
|
||||
#ifndef S3L_USE_Z_BUFFER
|
||||
#define S3L_USE_Z_BUFFER 1 /**< Whether to use z-buffer (depth buffer) for
|
||||
visibility determination. This is accurate
|
||||
and can be fast, but requires a lot of
|
||||
memory. */
|
||||
#endif
|
||||
|
||||
#define S3L_MAX_DEPTH 2147483647
|
||||
|
||||
#if S3L_USE_Z_BUFFER
|
||||
#define S3L_COMPUTE_DEPTH 1
|
||||
S3L_Unit S3L_zBuffer[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
|
||||
#endif
|
||||
|
||||
#ifndef S3L_NEAR
|
||||
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 4) /**< Distance of the near
|
||||
clipping plane. */
|
||||
|
@ -492,6 +481,8 @@ void S3L_drawTriangle(
|
|||
const S3L_Camera *camera,
|
||||
S3L_Index triangleID);
|
||||
|
||||
void S3L_zBufferClear();
|
||||
|
||||
static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle);
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1149,6 +1140,30 @@ 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)
|
||||
{
|
||||
uint32_t index = y * S3L_RESOLUTION_X + x;
|
||||
|
||||
if (depth < S3L_zBuffer[index])
|
||||
{
|
||||
S3L_zBuffer[index] = depth;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void S3L_zBufferClear()
|
||||
{
|
||||
#if S3L_USE_Z_BUFFER
|
||||
for (uint32_t i = 0; i < S3L_RESOLUTION_X * S3L_RESOLUTION_Y; ++i)
|
||||
S3L_zBuffer[i] = S3L_MAX_DEPTH;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _S3L_drawFilledTriangle(
|
||||
S3L_Vec4 point0,
|
||||
S3L_Vec4 point1,
|
||||
|
@ -1464,37 +1479,44 @@ void _S3L_drawFilledTriangle(
|
|||
|
||||
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||
{
|
||||
p->x = x;
|
||||
|
||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||
S3L_Unit rowT =
|
||||
S3L_correctPerspective(S3L_interpolateFrom0(S3L_FRACTIONS_PER_UNIT,
|
||||
x - lX,rowLength),&rowPC);
|
||||
#endif
|
||||
|
||||
#if S3L_COMPUTE_DEPTH
|
||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||
p->depth = S3L_interpolateByUnit(lDepth,rDepth,rowT);
|
||||
#else
|
||||
p->depth = S3L_getFastLerpValue(depthFLS);
|
||||
S3L_stepFastLerp(depthFLS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if S3L_USE_Z_BUFFER
|
||||
if (!S3L_zTest(p->x,p->y,p->depth))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||
*barycentric0 =
|
||||
S3L_interpolateByUnitFrom0(rT,rowT);
|
||||
|
||||
*barycentric1 =
|
||||
S3L_interpolateByUnitFrom0(lT,S3L_FRACTIONS_PER_UNIT - rowT);
|
||||
|
||||
#if S3L_COMPUTE_DEPTH
|
||||
p->depth = S3L_interpolateByUnit(lDepth,rDepth,rowT);
|
||||
#endif
|
||||
#else
|
||||
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
||||
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
||||
|
||||
S3L_stepFastLerp(b0FLS);
|
||||
S3L_stepFastLerp(b1FLS);
|
||||
|
||||
#if S3L_COMPUTE_LERP_DEPTH
|
||||
p->depth = S3L_getFastLerpValue(depthFLS);
|
||||
S3L_stepFastLerp(depthFLS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
||||
|
||||
p->x = x;
|
||||
S3L_PIXEL_FUNCTION(p);
|
||||
}
|
||||
} // y clipping
|
||||
|
|
67
testSDL.c
67
testSDL.c
|
@ -7,6 +7,8 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define S3L_USE_Z_BUFFER 1
|
||||
|
||||
#define S3L_PIXEL_FUNCTION drawPixel
|
||||
|
||||
#define S3L_RESOLUTION_X 640
|
||||
|
@ -134,17 +136,7 @@ S3L_DrawConfig conf;
|
|||
|
||||
void draw()
|
||||
{
|
||||
/*
|
||||
if (frame % 128 == 0)
|
||||
{
|
||||
printf("frame: %d\n",frame);
|
||||
printf("scene.camera:\n");
|
||||
printf(" translation: ");
|
||||
S3L_writeVec4(scene.camera.transform.translation);
|
||||
printf(" rotation: ");
|
||||
S3L_writeVec4(scene.camera.transform.rotation);
|
||||
}
|
||||
*/
|
||||
S3L_zBufferClear();
|
||||
|
||||
offScreenPixels = 0;
|
||||
|
||||
|
@ -155,63 +147,10 @@ void draw()
|
|||
scene.models[0].transform.rotation.z = f * 0.1;
|
||||
scene.models[0].transform.rotation.x = f * 0.3;
|
||||
|
||||
// modelTransform.translation.x = sin(f >> 7) * 700;
|
||||
// modelTransform.translation.y = sin(f >> 8) * 600;
|
||||
|
||||
/*
|
||||
S3L_drawModelIndexed(ver,tri,12,modelTransform,&scene.camera,&conf);
|
||||
|
||||
modelTransform.translation.x += 2 * S3L_FRACTIONS_PER_UNIT;
|
||||
S3L_drawModelIndexed(ver,tri,12,modelTransform,&scene.camera,&conf);
|
||||
modelTransform.translation.x -= 2 * S3L_FRACTIONS_PER_UNIT;
|
||||
*/
|
||||
|
||||
S3L_drawScene(scene);
|
||||
|
||||
if (offScreenPixels > 0)
|
||||
printf("offscreen pixels: %d\n",offScreenPixels);
|
||||
|
||||
// S3L_drawModelIndexed(ver,tri,1,modelTransform,&scene.camera,&conf);
|
||||
|
||||
/*
|
||||
conf.backfaceCulling = S3L_BACKFACE_CULLING_NONE;
|
||||
conf.mode = S3L_MODE_TRIANGLES;
|
||||
|
||||
for (int c = 0; c < 8; ++c)
|
||||
{
|
||||
int
|
||||
x0 = test_coords[6 * c],
|
||||
y0 = test_coords[6 * c + 1],
|
||||
x1 = test_coords[6 * c + 2],
|
||||
y1 = test_coords[6 * c + 3],
|
||||
x2 = test_coords[6 * c + 4],
|
||||
y2 = test_coords[6 * c + 5];
|
||||
|
||||
int cent = (x0 + x1 + x2) / 3.0;
|
||||
x2 = cent + (x2 - cent) * sin(frame * 0.001) * 2;
|
||||
//x2 = cent + (x2 - cent) * sin(600 * 0.001) * 2;
|
||||
|
||||
S3L_drawTriangle(x0,y0,x1,y1,x2,y2,conf,0);
|
||||
|
||||
setPixel(x0,y0,255,0,0);
|
||||
setPixel(x1,y1,255,0,0);
|
||||
setPixel(x2,y2,255,0,0);
|
||||
|
||||
}
|
||||
|
||||
float rotRate = 0.002;
|
||||
|
||||
int16_t rotX0 = 200 + sin(frame * rotRate) * 100;
|
||||
int16_t rotY0 = 200 + cos(frame * rotRate) * 100;
|
||||
|
||||
int16_t rotX1 = 200 + sin((frame + 1500) * rotRate) * 100;
|
||||
int16_t rotY1 = 200 + cos((frame + 1500) * rotRate) * 100;
|
||||
|
||||
int16_t rotX2 = 200 + sin((frame + 500) * rotRate) * 100;
|
||||
int16_t rotY2 = 200 + cos((frame + 500) * rotRate) * 100;
|
||||
|
||||
S3L_drawTriangle(rotX0,rotY0,rotX1,rotY1,rotX2,rotY2,conf,0);
|
||||
*/
|
||||
}
|
||||
|
||||
int main()
|
||||
|
|
Loading…
Reference in a new issue