mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-20 20:29:58 +01:00
Replace drawModel with drawScene
This commit is contained in:
parent
ae985635fd
commit
c11cc70238
2 changed files with 158 additions and 81 deletions
168
s3l.h
168
s3l.h
|
@ -125,6 +125,38 @@
|
|||
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
|
||||
affects the size of a cache used for
|
||||
triangle sorting. */
|
||||
#endif
|
||||
|
||||
#ifndef S3L_PERSPECTIVE_CORRECTION
|
||||
#define S3L_PERSPECTIVE_CORRECTION 0 /**< Specifies what type of perspective
|
||||
correction (PC) to use. Remember
|
||||
|
@ -198,6 +230,8 @@ typedef uint16_t S3L_Index;
|
|||
/* 7 back, top, left */\
|
||||
-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
|
||||
and S3L_CUBE_TEXCOORDS. */
|
||||
#define S3L_CUBE_TRIANGLES\
|
||||
|
@ -214,6 +248,8 @@ typedef uint16_t S3L_Index;
|
|||
4, 1, 0, /* bottom */\
|
||||
4, 5, 1
|
||||
|
||||
#define S3L_CUBE_TRIANGLE_COUNT 12
|
||||
|
||||
/** Predefined texture coordinates of a cube, corresponding to triangles (NOT
|
||||
vertices), to be used with S3L_CUBE_VERTICES and S3L_CUBE_TRIANGLES. */
|
||||
#define S3L_CUBE_TEXCOORDS(m)\
|
||||
|
@ -332,12 +368,37 @@ void S3L_mat4Xmat4(S3L_Mat4 *m1, S3L_Mat4 *m2);
|
|||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Unit focalLength; ///< Defines the field of view (FOV).
|
||||
S3L_Unit focalLength; ///< Defines the field of view (FOV).
|
||||
S3L_Transform3D transform;
|
||||
} S3L_Camera;
|
||||
|
||||
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
|
||||
{
|
||||
S3L_ScreenCoord x; ///< Screen X coordinate.
|
||||
|
@ -351,7 +412,8 @@ typedef struct
|
|||
S3L_FRACTIONS_PER_UNIT. */
|
||||
S3L_Unit barycentric1; ///< Baryc. coord 1 (corresponds to 2nd 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_PixelInfo; /**< Used to pass the info about a rasterized pixel
|
||||
(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_POINTS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t backfaceCulling;
|
||||
uint8_t mode;
|
||||
} S3L_DrawConfig;
|
||||
|
||||
void S3L_initDrawConfig(S3L_DrawConfig *config);
|
||||
|
||||
// general helper functions
|
||||
static inline S3L_Unit S3L_abs(S3L_Unit value);
|
||||
static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2);
|
||||
|
@ -1653,57 +1707,61 @@ static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
|
|||
vector->y = (vector->y * focalLength) / divisor;
|
||||
}
|
||||
|
||||
void S3L_drawModelIndexed(
|
||||
const S3L_Unit coords[],
|
||||
const S3L_Index triangleVertexIndices[],
|
||||
uint16_t triangleCount,
|
||||
S3L_Transform3D modelTransform,
|
||||
const S3L_Camera *camera,
|
||||
const S3L_DrawConfig *config)
|
||||
void S3L_drawScene(S3L_Scene scene)
|
||||
{
|
||||
S3L_Index triangleIndex = 0;
|
||||
S3L_Index coordIndex = 0;
|
||||
|
||||
S3L_Vec4 pointModel, transformed0, transformed1, transformed2;
|
||||
S3L_Unit indexIndex = 0;
|
||||
|
||||
pointModel.w = S3L_FRACTIONS_PER_UNIT; // has to be "1.0" for translation
|
||||
|
||||
S3L_Mat4 mat1, mat2;
|
||||
|
||||
S3L_makeWorldMatrix(modelTransform,&mat1);
|
||||
S3L_makeCameraMatrix(camera->transform,&mat2);
|
||||
|
||||
S3L_mat4Xmat4(&mat1,&mat2);
|
||||
|
||||
while (triangleIndex < triangleCount)
|
||||
for (S3L_Index modelIndex; modelIndex < scene.modelCount; ++modelIndex)
|
||||
{
|
||||
#define project(n)\
|
||||
indexIndex = triangleVertexIndices[coordIndex] * 3;\
|
||||
pointModel.x = coords[indexIndex];\
|
||||
++indexIndex; /* TODO: put into square brackets? */\
|
||||
pointModel.y = coords[indexIndex];\
|
||||
++indexIndex;\
|
||||
pointModel.z = coords[indexIndex];\
|
||||
++coordIndex;\
|
||||
S3L_vec3Xmat4(&pointModel,&mat1);\
|
||||
transformed##n.x = pointModel.x;\
|
||||
transformed##n.y = pointModel.y;\
|
||||
transformed##n.z = pointModel.z;\
|
||||
transformed##n.w = S3L_FRACTIONS_PER_UNIT;\
|
||||
S3L_perspectiveDivide(&transformed##n,camera->focalLength);
|
||||
S3L_Unit *vertices = scene.models[modelIndex].vertices;
|
||||
S3L_Index *triangles = scene.models[modelIndex].triangles;
|
||||
|
||||
S3L_Index triangleIndex = 0;
|
||||
S3L_Index coordIndex = 0;
|
||||
|
||||
/* TODO: maybe create an option that would use a cache here to not
|
||||
transform the same point twice? */
|
||||
S3L_Vec4 pointModel, transformed0, transformed1, transformed2;
|
||||
S3L_Unit indexIndex = 0;
|
||||
|
||||
project(0)
|
||||
project(1)
|
||||
project(2)
|
||||
pointModel.w = S3L_FRACTIONS_PER_UNIT; // has to be "1.0" for translation
|
||||
|
||||
S3L_drawTriangle(transformed0,transformed1,transformed2,config,camera,
|
||||
triangleIndex);
|
||||
S3L_Mat4 mat1, mat2;
|
||||
|
||||
++triangleIndex;
|
||||
S3L_makeWorldMatrix(scene.models[modelIndex].transform,&mat1);
|
||||
S3L_makeCameraMatrix(scene.camera.transform,&mat2);
|
||||
|
||||
S3L_mat4Xmat4(&mat1,&mat2);
|
||||
|
||||
S3L_Index triangleCount = scene.models[modelIndex].triangleCount;
|
||||
|
||||
while (triangleIndex < triangleCount)
|
||||
{
|
||||
#define project(n)\
|
||||
indexIndex = triangles[coordIndex] * 3;\
|
||||
pointModel.x = vertices[indexIndex];\
|
||||
++indexIndex; /* TODO: put into square brackets? */\
|
||||
pointModel.y = vertices[indexIndex];\
|
||||
++indexIndex;\
|
||||
pointModel.z = vertices[indexIndex];\
|
||||
++coordIndex;\
|
||||
S3L_vec3Xmat4(&pointModel,&mat1);\
|
||||
transformed##n.x = pointModel.x;\
|
||||
transformed##n.y = pointModel.y;\
|
||||
transformed##n.z = pointModel.z;\
|
||||
transformed##n.w = S3L_FRACTIONS_PER_UNIT;\
|
||||
S3L_perspectiveDivide(&transformed##n,scene.camera.focalLength);
|
||||
|
||||
/* TODO: maybe create an option that would use a cache here to not
|
||||
transform the same point twice? */
|
||||
|
||||
project(0)
|
||||
project(1)
|
||||
project(2)
|
||||
|
||||
#undef project
|
||||
|
||||
S3L_drawTriangle(transformed0,transformed1,transformed2,
|
||||
&(scene.models[modelIndex].config),&(scene.camera),triangleIndex);
|
||||
|
||||
++triangleIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
71
testSDL.c
71
testSDL.c
|
@ -35,6 +35,9 @@ const S3L_Unit ver[] = { S3L_CUBE_VERTICES };
|
|||
const S3L_Index tri[] = { S3L_CUBE_TRIANGLES };
|
||||
const S3L_Unit tex_coords[] = { S3L_CUBE_TEXCOORDS(16) };
|
||||
|
||||
S3L_Model3D models[2];
|
||||
S3L_Scene scene;
|
||||
|
||||
int8_t keys[256];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
S3L_Camera camera;
|
||||
S3L_Transform3D modelTransform;
|
||||
S3L_DrawConfig conf;
|
||||
|
||||
|
@ -136,11 +138,11 @@ void draw()
|
|||
if (frame % 128 == 0)
|
||||
{
|
||||
printf("frame: %d\n",frame);
|
||||
printf("camera:\n");
|
||||
printf("scene.camera:\n");
|
||||
printf(" translation: ");
|
||||
S3L_writeVec4(camera.transform.translation);
|
||||
S3L_writeVec4(scene.camera.transform.translation);
|
||||
printf(" rotation: ");
|
||||
S3L_writeVec4(camera.transform.rotation);
|
||||
S3L_writeVec4(scene.camera.transform.rotation);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -150,22 +152,26 @@ void draw()
|
|||
|
||||
uint32_t f = frame;
|
||||
|
||||
modelTransform.rotation.z = f * 0.1;
|
||||
modelTransform.rotation.x = f * 0.3;
|
||||
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,&camera,&conf);
|
||||
/*
|
||||
S3L_drawModelIndexed(ver,tri,12,modelTransform,&scene.camera,&conf);
|
||||
|
||||
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;
|
||||
*/
|
||||
|
||||
S3L_drawScene(scene);
|
||||
|
||||
if (offScreenPixels > 0)
|
||||
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;
|
||||
|
@ -216,12 +222,25 @@ int main()
|
|||
SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
|
||||
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 = ⊧
|
||||
|
||||
// camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT;
|
||||
// camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT;
|
||||
scene.models[0].vertices = ver;
|
||||
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_initDrawConfig(&conf);
|
||||
|
@ -261,47 +280,47 @@ int main()
|
|||
int step = 10;
|
||||
|
||||
S3L_rotationToDirections(
|
||||
camera.transform.rotation,
|
||||
scene.camera.transform.rotation,
|
||||
step,
|
||||
&camF,
|
||||
&camR,
|
||||
&camU);
|
||||
|
||||
if (keys['w'])
|
||||
S3L_vec3Add(&camera.transform.translation,camF);
|
||||
S3L_vec3Add(&scene.camera.transform.translation,camF);
|
||||
|
||||
if (keys['s'])
|
||||
S3L_vec3Sub(&camera.transform.translation,camF);
|
||||
S3L_vec3Sub(&scene.camera.transform.translation,camF);
|
||||
|
||||
if (keys['d'])
|
||||
S3L_vec3Add(&camera.transform.translation,camR);
|
||||
S3L_vec3Add(&scene.camera.transform.translation,camR);
|
||||
|
||||
if (keys['a'])
|
||||
S3L_vec3Sub(&camera.transform.translation,camR);
|
||||
S3L_vec3Sub(&scene.camera.transform.translation,camR);
|
||||
|
||||
if (keys['c'])
|
||||
S3L_vec3Add(&camera.transform.translation,camU);
|
||||
S3L_vec3Add(&scene.camera.transform.translation,camU);
|
||||
|
||||
if (keys['x'])
|
||||
S3L_vec3Sub(&camera.transform.translation,camU);
|
||||
S3L_vec3Sub(&scene.camera.transform.translation,camU);
|
||||
|
||||
if (keys['q'])
|
||||
camera.transform.rotation.y -= 1;
|
||||
scene.camera.transform.rotation.y -= 1;
|
||||
|
||||
if (keys['e'])
|
||||
camera.transform.rotation.y += 1;
|
||||
scene.camera.transform.rotation.y += 1;
|
||||
|
||||
if (keys['r'])
|
||||
camera.transform.rotation.x -= 1;
|
||||
scene.camera.transform.rotation.x -= 1;
|
||||
|
||||
if (keys['t'])
|
||||
camera.transform.rotation.x += 1;
|
||||
scene.camera.transform.rotation.x += 1;
|
||||
|
||||
if (keys['f'])
|
||||
camera.transform.rotation.z -= 1;
|
||||
scene.camera.transform.rotation.z -= 1;
|
||||
|
||||
if (keys['g'])
|
||||
camera.transform.rotation.z += 1;
|
||||
scene.camera.transform.rotation.z += 1;
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer,texture,NULL,NULL);
|
||||
|
|
Loading…
Reference in a new issue