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

Replace drawModel with drawScene

This commit is contained in:
Miloslav Číž 2019-05-21 21:28:16 +02:00
parent ae985635fd
commit c11cc70238
2 changed files with 158 additions and 81 deletions

108
s3l.h
View file

@ -125,6 +125,38 @@
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
#define S3L_MAX_TRIANGES_DRAWN 128 /**< Maximum number of triangles that can
be drawn in sorted modes. This
affects the size of a cache used for
triangle sorting. */
#endif
#ifndef S3L_PERSPECTIVE_CORRECTION #ifndef S3L_PERSPECTIVE_CORRECTION
#define S3L_PERSPECTIVE_CORRECTION 0 /**< Specifies what type of perspective #define S3L_PERSPECTIVE_CORRECTION 0 /**< Specifies what type of perspective
correction (PC) to use. Remember correction (PC) to use. Remember
@ -198,6 +230,8 @@ typedef uint16_t S3L_Index;
/* 7 back, top, left */\ /* 7 back, top, left */\
-S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2 -S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2
#define S3L_CUBE_VERTEX_COUNT 8
/** Predefined triangle indices of a cube, to be used with S3L_CUBE_VERTICES /** Predefined triangle indices of a cube, to be used with S3L_CUBE_VERTICES
and S3L_CUBE_TEXCOORDS. */ and S3L_CUBE_TEXCOORDS. */
#define S3L_CUBE_TRIANGLES\ #define S3L_CUBE_TRIANGLES\
@ -214,6 +248,8 @@ typedef uint16_t S3L_Index;
4, 1, 0, /* bottom */\ 4, 1, 0, /* bottom */\
4, 5, 1 4, 5, 1
#define S3L_CUBE_TRIANGLE_COUNT 12
/** Predefined texture coordinates of a cube, corresponding to triangles (NOT /** Predefined texture coordinates of a cube, corresponding to triangles (NOT
vertices), to be used with S3L_CUBE_VERTICES and S3L_CUBE_TRIANGLES. */ vertices), to be used with S3L_CUBE_VERTICES and S3L_CUBE_TRIANGLES. */
#define S3L_CUBE_TEXCOORDS(m)\ #define S3L_CUBE_TEXCOORDS(m)\
@ -338,6 +374,31 @@ typedef struct
static inline void S3L_initCamera(S3L_Camera *c); static inline void S3L_initCamera(S3L_Camera *c);
typedef struct
{
uint8_t backfaceCulling;
uint8_t mode;
} S3L_DrawConfig;
void S3L_initDrawConfig(S3L_DrawConfig *config);
typedef struct
{
S3L_Unit *vertices;
S3L_Index vertexCount;
S3L_Index *triangles;
S3L_Index triangleCount;
S3L_Transform3D transform;
S3L_DrawConfig config;
} S3L_Model3D; ///< Represents a 3D model.
typedef struct
{
S3L_Model3D *models;
S3L_Index modelCount;
S3L_Camera camera;
} S3L_Scene; ///< Represent the 3D scene to be rendered.
typedef struct typedef struct
{ {
S3L_ScreenCoord x; ///< Screen X coordinate. S3L_ScreenCoord x; ///< Screen X coordinate.
@ -351,7 +412,8 @@ typedef struct
S3L_FRACTIONS_PER_UNIT. */ S3L_FRACTIONS_PER_UNIT. */
S3L_Unit barycentric1; ///< Baryc. coord 1 (corresponds to 2nd vertex). S3L_Unit barycentric1; ///< Baryc. coord 1 (corresponds to 2nd vertex).
S3L_Unit barycentric2; ///< Baryc. coord 2 (corresponds to 3rd vertex). S3L_Unit barycentric2; ///< Baryc. coord 2 (corresponds to 3rd vertex).
S3L_Index triangleID; S3L_Index triangleID; ///< Triangle index.
S3L_Index modelID;
S3L_Unit depth; ///< Depth (only if depth is turned on). S3L_Unit depth; ///< Depth (only if depth is turned on).
} S3L_PixelInfo; /**< Used to pass the info about a rasterized pixel } S3L_PixelInfo; /**< Used to pass the info about a rasterized pixel
(fragment) to the user-defined drawing func. */ (fragment) to the user-defined drawing func. */
@ -366,14 +428,6 @@ static inline void S3L_initPixelInfo(S3L_PixelInfo *p);
#define S3L_MODE_LINES 1 #define S3L_MODE_LINES 1
#define S3L_MODE_POINTS 2 #define S3L_MODE_POINTS 2
typedef struct
{
uint8_t backfaceCulling;
uint8_t mode;
} S3L_DrawConfig;
void S3L_initDrawConfig(S3L_DrawConfig *config);
// general helper functions // general helper functions
static inline S3L_Unit S3L_abs(S3L_Unit value); static inline S3L_Unit S3L_abs(S3L_Unit value);
static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2); static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2);
@ -1653,14 +1707,13 @@ static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
vector->y = (vector->y * focalLength) / divisor; vector->y = (vector->y * focalLength) / divisor;
} }
void S3L_drawModelIndexed( void S3L_drawScene(S3L_Scene scene)
const S3L_Unit coords[],
const S3L_Index triangleVertexIndices[],
uint16_t triangleCount,
S3L_Transform3D modelTransform,
const S3L_Camera *camera,
const S3L_DrawConfig *config)
{ {
for (S3L_Index modelIndex; modelIndex < scene.modelCount; ++modelIndex)
{
S3L_Unit *vertices = scene.models[modelIndex].vertices;
S3L_Index *triangles = scene.models[modelIndex].triangles;
S3L_Index triangleIndex = 0; S3L_Index triangleIndex = 0;
S3L_Index coordIndex = 0; S3L_Index coordIndex = 0;
@ -1671,27 +1724,29 @@ void S3L_drawModelIndexed(
S3L_Mat4 mat1, mat2; S3L_Mat4 mat1, mat2;
S3L_makeWorldMatrix(modelTransform,&mat1); S3L_makeWorldMatrix(scene.models[modelIndex].transform,&mat1);
S3L_makeCameraMatrix(camera->transform,&mat2); S3L_makeCameraMatrix(scene.camera.transform,&mat2);
S3L_mat4Xmat4(&mat1,&mat2); S3L_mat4Xmat4(&mat1,&mat2);
S3L_Index triangleCount = scene.models[modelIndex].triangleCount;
while (triangleIndex < triangleCount) while (triangleIndex < triangleCount)
{ {
#define project(n)\ #define project(n)\
indexIndex = triangleVertexIndices[coordIndex] * 3;\ indexIndex = triangles[coordIndex] * 3;\
pointModel.x = coords[indexIndex];\ pointModel.x = vertices[indexIndex];\
++indexIndex; /* TODO: put into square brackets? */\ ++indexIndex; /* TODO: put into square brackets? */\
pointModel.y = coords[indexIndex];\ pointModel.y = vertices[indexIndex];\
++indexIndex;\ ++indexIndex;\
pointModel.z = coords[indexIndex];\ pointModel.z = vertices[indexIndex];\
++coordIndex;\ ++coordIndex;\
S3L_vec3Xmat4(&pointModel,&mat1);\ S3L_vec3Xmat4(&pointModel,&mat1);\
transformed##n.x = pointModel.x;\ transformed##n.x = pointModel.x;\
transformed##n.y = pointModel.y;\ transformed##n.y = pointModel.y;\
transformed##n.z = pointModel.z;\ transformed##n.z = pointModel.z;\
transformed##n.w = S3L_FRACTIONS_PER_UNIT;\ transformed##n.w = S3L_FRACTIONS_PER_UNIT;\
S3L_perspectiveDivide(&transformed##n,camera->focalLength); S3L_perspectiveDivide(&transformed##n,scene.camera.focalLength);
/* TODO: maybe create an option that would use a cache here to not /* TODO: maybe create an option that would use a cache here to not
transform the same point twice? */ transform the same point twice? */
@ -1700,11 +1755,14 @@ void S3L_drawModelIndexed(
project(1) project(1)
project(2) project(2)
S3L_drawTriangle(transformed0,transformed1,transformed2,config,camera, #undef project
triangleIndex);
S3L_drawTriangle(transformed0,transformed1,transformed2,
&(scene.models[modelIndex].config),&(scene.camera),triangleIndex);
++triangleIndex; ++triangleIndex;
} }
} }
}
#endif #endif

View file

@ -35,6 +35,9 @@ const S3L_Unit ver[] = { S3L_CUBE_VERTICES };
const S3L_Index tri[] = { S3L_CUBE_TRIANGLES }; const S3L_Index tri[] = { S3L_CUBE_TRIANGLES };
const S3L_Unit tex_coords[] = { S3L_CUBE_TEXCOORDS(16) }; const S3L_Unit tex_coords[] = { S3L_CUBE_TEXCOORDS(16) };
S3L_Model3D models[2];
S3L_Scene scene;
int8_t keys[256]; int8_t keys[256];
const uint8_t testTexture[] = const uint8_t testTexture[] =
@ -126,7 +129,6 @@ setPixel(p->x,p->y,sss,sss,sss);
// 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);
} }
S3L_Camera camera;
S3L_Transform3D modelTransform; S3L_Transform3D modelTransform;
S3L_DrawConfig conf; S3L_DrawConfig conf;
@ -136,11 +138,11 @@ void draw()
if (frame % 128 == 0) if (frame % 128 == 0)
{ {
printf("frame: %d\n",frame); printf("frame: %d\n",frame);
printf("camera:\n"); printf("scene.camera:\n");
printf(" translation: "); printf(" translation: ");
S3L_writeVec4(camera.transform.translation); S3L_writeVec4(scene.camera.transform.translation);
printf(" rotation: "); printf(" rotation: ");
S3L_writeVec4(camera.transform.rotation); S3L_writeVec4(scene.camera.transform.rotation);
} }
*/ */
@ -150,22 +152,26 @@ void draw()
uint32_t f = frame; uint32_t f = frame;
modelTransform.rotation.z = f * 0.1; scene.models[0].transform.rotation.z = f * 0.1;
modelTransform.rotation.x = f * 0.3; scene.models[0].transform.rotation.x = f * 0.3;
// modelTransform.translation.x = sin(f >> 7) * 700; // modelTransform.translation.x = sin(f >> 7) * 700;
// modelTransform.translation.y = sin(f >> 8) * 600; // modelTransform.translation.y = sin(f >> 8) * 600;
S3L_drawModelIndexed(ver,tri,12,modelTransform,&camera,&conf); /*
S3L_drawModelIndexed(ver,tri,12,modelTransform,&scene.camera,&conf);
modelTransform.translation.x += 2 * S3L_FRACTIONS_PER_UNIT; modelTransform.translation.x += 2 * S3L_FRACTIONS_PER_UNIT;
S3L_drawModelIndexed(ver,tri,12,modelTransform,&camera,&conf); S3L_drawModelIndexed(ver,tri,12,modelTransform,&scene.camera,&conf);
modelTransform.translation.x -= 2 * S3L_FRACTIONS_PER_UNIT; modelTransform.translation.x -= 2 * S3L_FRACTIONS_PER_UNIT;
*/
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,&camera,&conf); // S3L_drawModelIndexed(ver,tri,1,modelTransform,&scene.camera,&conf);
/* /*
conf.backfaceCulling = S3L_BACKFACE_CULLING_NONE; conf.backfaceCulling = S3L_BACKFACE_CULLING_NONE;
@ -216,12 +222,25 @@ int main()
SDL_Surface *screenSurface = SDL_GetWindowSurface(window); SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
SDL_Event event; SDL_Event event;
S3L_initCamera(&camera); S3L_initCamera(&scene.camera);
camera.transform.translation.z = -S3L_FRACTIONS_PER_UNIT * 2; scene.camera.transform.translation.z = -S3L_FRACTIONS_PER_UNIT * 2;
scene.modelCount = 2;
scene.models = &models;
// camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT; scene.models[0].vertices = ver;
// camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT; scene.models[0].vertexCount = S3L_CUBE_VERTEX_COUNT;
scene.models[0].triangles = tri;
scene.models[0].triangleCount = S3L_CUBE_TRIANGLE_COUNT;
S3L_initTransoform3D(&(scene.models[0].transform));
S3L_initDrawConfig(&(scene.models[0].config));
scene.models[0].transform.translation.x = S3L_FRACTIONS_PER_UNIT;
scene.models[1] = scene.models[0];
scene.models[1].transform.translation.x = -1 * S3L_FRACTIONS_PER_UNIT;
// scene.camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT;
// scene.camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT;
S3L_initTransoform3D(&modelTransform); S3L_initTransoform3D(&modelTransform);
S3L_initDrawConfig(&conf); S3L_initDrawConfig(&conf);
@ -261,47 +280,47 @@ int main()
int step = 10; int step = 10;
S3L_rotationToDirections( S3L_rotationToDirections(
camera.transform.rotation, scene.camera.transform.rotation,
step, step,
&camF, &camF,
&camR, &camR,
&camU); &camU);
if (keys['w']) if (keys['w'])
S3L_vec3Add(&camera.transform.translation,camF); S3L_vec3Add(&scene.camera.transform.translation,camF);
if (keys['s']) if (keys['s'])
S3L_vec3Sub(&camera.transform.translation,camF); S3L_vec3Sub(&scene.camera.transform.translation,camF);
if (keys['d']) if (keys['d'])
S3L_vec3Add(&camera.transform.translation,camR); S3L_vec3Add(&scene.camera.transform.translation,camR);
if (keys['a']) if (keys['a'])
S3L_vec3Sub(&camera.transform.translation,camR); S3L_vec3Sub(&scene.camera.transform.translation,camR);
if (keys['c']) if (keys['c'])
S3L_vec3Add(&camera.transform.translation,camU); S3L_vec3Add(&scene.camera.transform.translation,camU);
if (keys['x']) if (keys['x'])
S3L_vec3Sub(&camera.transform.translation,camU); S3L_vec3Sub(&scene.camera.transform.translation,camU);
if (keys['q']) if (keys['q'])
camera.transform.rotation.y -= 1; scene.camera.transform.rotation.y -= 1;
if (keys['e']) if (keys['e'])
camera.transform.rotation.y += 1; scene.camera.transform.rotation.y += 1;
if (keys['r']) if (keys['r'])
camera.transform.rotation.x -= 1; scene.camera.transform.rotation.x -= 1;
if (keys['t']) if (keys['t'])
camera.transform.rotation.x += 1; scene.camera.transform.rotation.x += 1;
if (keys['f']) if (keys['f'])
camera.transform.rotation.z -= 1; scene.camera.transform.rotation.z -= 1;
if (keys['g']) if (keys['g'])
camera.transform.rotation.z += 1; scene.camera.transform.rotation.z += 1;
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
SDL_RenderCopy(renderer,texture,NULL,NULL); SDL_RenderCopy(renderer,texture,NULL,NULL);