1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/small3dlib.git synced 2024-12-22 01:26:17 +01:00

Move early clipping to scene draw

This commit is contained in:
Miloslav Číž 2019-05-23 15:24:43 +02:00
parent 7fff6fc9bb
commit a281af0ef6
2 changed files with 50 additions and 32 deletions

76
s3l.h
View file

@ -1570,32 +1570,6 @@ void S3L_drawTriangle(
S3L_Index modelID,
S3L_Index triangleID)
{
#define clipTest(c,cmp,v)\
(point0.c cmp (v) && point1.c cmp (v) && point2.c cmp (v))
if ( // early clipping -- test if completely outside frustum
clipTest(z,<=,S3L_NEAR) ||
clipTest(x,<,-1 * S3L_FRACTIONS_PER_UNIT) ||
clipTest(x,>,S3L_FRACTIONS_PER_UNIT) ||
clipTest(y,<,-1 * S3L_PROJECTION_PLANE_HEIGHT / 2) ||
clipTest(y,>,S3L_PROJECTION_PLANE_HEIGHT / 2)
)
return; // completely behind the camera
if (config->backfaceCulling != S3L_BACKFACE_CULLING_NONE)
{
int32_t winding = // determines CW or CCW
(
(point1.y - point0.y) * (point2.x - point1.x) -
(point1.x - point0.x) * (point2.y - point1.y)
);
if ((config->backfaceCulling == S3L_BACKFACE_CULLING_CW && winding < 0) ||
(config->backfaceCulling == S3L_BACKFACE_CULLING_CCW && winding >= 0))
return;
}
S3L_PixelInfo p;
S3L_initPixelInfo(&p);
p.modelID = modelID;
@ -1754,6 +1728,45 @@ static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
vector->y = (vector->y * focalLength) / divisor;
}
/**
Checks if given triangle (in Projection Plane space) is at least partially
visible, i.e. returns false if the triangle is either completely outside
the frustum (left, right, top, bottom, near) or is invisible due to
backface culling.
*/
static inline int8_t S3L_triangleIsVisible(
S3L_Vec4 p0,
S3L_Vec4 p1,
S3L_Vec4 p2,
uint8_t backfaceCulling)
{
#define clipTest(c,cmp,v)\
(p0.c cmp (v) && p1.c cmp (v) && p2.c cmp (v))
if ( // completely outside frustum?
clipTest(z,<=,S3L_NEAR) ||
clipTest(x,<,-1 * S3L_FRACTIONS_PER_UNIT) ||
clipTest(x,>,S3L_FRACTIONS_PER_UNIT) ||
clipTest(y,<,-1 * S3L_PROJECTION_PLANE_HEIGHT / 2) ||
clipTest(y,>,S3L_PROJECTION_PLANE_HEIGHT / 2)
)
return 0;
#undef clipTest
if (backfaceCulling != S3L_BACKFACE_CULLING_NONE)
{
int32_t winding = // determines CW or CCW
(p1.y - p0.y) * (p2.x - p1.x) - (p1.x - p0.x) * (p2.y - p1.y);
if ((backfaceCulling == S3L_BACKFACE_CULLING_CW && winding < 0) ||
(backfaceCulling == S3L_BACKFACE_CULLING_CCW && winding >= 0))
return 0;
}
return 1;
}
void S3L_drawScene(S3L_Scene scene)
{
for (S3L_Index modelIndex; modelIndex < scene.modelCount; ++modelIndex)
@ -1804,9 +1817,14 @@ void S3L_drawScene(S3L_Scene scene)
#undef project
S3L_drawTriangle(transformed0,transformed1,transformed2,
&(scene.models[modelIndex].config),&(scene.camera),modelIndex,
triangleIndex);
S3L_DrawConfig *config = &(scene.models[modelIndex].config);
if (S3L_triangleIsVisible(transformed0,transformed1,transformed2,
config->backfaceCulling))
{
S3L_drawTriangle(transformed0,transformed1,transformed2,config,
&(scene.camera),modelIndex,triangleIndex);
}
++triangleIndex;
}

View file

@ -7,7 +7,7 @@
#include <stdio.h>
#include <math.h>
#define S3L_Z_BUFFER S3L_Z_BUFFER_BYTE
#define S3L_Z_BUFFER S3L_Z_BUFFER_FULL
#define S3L_PIXEL_FUNCTION drawPixel
@ -122,13 +122,13 @@ void drawPixel(S3L_PixelInfo *p)
uint8_t col = texturePixel(u,v);
// setPixel(p->x,p->y,col * 120,20,(2 - col) * 120);
setPixel(p->x,p->y,col * 120,20,(2 - col) * 120);
uint8_t sss = (p->depth / 5000.0) * 255 ;
//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->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);
}