mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-20 20:29:58 +01:00
Refactor
This commit is contained in:
parent
be396b5c68
commit
ff56c9da7f
1 changed files with 247 additions and 167 deletions
414
s3l.h
414
s3l.h
|
@ -1,3 +1,6 @@
|
|||
#ifndef S3L_H
|
||||
#define S3L_H
|
||||
|
||||
/*
|
||||
WIP
|
||||
|
||||
|
@ -105,9 +108,6 @@
|
|||
of the triangle and at the same time is also not the bottom-most corner.
|
||||
*/
|
||||
|
||||
#ifndef S3L_H
|
||||
#define S3L_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef S3L_RESOLUTION_X
|
||||
|
@ -133,9 +133,6 @@
|
|||
*/
|
||||
#endif
|
||||
|
||||
#define S3L_HALF_RESOLUTION_X (S3L_RESOLUTION_X >> 1)
|
||||
#define S3L_HALF_RESOLUTION_Y (S3L_RESOLUTION_Y >> 1)
|
||||
|
||||
typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
|
||||
S3L_FRACTIONS_PER_UNIT in one spatial unit.
|
||||
By dividing the unit into fractions we
|
||||
|
@ -149,9 +146,8 @@ typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
|
|||
have to modify a sin table otherwise
|
||||
it will overflow. Also other things
|
||||
may overflow, so rather don't do it. */
|
||||
|
||||
#define S3L_PROJECTION_PLANE_HEIGHT\
|
||||
((S3L_RESOLUTION_Y * S3L_FRACTIONS_PER_UNIT * 2) / S3L_RESOLUTION_X)
|
||||
typedef int16_t S3L_ScreenCoord;
|
||||
typedef uint16_t S3L_Index;
|
||||
|
||||
#ifndef S3L_NEAR
|
||||
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT) /**< Distance of the near clipping
|
||||
|
@ -169,6 +165,12 @@ typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
|
|||
prevent overflow. */
|
||||
#endif
|
||||
|
||||
#define S3L_HALF_RESOLUTION_X (S3L_RESOLUTION_X >> 1)
|
||||
#define S3L_HALF_RESOLUTION_Y (S3L_RESOLUTION_Y >> 1)
|
||||
|
||||
#define S3L_PROJECTION_PLANE_HEIGHT\
|
||||
((S3L_RESOLUTION_Y * S3L_FRACTIONS_PER_UNIT * 2) / S3L_RESOLUTION_X)
|
||||
|
||||
/** Predefined vertices of a cube to simply insert in an array. These come with
|
||||
S3L_CUBE_TRIANGLES and S3L_CUBE_TEXCOORDS. */
|
||||
#define S3L_CUBE_VERTICES\
|
||||
|
@ -221,6 +223,198 @@ typedef int32_t S3L_Unit; /**< Units of measurement in 3D space. There is
|
|||
0,m, m,0, m,m,\
|
||||
0,m, 0,0, m,0
|
||||
|
||||
/**
|
||||
Vector that consists of four scalars and can represent homogenous
|
||||
coordinates, but is generally also used as Vec3 and Vec2.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Unit x;
|
||||
S3L_Unit y;
|
||||
S3L_Unit z;
|
||||
S3L_Unit w;
|
||||
} S3L_Vec4;
|
||||
|
||||
static inline void S3L_initVec4(S3L_Vec4 *v);
|
||||
|
||||
#define S3L_writeVec4(v)\
|
||||
printf("Vec4: %d %d %d %d\n",((v).x),((v).y),((v).z),((v).w))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Vec4 translation;
|
||||
S3L_Vec4 rotation; /**< Euler angles. Rortation is applied in this order:
|
||||
1. z = around z (roll) CW looking along z+
|
||||
2. x = around x (pitch) CW looking along x+
|
||||
3. y = around y (yaw) CW looking along y+ */
|
||||
S3L_Vec4 scale;
|
||||
} S3L_Transform3D;
|
||||
|
||||
static inline void S3L_initTransoform3D(S3L_Transform3D *t);
|
||||
|
||||
typedef S3L_Unit S3L_Mat4[4][4]; /**< 4x4 matrix, used mostly for 3D
|
||||
transforms. The indexing is this:
|
||||
matrix[column][row]. */
|
||||
#define S3L_writeMat4(m)\
|
||||
printf("Mat4:\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n"\
|
||||
,(m)[0][0],(m)[1][0],(m)[2][0],(m)[3][0],\
|
||||
(m)[0][1],(m)[1][1],(m)[2][1],(m)[3][1],\
|
||||
(m)[0][2],(m)[1][2],(m)[2][2],(m)[3][2],\
|
||||
(m)[0][3],(m)[1][3],(m)[2][3],(m)[3][3])
|
||||
|
||||
/** Initializes a 4x4 matrix to identity. */
|
||||
static inline void S3L_initMat4(S3L_Mat4 *m);
|
||||
|
||||
void S3L_makeTranslationMat(
|
||||
S3L_Unit offsetX,
|
||||
S3L_Unit offsetY,
|
||||
S3L_Unit offsetZ,
|
||||
S3L_Mat4 *m);
|
||||
|
||||
/** Makes a scaling matrix. DON'T FORGET: scale of 1.0 is set with
|
||||
S3L_FRACTIONS_PER_UNIT! */
|
||||
void S3L_makeScaleMatrix(
|
||||
S3L_Unit scaleX,
|
||||
S3L_Unit scaleY,
|
||||
S3L_Unit scaleZ,
|
||||
S3L_Mat4 *m);
|
||||
|
||||
/** Makes a rotation matrix. For the rotation conventions (meaning, order,
|
||||
units) see the specific structure comments. */
|
||||
void S3L_makeRotationMatrix(
|
||||
S3L_Unit aroundX,
|
||||
S3L_Unit aroundY,
|
||||
S3L_Unit aroundZ,
|
||||
S3L_Mat4 *m);
|
||||
|
||||
void S3L_makeWorldMatrix(S3L_Transform3D worldTransform, S3L_Mat4 *m);
|
||||
void S3L_makeCameraMatrix(S3L_Transform3D cameraTransform, S3L_Mat4 *m);
|
||||
|
||||
/** Multiplies a vector by a matrix with normalization by
|
||||
S3L_FRACTIONS_PER_UNIT. Result is stored in the input vector. */
|
||||
void S3L_vec4Xmat4(S3L_Vec4 *v, S3L_Mat4 *m);
|
||||
|
||||
/** Same as S3L_vec4Xmat4 but faster, because this version doesn't compute the
|
||||
W component of the result, which is usually not needed. */
|
||||
void S3L_vec3Xmat4(S3L_Vec4 *v, S3L_Mat4 *m);
|
||||
|
||||
/** Multiplies two matrices with normalization by S3L_FRACTIONS_PER_UNIT.
|
||||
Result is stored in the first matrix. */
|
||||
void S3L_mat4Xmat4(S3L_Mat4 *m1, S3L_Mat4 *m2);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Unit focalLength; ///< Defines the field of view (FOV).
|
||||
S3L_Transform3D transform;
|
||||
} S3L_Camera;
|
||||
|
||||
static inline void S3L_initCamera(S3L_Camera *c);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_ScreenCoord x; ///< Screen X coordinate.
|
||||
S3L_ScreenCoord y; ///< Screen Y coordinate.
|
||||
|
||||
S3L_Unit barycentric0; /**< Barycentric coord 0 (corresponds to 1st vertex).
|
||||
Together with 1 and 2 coords these serve to
|
||||
locate the pixel on a triangle and interpolate
|
||||
values between it's three points. The sum of the
|
||||
three coordinates will always be exactly
|
||||
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_PixelInfo; /**< Used to pass the info about a rasterized pixel
|
||||
(fragment) to the user-defined drawing func. */
|
||||
|
||||
static inline void S3L_initPixelInfo(S3L_PixelInfo *p);
|
||||
|
||||
#define S3L_BACKFACE_CULLING_NONE 0
|
||||
#define S3L_BACKFACE_CULLING_CW 1
|
||||
#define S3L_BACKFACE_CULLING_CCW 2
|
||||
|
||||
#define S3L_MODE_TRIANGLES 0
|
||||
#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);
|
||||
static inline S3L_Unit S3L_max(S3L_Unit v1, S3L_Unit v2);
|
||||
static inline S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod);
|
||||
static inline S3L_Unit S3L_nonZero(S3L_Unit value);
|
||||
|
||||
S3L_Unit S3L_sin(S3L_Unit x);
|
||||
static inline S3L_Unit S3L_cos(S3L_Unit x);
|
||||
|
||||
/** Interpolated between two values, v1 and v2, in the same ratio as t is to
|
||||
tMax. Does NOT prevent zero division. */
|
||||
static inline S3L_Unit S3L_interpolate(
|
||||
S3L_Unit v1,
|
||||
S3L_Unit v2,
|
||||
S3L_Unit t,
|
||||
S3L_Unit tMax);
|
||||
|
||||
/** Same as S3L_interpolate but with v1 == 0. Should be faster. */
|
||||
static inline S3L_Unit S3L_interpolateFrom0(
|
||||
S3L_Unit v2,
|
||||
S3L_Unit t,
|
||||
S3L_Unit tMax);
|
||||
|
||||
/** Like S3L_interpolate, but uses a parameter that goes from 0 to
|
||||
S3L_FRACTIONS_PER_UNIT - 1, which can be faster. */
|
||||
static inline S3L_Unit S3L_interpolateByUnit(
|
||||
S3L_Unit v1,
|
||||
S3L_Unit v2,
|
||||
S3L_Unit t);
|
||||
|
||||
/** Same as S3L_interpolateByUnit but with v1 == 0. Should be faster. */
|
||||
static inline S3L_Unit S3L_interpolateByUnitFrom0(
|
||||
S3L_Unit v2,
|
||||
S3L_Unit t);
|
||||
|
||||
/** Returns a value interpolated between the three triangle vertices based on
|
||||
barycentric coordinates. */
|
||||
static inline S3L_Unit S3L_interpolateBarycentric(
|
||||
S3L_Unit value0,
|
||||
S3L_Unit value1,
|
||||
S3L_Unit value2,
|
||||
S3L_Unit barycentric0,
|
||||
S3L_Unit barycentric1,
|
||||
S3L_Unit barycentric2);
|
||||
|
||||
static inline void S3L_mapProjectionPlaneToScreen(
|
||||
S3L_Vec4 point,
|
||||
S3L_ScreenCoord *screenX,
|
||||
S3L_ScreenCoord *screenY);
|
||||
|
||||
/** Draws a triangle according to given config. The vertices are specified in
|
||||
projection-plane space (NOT screen space!) -- they wll be mapped to screen
|
||||
space by thies function. If perspective correction is enabled, each vertex
|
||||
has to have a depth (Z position in camera space) specified in the Z
|
||||
component. */
|
||||
void S3L_drawTriangle(
|
||||
S3L_Vec4 point0,
|
||||
S3L_Vec4 point1,
|
||||
S3L_Vec4 point2,
|
||||
const S3L_DrawConfig *config,
|
||||
const S3L_Camera *camera,
|
||||
S3L_Index triangleID);
|
||||
|
||||
static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle);
|
||||
|
||||
//=============================================================================
|
||||
// privates
|
||||
|
||||
#define S3L_SIN_TABLE_LENGTH 128
|
||||
static const S3L_Unit S3L_sinTable[S3L_SIN_TABLE_LENGTH] =
|
||||
{
|
||||
|
@ -296,44 +490,12 @@ static const S3L_Unit S3L_sinTable[S3L_SIN_TABLE_LENGTH] =
|
|||
#define S3L_SIN_TABLE_UNIT_STEP\
|
||||
(S3L_FRACTIONS_PER_UNIT / (S3L_SIN_TABLE_LENGTH * 4))
|
||||
|
||||
typedef int16_t S3L_ScreenCoord;
|
||||
typedef uint16_t S3L_Index;
|
||||
|
||||
/**
|
||||
Vector that consists of four scalars and can represent homogenous
|
||||
coordinates, but is generally also used as Vec3 and Vec2.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Unit x;
|
||||
S3L_Unit y;
|
||||
S3L_Unit z;
|
||||
S3L_Unit w;
|
||||
} S3L_Vec4;
|
||||
|
||||
#define S3L_writeVec4(v)\
|
||||
printf("Vec4: %d %d %d %d\n",((v).x),((v).y),((v).z),((v).w))
|
||||
|
||||
static inline void S3L_initVec4(S3L_Vec4 *v)
|
||||
void S3L_initVec4(S3L_Vec4 *v)
|
||||
{
|
||||
v->x = 0; v->y = 0; v->z = 0; v->w = S3L_FRACTIONS_PER_UNIT;
|
||||
}
|
||||
|
||||
typedef S3L_Unit S3L_Mat4[4][4]; /**< 4x4 matrix, used mostly for 3D
|
||||
transforms. The indexing is this:
|
||||
matrix[column][row]. */
|
||||
#define S3L_writeMat4(m)\
|
||||
printf("Mat4:\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n %d %d %d %d\n"\
|
||||
,(m)[0][0],(m)[1][0],(m)[2][0],(m)[3][0],\
|
||||
(m)[0][1],(m)[1][1],(m)[2][1],(m)[3][1],\
|
||||
(m)[0][2],(m)[1][2],(m)[2][2],(m)[3][2],\
|
||||
(m)[0][3],(m)[1][3],(m)[2][3],(m)[3][3])
|
||||
|
||||
/**
|
||||
Initializes a 4x4 matrix to identity.
|
||||
*/
|
||||
static inline void S3L_initMat4(S3L_Mat4 *m)
|
||||
void S3L_initMat4(S3L_Mat4 *m)
|
||||
{
|
||||
#define M(x,y) (*m)[x][y]
|
||||
#define S S3L_FRACTIONS_PER_UNIT
|
||||
|
@ -347,10 +509,6 @@ static inline void S3L_initMat4(S3L_Mat4 *m)
|
|||
#undef S
|
||||
}
|
||||
|
||||
/**
|
||||
Multiplies a vector by a matrix with normalization by S3L_FRACTIONS_PER_UNIT.
|
||||
Result is stored in the input vector.
|
||||
*/
|
||||
void S3L_vec4Xmat4(S3L_Vec4 *v, S3L_Mat4 *m)
|
||||
{
|
||||
S3L_Vec4 vBackup;
|
||||
|
@ -372,13 +530,8 @@ void S3L_vec4Xmat4(S3L_Vec4 *v, S3L_Mat4 *m)
|
|||
v->y = dotCol(1);
|
||||
v->z = dotCol(2);
|
||||
v->w = dotCol(3);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Same as S3L_vec4Xmat4 but faster, because this version doesn't compute the W
|
||||
component of the result, which is usually not needed.
|
||||
*/
|
||||
void S3L_vec3Xmat4(S3L_Vec4 *v, S3L_Mat4 *m)
|
||||
{
|
||||
S3L_Vec4 vBackup;
|
||||
|
@ -403,76 +556,51 @@ void S3L_vec3Xmat4(S3L_Vec4 *v, S3L_Mat4 *m)
|
|||
|
||||
#undef dotCol
|
||||
|
||||
// general helper functions
|
||||
|
||||
static inline S3L_Unit S3L_abs(S3L_Unit value)
|
||||
S3L_Unit S3L_abs(S3L_Unit value)
|
||||
{
|
||||
return value >= 0 ? value : -1 * value;
|
||||
}
|
||||
|
||||
static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2)
|
||||
S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2)
|
||||
{
|
||||
return v1 >= v2 ? v2 : v1;
|
||||
}
|
||||
|
||||
static inline S3L_Unit S3L_max(S3L_Unit v1, S3L_Unit v2)
|
||||
S3L_Unit S3L_max(S3L_Unit v1, S3L_Unit v2)
|
||||
{
|
||||
return v1 >= v2 ? v1 : v2;
|
||||
}
|
||||
|
||||
static inline S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod)
|
||||
S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod)
|
||||
{
|
||||
return value >= 0 ? (value % mod) : (mod + (value % mod) - 1);
|
||||
}
|
||||
|
||||
static inline S3L_Unit S3L_nonZero(S3L_Unit value)
|
||||
S3L_Unit S3L_nonZero(S3L_Unit value)
|
||||
{
|
||||
return value != 0 ? value : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Interpolated between two values, v1 and v2, in the same ratio as t is to
|
||||
tMax. Does NOT prevent zero division.
|
||||
*/
|
||||
static inline S3L_Unit S3L_interpolate(S3L_Unit v1, S3L_Unit v2, S3L_Unit t,
|
||||
S3L_Unit tMax)
|
||||
S3L_Unit S3L_interpolate(S3L_Unit v1, S3L_Unit v2, S3L_Unit t, S3L_Unit tMax)
|
||||
{
|
||||
return v1 + ((v2 - v1) * t) / tMax;
|
||||
}
|
||||
|
||||
/**
|
||||
Like S3L_interpolate, but uses a parameter that goes from 0 to
|
||||
S3L_FRACTIONS_PER_UNIT - 1, which can be faster.
|
||||
*/
|
||||
static inline S3L_Unit S3L_interpolateByUnit(S3L_Unit v1, S3L_Unit v2,
|
||||
S3L_Unit t)
|
||||
S3L_Unit S3L_interpolateByUnit(S3L_Unit v1, S3L_Unit v2, S3L_Unit t)
|
||||
{
|
||||
return v1 + ((v2 - v1) * t) / S3L_FRACTIONS_PER_UNIT;
|
||||
}
|
||||
|
||||
// TODO: change parameters in interpolation functions to S3L_Unit
|
||||
|
||||
/**
|
||||
Same as S3L_interpolate but with v1 = 0. Should be faster.
|
||||
*/
|
||||
static inline S3L_Unit S3L_interpolateByUnitFrom0(S3L_Unit v2, S3L_Unit t)
|
||||
S3L_Unit S3L_interpolateByUnitFrom0(S3L_Unit v2, S3L_Unit t)
|
||||
{
|
||||
return (v2 * t) / S3L_FRACTIONS_PER_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
Same as S3L_interpolate but with v1 = 0. Should be faster.
|
||||
*/
|
||||
static inline S3L_Unit S3L_interpolateFrom0(S3L_Unit v2, S3L_Unit t,
|
||||
S3L_Unit tMax)
|
||||
S3L_Unit S3L_interpolateFrom0(S3L_Unit v2, S3L_Unit t, S3L_Unit tMax)
|
||||
{
|
||||
return (v2 * t) / tMax;
|
||||
}
|
||||
|
||||
/**
|
||||
Multiplies two matrices with normalization by S3L_FRACTIONS_PER_UNIT. Result
|
||||
is stored in the first matrix.
|
||||
*/
|
||||
void S3L_mat4Xmat4(S3L_Mat4 *m1, S3L_Mat4 *m2)
|
||||
{
|
||||
S3L_Mat4 mat1;
|
||||
|
@ -515,13 +643,16 @@ S3L_Unit S3L_sin(S3L_Unit x)
|
|||
return positive ? S3L_sinTable[x] : -1 * S3L_sinTable[x];
|
||||
}
|
||||
|
||||
static inline S3L_Unit S3L_cos(S3L_Unit x)
|
||||
S3L_Unit S3L_cos(S3L_Unit x)
|
||||
{
|
||||
return S3L_sin(x - S3L_FRACTIONS_PER_UNIT / 4);
|
||||
}
|
||||
|
||||
void S3L_makeTranslationMat(
|
||||
S3L_Unit offsetX, S3L_Unit offsetY, S3L_Unit offsetZ, S3L_Mat4 *m)
|
||||
S3L_Unit offsetX,
|
||||
S3L_Unit offsetY,
|
||||
S3L_Unit offsetZ,
|
||||
S3L_Mat4 *m)
|
||||
{
|
||||
#define M(x,y) (*m)[x][y]
|
||||
#define S S3L_FRACTIONS_PER_UNIT
|
||||
|
@ -535,12 +666,11 @@ void S3L_makeTranslationMat(
|
|||
#undef S
|
||||
}
|
||||
|
||||
/**
|
||||
Makes a scaling matrix. DON'T FORGET: scale of 1.0 is set with
|
||||
S3L_FRACTIONS_PER_UNIT!
|
||||
*/
|
||||
void S3L_makeScaleMatrix(
|
||||
S3L_Unit scaleX, S3L_Unit scaleY, S3L_Unit scaleZ, S3L_Mat4 *m)
|
||||
S3L_Unit scaleX,
|
||||
S3L_Unit scaleY,
|
||||
S3L_Unit scaleZ,
|
||||
S3L_Mat4 *m)
|
||||
{
|
||||
#define M(x,y) (*m)[x][y]
|
||||
|
||||
|
@ -552,12 +682,11 @@ void S3L_makeScaleMatrix(
|
|||
#undef M
|
||||
}
|
||||
|
||||
/**
|
||||
Makes a rotation matrix. For the rotation conventions (meaning, order, units)
|
||||
see the appropriate structure comments.
|
||||
*/
|
||||
void S3L_makeRotationMatrix(
|
||||
S3L_Unit aroundX, S3L_Unit aroundY, S3L_Unit aroundZ, S3L_Mat4 *m)
|
||||
S3L_Unit aroundX,
|
||||
S3L_Unit aroundY,
|
||||
S3L_Unit aroundZ,
|
||||
S3L_Mat4 *m)
|
||||
{
|
||||
S3L_Unit sx = S3L_sin(aroundX);
|
||||
S3L_Unit sy = S3L_sin(aroundY);
|
||||
|
@ -594,17 +723,7 @@ void S3L_makeRotationMatrix(
|
|||
#undef S
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Vec4 translation;
|
||||
S3L_Vec4 rotation; /**< Euler angles. Rortation is applied in this order:
|
||||
1. z = around z (roll) CW looking along z+
|
||||
2. x = around x (pitch) CW looking along x+
|
||||
3. y = around y (yaw) CW looking along y+ */
|
||||
S3L_Vec4 scale;
|
||||
} S3L_Transform3D;
|
||||
|
||||
static inline void S3L_initTransoform3D(S3L_Transform3D *t)
|
||||
void S3L_initTransoform3D(S3L_Transform3D *t)
|
||||
{
|
||||
S3L_initVec4(&(t->translation));
|
||||
S3L_initVec4(&(t->rotation));
|
||||
|
@ -613,35 +732,13 @@ static inline void S3L_initTransoform3D(S3L_Transform3D *t)
|
|||
t->scale.z = S3L_FRACTIONS_PER_UNIT;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_Unit focalLength; ///< Defines the field of view (FOV).
|
||||
S3L_Transform3D transform;
|
||||
} S3L_Camera;
|
||||
|
||||
static inline void S3L_initCamera(S3L_Camera *c)
|
||||
void S3L_initCamera(S3L_Camera *c)
|
||||
{
|
||||
c->focalLength = S3L_FRACTIONS_PER_UNIT;
|
||||
S3L_initTransoform3D(&(c->transform));
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
S3L_ScreenCoord x; ///< Screen X coordinate.
|
||||
S3L_ScreenCoord y; ///< Screen Y coordinate.
|
||||
|
||||
S3L_Unit barycentric0; /**< Barycentric coord 0 (corresponds to 1st vertex).
|
||||
Together with 1 and 2 coords these serve to
|
||||
locate the pixel on a triangle and interpolate
|
||||
values between it's three points. The sum of the
|
||||
three coordinates will always be exactly
|
||||
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_PixelInfo;
|
||||
|
||||
static inline void S3L_initPixelInfo(S3L_PixelInfo *p)
|
||||
void S3L_initPixelInfo(S3L_PixelInfo *p)
|
||||
{
|
||||
p->x = 0;
|
||||
p->y = 0;
|
||||
|
@ -651,20 +748,6 @@ static inline void S3L_initPixelInfo(S3L_PixelInfo *p)
|
|||
p->triangleID = 0;
|
||||
}
|
||||
|
||||
#define S3L_BACKFACE_CULLING_NONE 0
|
||||
#define S3L_BACKFACE_CULLING_CW 1
|
||||
#define S3L_BACKFACE_CULLING_CCW 2
|
||||
|
||||
#define S3L_MODE_TRIANGLES 0
|
||||
#define S3L_MODE_LINES 1
|
||||
#define S3L_MODE_POINTS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int backfaceCulling;
|
||||
int mode;
|
||||
} S3L_DrawConfig;
|
||||
|
||||
void S3L_initDrawConfig(S3L_DrawConfig *config)
|
||||
{
|
||||
config->backfaceCulling = 1;
|
||||
|
@ -788,13 +871,13 @@ S3L_Unit S3L_correctPerspective(
|
|||
(result > S3L_FRACTIONS_PER_UNIT ? S3L_FRACTIONS_PER_UNIT : result);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a value interpolated between the three triangle vertices based on
|
||||
barycentric coordinates.
|
||||
*/
|
||||
static inline S3L_Unit S3L_interpolateBarycentric(
|
||||
S3L_Unit value0, S3L_Unit value1, S3L_Unit value2,
|
||||
S3L_Unit barycentric0, S3L_Unit barycentric1, S3L_Unit barycentric2)
|
||||
S3L_Unit value0,
|
||||
S3L_Unit value1,
|
||||
S3L_Unit value2,
|
||||
S3L_Unit barycentric0,
|
||||
S3L_Unit barycentric1,
|
||||
S3L_Unit barycentric2)
|
||||
{
|
||||
return
|
||||
(
|
||||
|
@ -863,8 +946,10 @@ int S3L_bresenhamStep(S3L_BresenhamState *state)
|
|||
return state->steps >= 0;
|
||||
}
|
||||
|
||||
static inline void S3L_mapProjectionPlaneToScreen(S3L_Vec4 point,
|
||||
S3L_ScreenCoord *screenX, S3L_ScreenCoord *screenY)
|
||||
void S3L_mapProjectionPlaneToScreen(
|
||||
S3L_Vec4 point,
|
||||
S3L_ScreenCoord *screenX,
|
||||
S3L_ScreenCoord *screenY)
|
||||
{
|
||||
*screenX =
|
||||
S3L_HALF_RESOLUTION_X +
|
||||
|
@ -1209,17 +1294,12 @@ void _S3L_drawFilledTriangle(
|
|||
#undef stepSide
|
||||
}
|
||||
|
||||
int a = 0;
|
||||
|
||||
/**
|
||||
Draws a triangle according to given config. The vertices are specified in
|
||||
projection-plane space (NOT screen space!) -- they wll be mapped to screen
|
||||
space by thies function. If perspective correction is enabled, each vertex
|
||||
has to have a depth (Z position in camera space) specified in the Z
|
||||
component.
|
||||
*/
|
||||
void S3L_drawTriangle(S3L_Vec4 point0, S3L_Vec4 point1, S3L_Vec4 point2,
|
||||
const S3L_DrawConfig *config, const S3L_Camera *camera,
|
||||
void S3L_drawTriangle(
|
||||
S3L_Vec4 point0,
|
||||
S3L_Vec4 point1,
|
||||
S3L_Vec4 point2,
|
||||
const S3L_DrawConfig *config,
|
||||
const S3L_Camera *camera,
|
||||
S3L_Index triangleID)
|
||||
{
|
||||
#define clipTest(c,cmp,v)\
|
||||
|
@ -1323,7 +1403,7 @@ void S3L_drawTriangle(S3L_Vec4 point0, S3L_Vec4 point1, S3L_Vec4 point2,
|
|||
}
|
||||
}
|
||||
|
||||
static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle)
|
||||
void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle)
|
||||
{
|
||||
if (angle < S3L_SIN_TABLE_UNIT_STEP)
|
||||
return; // no visible rotation
|
||||
|
|
Loading…
Reference in a new issue