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. */
|
on. */
|
||||||
#endif
|
#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
|
#ifndef S3L_MAX_TRIANGES_DRAWN
|
||||||
#define S3L_MAX_TRIANGES_DRAWN 128 /**< Maximum number of triangles that can
|
#define S3L_MAX_TRIANGES_DRAWN 128 /**< Maximum number of triangles that can
|
||||||
be drawn in sorted modes. This
|
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 int16_t S3L_ScreenCoord;
|
||||||
typedef uint16_t S3L_Index;
|
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
|
#ifndef S3L_NEAR
|
||||||
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 4) /**< Distance of the near
|
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 4) /**< Distance of the near
|
||||||
clipping plane. */
|
clipping plane. */
|
||||||
|
@ -492,6 +481,8 @@ void S3L_drawTriangle(
|
||||||
const S3L_Camera *camera,
|
const S3L_Camera *camera,
|
||||||
S3L_Index triangleID);
|
S3L_Index triangleID);
|
||||||
|
|
||||||
|
void S3L_zBufferClear();
|
||||||
|
|
||||||
static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle);
|
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;
|
(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(
|
void _S3L_drawFilledTriangle(
|
||||||
S3L_Vec4 point0,
|
S3L_Vec4 point0,
|
||||||
S3L_Vec4 point1,
|
S3L_Vec4 point1,
|
||||||
|
@ -1464,37 +1479,44 @@ void _S3L_drawFilledTriangle(
|
||||||
|
|
||||||
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
for (S3L_ScreenCoord x = lXClipped; x < rXClipped; ++x)
|
||||||
{
|
{
|
||||||
|
p->x = x;
|
||||||
|
|
||||||
#if S3L_PERSPECTIVE_CORRECTION == 1
|
#if S3L_PERSPECTIVE_CORRECTION == 1
|
||||||
S3L_Unit rowT =
|
S3L_Unit rowT =
|
||||||
S3L_correctPerspective(S3L_interpolateFrom0(S3L_FRACTIONS_PER_UNIT,
|
S3L_correctPerspective(S3L_interpolateFrom0(S3L_FRACTIONS_PER_UNIT,
|
||||||
x - lX,rowLength),&rowPC);
|
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 =
|
*barycentric0 =
|
||||||
S3L_interpolateByUnitFrom0(rT,rowT);
|
S3L_interpolateByUnitFrom0(rT,rowT);
|
||||||
|
|
||||||
*barycentric1 =
|
*barycentric1 =
|
||||||
S3L_interpolateByUnitFrom0(lT,S3L_FRACTIONS_PER_UNIT - rowT);
|
S3L_interpolateByUnitFrom0(lT,S3L_FRACTIONS_PER_UNIT - rowT);
|
||||||
|
|
||||||
#if S3L_COMPUTE_DEPTH
|
|
||||||
p->depth = S3L_interpolateByUnit(lDepth,rDepth,rowT);
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
*barycentric0 = S3L_getFastLerpValue(b0FLS);
|
||||||
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
*barycentric1 = S3L_getFastLerpValue(b1FLS);
|
||||||
|
|
||||||
S3L_stepFastLerp(b0FLS);
|
S3L_stepFastLerp(b0FLS);
|
||||||
S3L_stepFastLerp(b1FLS);
|
S3L_stepFastLerp(b1FLS);
|
||||||
|
|
||||||
#if S3L_COMPUTE_LERP_DEPTH
|
|
||||||
p->depth = S3L_getFastLerpValue(depthFLS);
|
|
||||||
S3L_stepFastLerp(depthFLS);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
*barycentric2 = S3L_FRACTIONS_PER_UNIT - *barycentric0 - *barycentric1;
|
||||||
|
|
||||||
p->x = x;
|
|
||||||
S3L_PIXEL_FUNCTION(p);
|
S3L_PIXEL_FUNCTION(p);
|
||||||
}
|
}
|
||||||
} // y clipping
|
} // y clipping
|
||||||
|
|
67
testSDL.c
67
testSDL.c
|
@ -7,6 +7,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#define S3L_USE_Z_BUFFER 1
|
||||||
|
|
||||||
#define S3L_PIXEL_FUNCTION drawPixel
|
#define S3L_PIXEL_FUNCTION drawPixel
|
||||||
|
|
||||||
#define S3L_RESOLUTION_X 640
|
#define S3L_RESOLUTION_X 640
|
||||||
|
@ -134,17 +136,7 @@ S3L_DrawConfig conf;
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
/*
|
S3L_zBufferClear();
|
||||||
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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
offScreenPixels = 0;
|
offScreenPixels = 0;
|
||||||
|
|
||||||
|
@ -155,63 +147,10 @@ void draw()
|
||||||
scene.models[0].transform.rotation.z = f * 0.1;
|
scene.models[0].transform.rotation.z = f * 0.1;
|
||||||
scene.models[0].transform.rotation.x = f * 0.3;
|
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);
|
S3L_drawScene(scene);
|
||||||
|
|
||||||
if (offScreenPixels > 0)
|
if (offScreenPixels > 0)
|
||||||
printf("offscreen pixels: %d\n",offScreenPixels);
|
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()
|
int main()
|
||||||
|
|
Loading…
Reference in a new issue