20#ifndef _TGX_RASTERIZER_H_
21#define _TGX_RASTERIZER_H_
46#define TGX_RASTERIZE_SUBPIXEL_BITS (6)
48#define TGX_RASTERIZE_SUBPIXEL256 (1 << TGX_RASTERIZE_SUBPIXEL_BITS)
49#define TGX_RASTERIZE_SUBPIXEL128 (1 << (TGX_RASTERIZE_SUBPIXEL_BITS -1))
50#define TGX_RASTERIZE_MULT256(X) ((X) << (TGX_RASTERIZE_SUBPIXEL_BITS))
51#define TGX_RASTERIZE_MULT128(X) ((X) << (TGX_RASTERIZE_SUBPIXEL_BITS -1))
52#define TGX_RASTERIZE_DIV256(X) ((X) >> (TGX_RASTERIZE_SUBPIXEL_BITS))
57TGX_INLINE
inline void minmax3_i32(
const int32_t a,
const int32_t b,
const int32_t c, int32_t& mn, int32_t& mx)
59 if (a < b) { mn = a; mx = b; }
else { mn = b; mx = a; }
60 if (c < mn) { mn = c; }
else if (c > mx) { mx = c; }
64TGX_INLINE
inline int32_t tgx_floor_div_subpixel_i32(
const int32_t x)
66#if defined(__GNUC__) || defined(__clang__)
71 const int32_t S = TGX_RASTERIZE_SUBPIXEL256;
72 return (x >= 0) ? (x / S) : -(((-x) + S - 1) / S);
77TGX_INLINE
inline int32_t tgx_ceil_div_subpixel_i32(
const int32_t x)
79#if defined(__GNUC__) || defined(__clang__)
84 const int32_t S = TGX_RASTERIZE_SUBPIXEL256;
85 return (x >= 0) ? ((x + S - 1) / S) : -((-x) / S);
141 template<auto shader_function,
typename RASTERIZER_PARAMS>
142 TGX_INLINE
inline void rasterizeTriangle(
const int LX,
const int LY,
const RasterizerVec4 & V0,
const RasterizerVec4 & V1,
const RasterizerVec4 & V2,
const int32_t offset_x,
const int32_t offset_y,
const RASTERIZER_PARAMS & data)
145 const int32_t hx = TGX_RASTERIZE_MULT128(LX);
146 const int32_t hy = TGX_RASTERIZE_MULT128(LY);
147 const float mx = (float)(hx);
148 const float my = (float)(hy);
154 int32_t umx, uMx, umy, uMy;
155 minmax3_i32(P0.
x, sP1.
x, sP2.
x, umx, uMx);
156 minmax3_i32(P0.
y, sP1.
y, sP2.
y, umy, uMy);
158 const int32_t bx0 = umx + hx - TGX_RASTERIZE_SUBPIXEL128;
159 const int32_t bx1 = uMx + hx - TGX_RASTERIZE_SUBPIXEL128;
160 const int32_t by0 = umy + hy - TGX_RASTERIZE_SUBPIXEL128;
161 const int32_t by1 = uMy + hy - TGX_RASTERIZE_SUBPIXEL128;
162 int32_t xmin = tgx_ceil_div_subpixel_i32(bx0);
163 int32_t xmax = tgx_floor_div_subpixel_i32(bx1);
164 int32_t ymin = tgx_ceil_div_subpixel_i32(by0);
165 int32_t ymax = tgx_floor_div_subpixel_i32(by1);
170 int32_t sx = data.im->lx();
171 int32_t sy = data.im->ly();
172 int32_t ox = offset_x;
173 int32_t oy = offset_y;
175 if (ox < xmin) { sx -= (xmin - ox); ox = xmin; }
176 if (ox + sx > xmax) { sx = xmax - ox + 1; }
179 if (oy < ymin) { sy -= (ymin - oy); oy = ymin; }
180 if (oy + sy > ymax) { sy = ymax - oy + 1; }
183 const uint32_t bw = (uint32_t)uMx - (uint32_t)umx;
184 const uint32_t bh = (uint32_t)uMy - (uint32_t)umy;
185 const bool c32 = ((bw < 32768u) && (bh < 32768u));
189 a = (((sP2.
x - P0.
x) * (sP1.
y - P0.
y)) - ((sP2.
y - P0.
y) * (sP1.
x - P0.
x)));
194 const int64_t a64 = (((int64_t)(sP2.
x - P0.
x)) * ((int64_t)(sP1.
y - P0.
y))) - (((int64_t)(sP2.
y - P0.
y)) * ((int64_t)(sP1.
x - P0.
x)));
195 if (a64 == 0)
return;
196 a = (a64 > 0) ? 1 : -1;
199 const RasterizerVec4& fP1 = (a > 0) ? V1 : V2;
200 const RasterizerVec4& fP2 = (a > 0) ? V2 : V1;
201 const iVec2& P1 = (a > 0) ? sP1 : sP2;
202 const iVec2& P2 = (a > 0) ? sP2 : sP1;
204 const int32_t us = TGX_RASTERIZE_MULT256(ox) - hx + TGX_RASTERIZE_SUBPIXEL128;
205 const int32_t vs = TGX_RASTERIZE_MULT256(oy) - hy + TGX_RASTERIZE_SUBPIXEL128;
210 int32_t dx1 = P1.
y - P0.
y;
211 int32_t dy1 = P0.
x - P1.
x;
212 int32_t dx2 = P2.
y - P1.
y;
213 int32_t dy2 = P1.
x - P2.
x;
214 int32_t dx3 = P0.
y - P2.
y;
215 int32_t dy3 = P2.
x - P0.
x;
221 O1 = ((us - P0.
x) * dx1) + ((vs - P0.
y) * dy1);
222 O3 = ((us - P2.
x) * dx3) + ((vs - P2.
y) * dy3);
225 const int32_t A32 = (a > 0) ? a : -a;
226 O2 = (int32_t)((uint32_t)A32 - (uint32_t)O1 - (uint32_t)O3);
228 if ((dx1 < 0) || ((dx1 == 0) && (dy1 < 0))) O1--;
229 if ((dx2 < 0) || ((dx2 == 0) && (dy2 < 0))) O2--;
230 if ((dx3 < 0) || ((dx3 == 0) && (dy3 < 0))) O3--;
232 dx1 *= TGX_RASTERIZE_SUBPIXEL256;
233 dy1 *= TGX_RASTERIZE_SUBPIXEL256;
234 dx2 *= TGX_RASTERIZE_SUBPIXEL256;
235 dy2 *= TGX_RASTERIZE_SUBPIXEL256;
236 dx3 *= TGX_RASTERIZE_SUBPIXEL256;
237 dy3 *= TGX_RASTERIZE_SUBPIXEL256;
241 int64_t dO1 = (((int64_t)(us - P0.
x)) * ((int64_t)dx1)) + (((int64_t)(vs - P0.
y)) * ((int64_t)dy1));
242 if ((dx1 < 0) || ((dx1 == 0) && (dy1 < 0))) dO1--;
243 O1 = (dO1 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO1)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO1 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
245 int64_t dO2 = (((int64_t)(us - P1.
x)) * ((int64_t)dx2)) + (((int64_t)(vs - P1.
y)) * ((int64_t)dy2));
246 if ((dx2 < 0) || ((dx2 == 0) && (dy2 < 0))) dO2--;
247 O2 = (dO2 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO2)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO2 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
249 int64_t dO3 = (((int64_t)(us - P2.
x)) * ((int64_t)dx3)) + (((int64_t)(vs - P2.
y)) * ((int64_t)dy3));
250 if ((dx3 < 0) || ((dx3 == 0) && (dy3 < 0))) dO3--;
251 O3 = (dO3 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO3)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO3 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
258 while (((O1 | O2 | O3) < 0) && (sy > 0))
270 while (((O1 | O2 | O3) < 0) && (sx > 0))
281 const RasterizerVec4* F1 = &fP2;
282 const RasterizerVec4* F2 = &V0;
283 const RasterizerVec4* F3 = &fP1;
290 const int32_t tdx = dx1;
291 const int32_t tdy = dy1;
292 const int32_t tO = O1;
293 const RasterizerVec4* tF = F1;
313 const int32_t tdx = dx3;
314 const int32_t tdy = dy3;
315 const int32_t tO = O3;
316 const RasterizerVec4* tF = F3;
335 shader_function(ox, oy, sx, sy, dx1, dy1, O1, *F1, dx2, dy2, O2, *F2, dx3, dy3, O3, *F3, data);
TGX_INLINE int32_t lfloorf(float x)
Compute (int32_t)floorf(x).
Definition: Misc.h:425
#define TGX_RASTERIZE_SUBPIXEL_BITS
Sub-pixel precision bits.
Definition: Rasterizer.h:46
TGX_INLINE void rasterizeTriangle(const int LX, const int LY, const RasterizerVec4 &V0, const RasterizerVec4 &V1, const RasterizerVec4 &V2, const int32_t offset_x, const int32_t offset_y, const RASTERIZER_PARAMS &data)
Fast triangle rasterizer for 3D graphics:
Definition: Rasterizer.h:142
Triangle shader parameters.
Generic 2D vector [specializations iVec2, fVec2, dVec2].
Definition: Vec2.h:64
T x
'x' coordinate (first dimension)
Definition: Vec2.h:72
T y
'y' coordinate (second dimension)
Definition: Vec2.h:73