diff --git a/programs/demo.c b/programs/demo.c index 419a775..87506af 100644 --- a/programs/demo.c +++ b/programs/demo.c @@ -11,7 +11,7 @@ #define S3L_FLAT 0 #define S3L_STRICT_NEAR_CULLING 0 -#define S3L_PERSPECTIVE_CORRECTION 1 +#define S3L_PERSPECTIVE_CORRECTION 2 #define S3L_SORT 2 #define S3L_STENCIL_BUFFER 1 #define S3L_Z_BUFFER 0 @@ -80,6 +80,8 @@ void drawPixel(S3L_PixelInfo *p) { /* + S3L_correctBarycentricCoords(p->barycentric); + if (p->barycentric[0] < 0 || p->barycentric[0] > 512) printf("%d %d %d\n",p->barycentric[0],p->barycentric[1],p->barycentric[2]); diff --git a/small3dlib.h b/small3dlib.h index 1acbd70..21b6558 100644 --- a/small3dlib.h +++ b/small3dlib.h @@ -448,9 +448,11 @@ typedef struct triangle and interpolate values between it's three points. Each one goes from 0 to S3L_FRACTIONS_PER_UNIT (inclidung), but due to - rounding error may fall outside this range. The - sum of the three coordinates will always be - exactly S3L_FRACTIONS_PER_UNIT. */ + rounding error may fall outside this range (you + can use S3L_correctBarycentricCoords to fix this + for the price of some performance). The sum of + the three coordinates will always be exactly + S3L_FRACTIONS_PER_UNIT. */ S3L_Index triangleIndex; ///< Triangle index. S3L_Index modelIndex; S3L_Unit depth; ///< Depth (only if depth is turned on). @@ -466,6 +468,12 @@ typedef struct static inline void S3L_initPixelInfo(S3L_PixelInfo *p); +/** Corrects barycentric coordinates so that they exactly meet the defined + conditions (each fall into <0,S3L_FRACTIONS_PER_UNIT>, sum = + S3L_FRACTIONS_PER_UNIT). Note that doing this per-pixel can slow the program + down significantly. */ +static inline void S3LcorrectBarycentricCoords(S3L_Unit barycentric[3]); + // general helper functions static inline S3L_Unit S3L_abs(S3L_Unit value); static inline S3L_Unit S3L_min(S3L_Unit v1, S3L_Unit v2); @@ -1138,6 +1146,22 @@ S3L_Unit S3L_cos(S3L_Unit x) return S3L_sin(x - S3L_FRACTIONS_PER_UNIT / 4); } +void S3L_correctBarycentricCoords(S3L_Unit barycentric[3]) +{ + barycentric[0] = S3L_clamp(barycentric[0],0,S3L_FRACTIONS_PER_UNIT); + barycentric[1] = S3L_clamp(barycentric[1],0,S3L_FRACTIONS_PER_UNIT); + + S3L_Unit d = S3L_FRACTIONS_PER_UNIT - barycentric[0] - barycentric[1]; + + if (d < 0) + { + barycentric[0] += d; + barycentric[2] = 0; + } + else + barycentric[2] = d; +} + void S3L_makeTranslationMat( S3L_Unit offsetX, S3L_Unit offsetY,