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))
107 template<
typename SHADER_FUNCTION,
typename RASTERIZER_PARAMS>
108 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, SHADER_FUNCTION shader_fun)
112 const float mx = (float)(TGX_RASTERIZE_MULT128(LX));
113 const float my = (float)(TGX_RASTERIZE_MULT128(LY));
114 const iVec2 P0((int32_t)floorf(V0.x * mx), (int32_t)floorf(V0.y * my));
115 const iVec2 sP1((int32_t)floorf(V1.x * mx), (int32_t)floorf(V1.y * my));
116 const iVec2 sP2((int32_t)floorf(V2.x * mx), (int32_t)floorf(V2.y * my));
118 const int32_t umx =
min(
min(P0.
x, sP1.
x), sP2.
x);
119 const int32_t uMx =
max(
max(P0.
x, sP1.
x), sP2.
x);
120 const int32_t umy =
min(
min(P0.
y, sP1.
y), sP2.
y);
121 const int32_t uMy =
max(
max(P0.
y, sP1.
y), sP2.
y);
123 const bool c32 = ((uMx - umx < 32768) && (uMy - umy < 32768));
127 a = (((sP2.
x - P0.
x) * (sP1.
y - P0.
y)) - ((sP2.
y - P0.
y) * (sP1.
x - P0.
x)));
132 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)));
133 if (a64 == 0)
return;
134 a = (a64 > 0) ? 1 : -1;
137 int32_t xmin = (umx + TGX_RASTERIZE_MULT128(LX)) / TGX_RASTERIZE_SUBPIXEL256;
138 int32_t xmax = (uMx + TGX_RASTERIZE_MULT128(LX)) / TGX_RASTERIZE_SUBPIXEL256;
139 int32_t ymin = (umy + TGX_RASTERIZE_MULT128(LY)) / TGX_RASTERIZE_SUBPIXEL256;
140 int32_t ymax = (uMy + TGX_RASTERIZE_MULT128(LY)) / TGX_RASTERIZE_SUBPIXEL256;
143 int32_t sx = data.im->lx();
144 int32_t sy = data.im->ly();
145 int32_t ox = offset_x;
146 int32_t oy = offset_y;
147 if (ox < xmin) { sx -= (xmin - ox); ox = xmin; }
148 if (ox + sx > xmax) { sx = xmax - ox + 1; }
150 if (oy < ymin) { sy -= (ymin - oy); oy = ymin; }
151 if (oy + sy > ymax) { sy = ymax - oy + 1; }
154 const RasterizerVec4& fP1 = (a > 0) ? V1 : V2;
155 const RasterizerVec4& fP2 = (a > 0) ? V2 : V1;
156 const iVec2& P1 = (a > 0) ? sP1 : sP2;
157 const iVec2& P2 = (a > 0) ? sP2 : sP1;
159 const int32_t us = TGX_RASTERIZE_MULT256(ox) - TGX_RASTERIZE_MULT128(LX) + TGX_RASTERIZE_SUBPIXEL128;
160 const int32_t vs = TGX_RASTERIZE_MULT256(oy) - TGX_RASTERIZE_MULT128(LY) + TGX_RASTERIZE_SUBPIXEL128;
165 int32_t dx1 = P1.
y - P0.
y;
166 int32_t dy1 = P0.
x - P1.
x;
167 int32_t dx2 = P2.
y - P1.
y;
168 int32_t dy2 = P1.
x - P2.
x;
169 int32_t dx3 = P0.
y - P2.
y;
170 int32_t dy3 = P2.
x - P0.
x;
176 O1 = ((us - P0.
x) * dx1) + ((vs - P0.
y) * dy1);
177 if ((dx1 < 0) || ((dx1 == 0) && (dy1 < 0))) O1--;
179 O2 = ((us - P1.
x) * dx2) + ((vs - P1.
y) * dy2);
180 if ((dx2 < 0) || ((dx2 == 0) && (dy2 < 0))) O2--;
182 O3 = ((us - P2.
x) * dx3) + ((vs - P2.
y) * dy3);
183 if ((dx3 < 0) || ((dx3 == 0) && (dy3 < 0))) O3--;
185 dx1 *= (TGX_RASTERIZE_SUBPIXEL256);
186 dy1 *= (TGX_RASTERIZE_SUBPIXEL256);
187 dx2 *= (TGX_RASTERIZE_SUBPIXEL256);
188 dy2 *= (TGX_RASTERIZE_SUBPIXEL256);
189 dx3 *= (TGX_RASTERIZE_SUBPIXEL256);
190 dy3 *= (TGX_RASTERIZE_SUBPIXEL256);
194 int64_t dO1 = (((int64_t)(us - P0.
x)) * ((int64_t)dx1)) + (((int64_t)(vs - P0.
y)) * ((int64_t)dy1));
195 if ((dx1 < 0) || ((dx1 == 0) && (dy1 < 0))) dO1--;
196 O1 = (dO1 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO1)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO1 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
198 int64_t dO2 = (((int64_t)(us - P1.
x)) * ((int64_t)dx2)) + (((int64_t)(vs - P1.
y)) * ((int64_t)dy2));
199 if ((dx2 < 0) || ((dx2 == 0) && (dy2 < 0))) dO2--;
200 O2 = (dO2 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO2)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO2 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
202 int64_t dO3 = (((int64_t)(us - P2.
x)) * ((int64_t)dx3)) + (((int64_t)(vs - P2.
y)) * ((int64_t)dy3));
203 if ((dx3 < 0) || ((dx3 == 0) && (dy3 < 0))) dO3--;
204 O3 = (dO3 >= 0) ? ((int32_t)TGX_RASTERIZE_DIV256(dO3)) : -((int32_t)TGX_RASTERIZE_DIV256(-dO3 + (TGX_RASTERIZE_SUBPIXEL256 - 1)));
212 while (((O1 | O2 | O3) < 0) && (sy > 0))
224 while (((O1 | O2 | O3) < 0) && (sx > 0))
238 shader_fun(ox + (data.im->stride() * oy), sx, sy,
246 shader_fun(ox + (data.im->stride() * oy), sx, sy,
254 shader_fun(ox + (data.im->stride() * oy), sx, sy,
TGX_INLINE T min(const T &a, const T &b)
Don't know why but faster than fminf() for floats.
Definition: Misc.h:180
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:184
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, SHADER_FUNCTION shader_fun)
Fast triangle rasterizer for 3D graphics:
Definition: Rasterizer.h:108
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