| TGX 1.0.5 A tiny 2D/3D graphics library optimized for 32 bits microcontrollers.

Loading...
Searching...
No Matches
Shaders.h
Go to the documentation of this file.
1
5//
6// Copyright 2020 Arvind Singh
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11// version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; If not, see <http://www.gnu.org/licenses/>.
20#ifndef _TGX_SHADERS_H_
21#define _TGX_SHADERS_H_
22
23
24// only C++, no plain C
25#ifdef __cplusplus
26
27
28#include "ShaderParams.h"
29
30 namespace tgx
31{
32
34 inline TGX_INLINE int shaderclip(int v, int maxv)
35 {
36 return ((v < 0) ? 0 : ((v > maxv) ? maxv : v));
37 }
38
39
40
44 template<typename color_t, typename ZBUFFER_t>
45 void shader_test(const int32_t& offset, const int32_t& lx, const int32_t& ly,
46 const int32_t& dx1, const int32_t& dy1, int32_t O1, const tgx::RasterizerVec4& fP1,
47 const int32_t& dx2, const int32_t& dy2, int32_t O2, const tgx::RasterizerVec4& fP2,
48 const int32_t& dx3, const int32_t& dy3, int32_t O3, const tgx::RasterizerVec4& fP3,
49 const tgx::RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
50 {
51 color_t col = (color_t)tgx::RGB32_Red; //data.facecolor;
52 color_t* buf = data.im->data() + offset;
53 const int32_t stride = data.im->stride();
54 for (int y = 0; y < ly; y++)
55 {
56 for (int x = 0; x < lx; x++)
57 {
58 const int32_t o1 = O1 + dx1 * x + dy1 * y;
59 const int32_t o2 = O2 + dx2 * x + dy2 * y;
60 const int32_t o3 = O3 + dx3 * x + dy3 * y;
61 if ((o1 >= 0) && (o2 >= 0) && (o3 >= 0))
62 {
63 buf[x + stride * y].blend256(col, 128);
64 }
65 }
66 }
67 }
68
69
73 template<typename color_t, typename ZBUFFER_t>
74 void shader_Flat(const int32_t& offset, const int32_t& lx, const int32_t& ly,
75 const int32_t& dx1, const int32_t& dy1, int32_t O1, const RasterizerVec4& fP1,
76 const int32_t& dx2, const int32_t& dy2, int32_t O2, const RasterizerVec4& fP2,
77 const int32_t& dx3, const int32_t& dy3, int32_t O3, const RasterizerVec4& fP3,
78 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
79 {
80 color_t col = (color_t)data.facecolor;
81 color_t* buf = data.im->data() + offset;
82 const int32_t stride = data.im->stride();
83
84 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
85
86 while ((uintptr_t)(buf) < end)
87 { // iterate over scanlines
88 int32_t bx = 0; // start offset
89 if (O1 < 0)
90 {
91 // we know that dx1 > 0
92 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
93 }
94 if (O2 < 0)
95 {
96 if (dx2 <= 0)
97 {
98 if (dy2 <= 0) return;
99 const int32_t by = (-O2 + dy2 - 1u) / dy2;
100 O1 += (by * dy1);
101 O2 += (by * dy2);
102 O3 += (by * dy3);
103 const int32_t offs = by * stride;
104 buf += offs;
105 continue;
106 }
107 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
108 bx = max(bx, bx2);
109 }
110 if (O3 < 0)
111 {
112 if (dx3 <= 0)
113 {
114 if (dy3 <= 0) return;
115 const int32_t by = (-O3 + dy3 - 1u) / dy3;
116 O1 += (by * dy1);
117 O2 += (by * dy2);
118 O3 += (by * dy3);
119 const int32_t offs = by * stride;
120 buf += offs;
121 continue;
122 }
123 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
124 bx = max(bx, bx3);
125 }
126
127 int32_t C2 = O2 + (dx2 * bx);
128 int32_t C3 = O3 + (dx3 * bx);
129 while ((bx < lx) && ((C2 | C3) >= 0))
130 {
131 buf[bx] = col;
132 //buf[bx].blend256(col, 128) // for testing.
133 C2 += dx2;
134 C3 += dx3;
135 bx++;
136 }
137
138 O1 += dy1;
139 O2 += dy2;
140 O3 += dy3;
141 buf += stride;
142 }
143 }
144
145
146
150 template<typename color_t, typename ZBUFFER_t>
151 void shader_Gouraud(const int32_t& offset, const int32_t& lx, const int32_t& ly,
152 const int32_t& dx1, const int32_t& dy1, int32_t O1, const RasterizerVec4& fP1,
153 const int32_t& dx2, const int32_t& dy2, int32_t O2, const RasterizerVec4& fP2,
154 const int32_t& dx3, const int32_t& dy3, int32_t O3, const RasterizerVec4& fP3,
155 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
156 {
157 color_t* buf = data.im->data() + offset;
158 const int32_t stride = data.im->stride();
159
160 const color_t col1 = (color_t)fP1.color;
161 const color_t col2 = (color_t)fP2.color;
162 const color_t col3 = (color_t)fP3.color;
163
164 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
165 const int32_t pa = O1 + O2 + O3;
166 const int32_t E = ((pa == 0) ? 1 : 0);
167 const int32_t aera = pa + E;
168 const int shiftC = (aera > (1 << 22)) ? 10 : 0; // prevent overflow during color interpolation
169
170 while ((uintptr_t)(buf) < end)
171 { // iterate over scanlines
172 int32_t bx = 0; // start offset
173 if (O1 < 0)
174 {
175 // we know that dx1 > 0
176 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
177 }
178 if (O2 < 0)
179 {
180 if (dx2 <= 0)
181 {
182 if (dy2 <= 0) return;
183 const int32_t by = (-O2 + dy2 - 1u) / dy2;
184 O1 += (by * dy1);
185 O2 += (by * dy2);
186 O3 += (by * dy3);
187 const int32_t offs = by * stride;
188 buf += offs;
189 continue;
190 }
191 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
192 bx = max(bx, bx2);
193 }
194 if (O3 < 0)
195 {
196 if (dx3 <= 0)
197 {
198 if (dy3 <= 0) return;
199 const int32_t by = (-O3 + dy3 - 1u) / dy3;
200 O1 += (by * dy1);
201 O2 += (by * dy2);
202 O3 += (by * dy3);
203 const int32_t offs = by * stride;
204 buf += offs;
205 continue;
206 }
207 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
208 bx = max(bx, bx3);
209 }
210
211 int32_t C2 = O2 + (dx2 * bx);
212 int32_t C3 = O3 + (dx3 * bx);
213 while ((bx < lx) && ((C2 | C3) >= 0))
214 {
215 buf[bx] = interpolateColorsTriangle(col2, C2 >> shiftC, col3, C3 >> shiftC, col1, aera >> shiftC);
216 C2 += dx2;
217 C3 += dx3;
218 bx++;
219 }
220
221 O1 += dy1;
222 O2 += dy2;
223 O3 += dy3;
224 buf += stride;
225 }
226 }
227
228
229
233 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
234 void shader_Flat_Texture(const int32_t& offset, const int32_t& lx, const int32_t& ly,
235 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
236 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
237 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
238 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
239 {
240 color_t* buf = data.im->data() + offset;
241 const int32_t stride = data.im->stride();
242
243 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
244 const int32_t pa = O1 + O2 + O3;
245 const int32_t E = ((pa == 0) ? 1 : 0);
246 const int32_t aera = pa + E;
247
248
249 const float invaera = fast_inv((float)aera);
250 const float fP1a = fP1.w * invaera;
251 const float fP2a = fP2.w * invaera;
252 const float fP3a = fP3.w * invaera;
253
254 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
255
256 const RGBf& cf = (RGBf)data.facecolor;
257 const int fPR = (int)(256 * cf.R);
258 const int fPG = (int)(256 * cf.G);
259 const int fPB = (int)(256 * cf.B);
260
261 // the texture coord
262 fVec2 T1 = fP1.T;
263 fVec2 T2 = fP2.T;
264 fVec2 T3 = fP3.T;
265
266 const color_t* tex = data.tex->data();
267 const int32_t texsize_x = data.tex->width();
268 const int32_t texsize_y = data.tex->height();
269 const int32_t texsize_x_mm = texsize_x - 1;
270 const int32_t texsize_y_mm = texsize_y - 1;
271 const int32_t texstride = data.tex->stride();
272
273 // divide the texture coord by z * aera
274 T1 *= fP1a;
275 T2 *= fP2a;
276 T3 *= fP3a;
277 T1.x *= texsize_x;
278 T2.x *= texsize_x;
279 T3.x *= texsize_x;
280 T1.y *= texsize_y;
281 T2.y *= texsize_y;
282 T3.y *= texsize_y;
283
284 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
285 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
286
287 while ((uintptr_t)(buf) < end)
288 { // iterate over scanlines
289 int32_t bx = 0; // start offset
290 if (O1 < 0)
291 {
292 // we know that dx1 > 0
293 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
294 }
295 if (O2 < 0)
296 {
297 if (dx2 <= 0)
298 {
299 if (dy2 <= 0) return;
300 const int32_t by = (-O2 + dy2 - 1u) / dy2;
301 O1 += (by * dy1);
302 O2 += (by * dy2);
303 O3 += (by * dy3);
304 const int32_t offs = by * stride;
305 buf += offs;
306 continue;
307 }
308 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
309 bx = max(bx, bx2);
310 }
311 if (O3 < 0)
312 {
313 if (dx3 <= 0)
314 {
315 if (dy3 <= 0) return;
316 const int32_t by = (-O3 + dy3 - 1u) / dy3;
317 O1 += (by * dy1);
318 O2 += (by * dy2);
319 O3 += (by * dy3);
320 const int32_t offs = by * stride;
321 buf += offs;
322 continue;
323 }
324 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
325 bx = max(bx, bx3);
326 }
327
328 int32_t C1 = O1 + (dx1 * bx) + E;
329 int32_t C2 = O2 + (dx2 * bx);
330 int32_t C3 = O3 + (dx3 * bx);
331 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
332
333 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
334 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
335
336 while ((bx < lx) && ((C2 | C3) >= 0))
337 {
338 const float icw = fast_inv(cw);
339
340 color_t col;
341 if (TEXTURE_BILINEAR)
342 {
343 const float xx = tx * icw;
344 const float yy = ty * icw;
345 const int ttx = lfloorf(xx);
346 const int tty = lfloorf(yy);
347 const float ax = xx - ttx;
348 const float ay = yy - tty;
349 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
350 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
351 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm))*texstride) : shaderclip(tty, texsize_y_mm) * texstride);
352 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm))*texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
353 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
354 }
355 else
356 {
357 const int ttx = (TEXTURE_WRAP ? ((int)((tx * icw))) & (texsize_x_mm) : shaderclip((int)(tx * icw), texsize_x_mm));
358 const int tty = (TEXTURE_WRAP ? ((int)((ty * icw))) & (texsize_y_mm) : shaderclip((int)(ty * icw), texsize_y_mm));
359 col = tex[ttx + (tty)*texstride];
360 }
361
362 col.mult256(fPR, fPG, fPB);
363 buf[bx] = col;
364
365 C2 += dx2;
366 C3 += dx3;
367 cw += dw;
368
369 tx += dtx;
370 ty += dty;
371
372 bx++;
373 }
374
375 O1 += dy1;
376 O2 += dy2;
377 O3 += dy3;
378 buf += stride;
379 }
380 }
381
382
383
387 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
388 void shader_Gouraud_Texture(const int32_t& offset, const int32_t& lx, const int32_t& ly,
389 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
390 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
391 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
392 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
393 {
394
395 color_t* buf = data.im->data() + offset;
396 const int32_t stride = data.im->stride();
397
398 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
399 const int32_t pa = O1 + O2 + O3;
400 const int32_t E = ((pa == 0) ? 1 : 0);
401 const int32_t aera = pa + E;
402
403 const float invaera = fast_inv((float)aera);
404 const float fP1a = fP1.w * invaera;
405 const float fP2a = fP2.w * invaera;
406 const float fP3a = fP3.w * invaera;
407
408 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
409
410 const RGBf& cf1 = (RGBf)fP1.color;
411 const RGBf& cf2 = (RGBf)fP2.color;
412 const RGBf& cf3 = (RGBf)fP3.color;
413 const int fP1R = (int)(256 * cf1.R);
414 const int fP1G = (int)(256 * cf1.G);
415 const int fP1B = (int)(256 * cf1.B);
416 const int fP21R = (int)(256 * (cf2.R - cf1.R));
417 const int fP21G = (int)(256 * (cf2.G - cf1.G));
418 const int fP21B = (int)(256 * (cf2.B - cf1.B));
419 const int fP31R = (int)(256 * (cf3.R - cf1.R));
420 const int fP31G = (int)(256 * (cf3.G - cf1.G));
421 const int fP31B = (int)(256 * (cf3.B - cf1.B));
422
423 // the texture coord
424 fVec2 T1 = fP1.T;
425 fVec2 T2 = fP2.T;
426 fVec2 T3 = fP3.T;
427
428 const color_t* tex = data.tex->data();
429 const int32_t texsize_x = data.tex->width();
430 const int32_t texsize_y = data.tex->height();
431 const int32_t texsize_x_mm = texsize_x - 1;
432 const int32_t texsize_y_mm = texsize_y - 1;
433 const int32_t texstride = data.tex->stride();
434
435 // divide the texture coord by z * aera
436 T1 *= fP1a;
437 T2 *= fP2a;
438 T3 *= fP3a;
439 T1.x *= texsize_x;
440 T2.x *= texsize_x;
441 T3.x *= texsize_x;
442 T1.y *= texsize_y;
443 T2.y *= texsize_y;
444 T3.y *= texsize_y;
445
446
447 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
448 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
449
450 while ((uintptr_t)(buf) < end)
451 { // iterate over scanlines
452 int32_t bx = 0; // start offset
453 if (O1 < 0)
454 {
455 // we know that dx1 > 0
456 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
457 }
458 if (O2 < 0)
459 {
460 if (dx2 <= 0)
461 {
462 if (dy2 <= 0) return;
463 const int32_t by = (-O2 + dy2 - 1u) / dy2;
464 O1 += (by * dy1);
465 O2 += (by * dy2);
466 O3 += (by * dy3);
467 const int32_t offs = by * stride;
468 buf += offs;
469 continue;
470 }
471 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
472 bx = max(bx, bx2);
473 }
474 if (O3 < 0)
475 {
476 if (dx3 <= 0)
477 {
478 if (dy3 <= 0) return;
479 const int32_t by = (-O3 + dy3 - 1u) / dy3;
480 O1 += (by * dy1);
481 O2 += (by * dy2);
482 O3 += (by * dy3);
483 const int32_t offs = by * stride;
484 buf += offs;
485 continue;
486 }
487 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
488 bx = max(bx, bx3);
489 }
490
491 int32_t C1 = O1 + (dx1 * bx) + E;
492 int32_t C2 = O2 + (dx2 * bx);
493 int32_t C3 = O3 + (dx3 * bx);
494 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
495
496 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
497 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
498
499 while ((bx < lx) && ((C2 | C3) >= 0))
500 {
501 const float icw = fast_inv(cw);
502
503 color_t col;
504 if (TEXTURE_BILINEAR)
505 {
506 const float xx = tx * icw;
507 const float yy = ty * icw;
508 const int ttx = lfloorf(xx);
509 const int tty = lfloorf(yy);
510 const float ax = xx - ttx;
511 const float ay = yy - tty;
512 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
513 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
514 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
515 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
516 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
517 }
518 else
519 {
520 const int ttx = (TEXTURE_WRAP ? ((int)((tx * icw))) & (texsize_x_mm) : shaderclip((int)(tx * icw), texsize_x_mm));
521 const int tty = (TEXTURE_WRAP ? ((int)((ty * icw))) & (texsize_y_mm) : shaderclip((int)(ty * icw), texsize_y_mm));
522 col = tex[ttx + (tty)*texstride];
523 }
524
525 const int r = fP1R + ((C2 * fP21R + C3 * fP31R) / aera);
526 const int g = fP1G + ((C2 * fP21G + C3 * fP31G) / aera);
527 const int b = fP1B + ((C2 * fP21B + C3 * fP31B) / aera);
528
529 col.mult256(r, g, b);
530 buf[bx] = col;
531
532 C2 += dx2;
533 C3 += dx3;
534 cw += dw;
535
536 tx += dtx;
537 ty += dty;
538
539 bx++;
540 }
541
542 O1 += dy1;
543 O2 += dy2;
544 O3 += dy3;
545 buf += stride;
546 }
547 }
548
549
550
554 template<typename color_t, typename ZBUFFER_t>
555 void shader_Flat_Zbuffer(const int32_t offset, const int32_t& lx, const int32_t& ly,
556 const int32_t& dx1, const int32_t& dy1, int32_t O1, const RasterizerVec4& fP1,
557 const int32_t& dx2, const int32_t& dy2, int32_t O2, const RasterizerVec4& fP2,
558 const int32_t& dx3, const int32_t& dy3, int32_t O3, const RasterizerVec4& fP3,
559 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
560 {
561 const color_t col = (color_t)data.facecolor;
562 color_t* buf = data.im->data() + offset;
563 ZBUFFER_t * zbuf = data.zbuf + offset;
564
565 const int32_t stride = data.im->stride();
566 const int32_t zstride = data.im->lx();
567
568 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
569 const int32_t pa = O1 + O2 + O3;
570 const int32_t E = ((pa == 0) ? 1 : 0);
571 const int32_t aera = pa + E;
572
573 const float wa = data.wa;
574 const float wb = data.wb;
575 const float invaera = fast_inv((float)aera);
576 const float invaera_wa = invaera * wa;
577 const float fP1a = fP1.w * invaera_wa;
578 const float fP2a = fP2.w * invaera_wa;
579 const float fP3a = fP3.w * invaera_wa;
580 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
581
582 while ((uintptr_t)(buf) < end)
583 { // iterate over scanlines
584 int32_t bx = 0; // start offset
585 if (O1 < 0)
586 {
587 // we know that dx1 > 0
588 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
589 }
590 if (O2 < 0)
591 {
592 if (dx2 <= 0)
593 {
594 if (dy2 <= 0) return;
595 const int32_t by = (-O2 + dy2 - 1u) / dy2;
596 O1 += (by * dy1);
597 O2 += (by * dy2);
598 O3 += (by * dy3);
599 const int32_t offs = by * stride;
600 buf += offs;
601 zbuf += offs;
602 continue;
603 }
604 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
605 bx = max(bx, bx2);
606 }
607 if (O3 < 0)
608 {
609 if (dx3 <= 0)
610 {
611 if (dy3 <= 0) return;
612 const int32_t by = (-O3 + dy3 - 1u) / dy3;
613 O1 += (by * dy1);
614 O2 += (by * dy2);
615 O3 += (by * dy3);
616 const int32_t offs = by * stride;
617 buf += offs;
618 zbuf += offs;
619 continue;
620 }
621 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
622 bx = max(bx, bx3);
623 }
624
625 const int32_t C1 = O1 + (dx1 * bx) + E;
626 int32_t C2 = O2 + (dx2 * bx);
627 int32_t C3 = O3 + (dx3 * bx);
628 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a)) + wb;
629
630 while ((bx < lx) && ((C2 | C3) >= 0))
631 {
632 ZBUFFER_t& W = zbuf[bx];
633 const ZBUFFER_t aa = (ZBUFFER_t)(cw);
634 if (W < aa)
635 {
636 W = aa;
637 buf[bx] = col;
638 }
639 C2 += dx2;
640 C3 += dx3;
641 cw += dw;
642 bx++;
643 }
644
645 O1 += dy1;
646 O2 += dy2;
647 O3 += dy3;
648 buf += stride;
649 zbuf += zstride;
650 }
651 }
652
653
654
658 template<typename color_t, typename ZBUFFER_t, int shiftC>
659 void shader_Gouraud_Zbuffer_sub(const int32_t& offset, const int32_t& lx, const int32_t& ly,
660 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
661 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
662 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
663 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
664 {
665 color_t* buf = data.im->data() + offset;
666 ZBUFFER_t* zbuf = data.zbuf + offset;
667
668
669 const int32_t stride = data.im->stride();
670 const int32_t zstride = data.im->lx();
671
672 const color_t col1 = (color_t)fP1.color;
673 const color_t col2 = (color_t)fP2.color;
674 const color_t col3 = (color_t)fP3.color;
675
676 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
677 const int32_t pa = O1 + O2 + O3;
678 const int32_t E = ((pa == 0) ? 1 : 0);
679 const int32_t aera = pa + E;
680 const int32_t aeraShifted = aera >> shiftC;
681
682 const float wa = data.wa;
683 const float wb = data.wb;
684 const float invaera = fast_inv((float)aera);
685 const float invaera_wa = invaera * wa;
686 const float fP1a = fP1.w * invaera_wa;
687 const float fP2a = fP2.w * invaera_wa;
688 const float fP3a = fP3.w * invaera_wa;
689 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
690
691 while ((uintptr_t)(buf) < end)
692 { // iterate over scanlines
693 int32_t bx = 0; // start offset
694 if (O1 < 0)
695 {
696 // we know that dx1 > 0
697 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
698 }
699 if (O2 < 0)
700 {
701 if (dx2 <= 0)
702 {
703 if (dy2 <= 0) return;
704 const int32_t by = (-O2 + dy2 - 1u) / dy2;
705 O1 += (by * dy1);
706 O2 += (by * dy2);
707 O3 += (by * dy3);
708 const int32_t offs = by * stride;
709 buf += offs;
710 zbuf += offs;
711 continue;
712 }
713 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
714 bx = max(bx, bx2);
715 }
716 if (O3 < 0)
717 {
718 if (dx3 <= 0)
719 {
720 if (dy3 <= 0) return;
721 const int32_t by = (-O3 + dy3 - 1u) / dy3;
722 O1 += (by * dy1);
723 O2 += (by * dy2);
724 O3 += (by * dy3);
725 const int32_t offs = by * stride;
726 buf += offs;
727 zbuf += offs;
728 continue;
729 }
730 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
731 bx = max(bx, bx3);
732 }
733
734 const int32_t C1 = O1 + (dx1 * bx) + E;
735 int32_t C2 = O2 + (dx2 * bx);
736 int32_t C3 = O3 + (dx3 * bx);
737 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a)) + wb;
738
739 while ((bx < lx) && ((C2 | C3) >= 0))
740 {
741 ZBUFFER_t& W = zbuf[bx];
742 const ZBUFFER_t aa = (ZBUFFER_t)(cw);
743 if (W < aa)
744 {
745 W = aa;
746 buf[bx] = interpolateColorsTriangle(col2, C2 >> shiftC, col3, C3 >> shiftC , col1, aeraShifted);
747 }
748 C2 += dx2;
749 C3 += dx3;
750 cw += dw;
751 bx++;
752 }
753
754 O1 += dy1;
755 O2 += dy2;
756 O3 += dy3;
757 buf += stride;
758 zbuf += zstride;
759 }
760 }
761
765 template<typename color_t, typename ZBUFFER_t>
766 void shader_Gouraud_Zbuffer(const int32_t& offset, const int32_t& lx, const int32_t& ly,
767 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
768 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
769 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
770 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
771
772 {
773 if (O1 + O2 + O3 > (1 << 24))
774 { // large aera, use interpolateColorsTriangle<true>
775 shader_Gouraud_Zbuffer_sub<color_t, ZBUFFER_t, 10>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
776 }
777 else
778 { // small aera, use interpolateColorsTriangle<false>
779 shader_Gouraud_Zbuffer_sub<color_t, ZBUFFER_t, 0>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
780 }
781 }
782
783
784
788 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
789 void shader_Flat_Texture_Zbuffer(const int32_t& offset, const int32_t& lx, const int32_t& ly,
790 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
791 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
792 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
793 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
794 {
795 color_t* buf = data.im->data() + offset;
796 ZBUFFER_t* zbuf = data.zbuf + offset;
797
798 const float wa = data.wa;
799 const float wb = data.wb;
800 (void)wa; // silence possible unused warnings
801 (void)wb; //
802
803
804 const int32_t stride = data.im->stride();
805 const int32_t zstride = data.im->lx();
806
807 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
808 const int32_t pa = O1 + O2 + O3;
809 const int32_t E = ((pa == 0) ? 1 : 0);
810 const int32_t aera = pa + E;
811
812 const float invaera = fast_inv((float)aera);
813 const float fP1a = fP1.w * invaera;
814 const float fP2a = fP2.w * invaera;
815 const float fP3a = fP3.w * invaera;
816
817 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
818
819 const RGBf& cf = (RGBf)data.facecolor;
820 const int fPR = (int)(256 * cf.R);
821 const int fPG = (int)(256 * cf.G);
822 const int fPB = (int)(256 * cf.B);
823
824 // the texture coord
825 fVec2 T1 = fP1.T;
826 fVec2 T2 = fP2.T;
827 fVec2 T3 = fP3.T;
828
829 const color_t* tex = data.tex->data();
830 const int32_t texsize_x = data.tex->width();
831 const int32_t texsize_y = data.tex->height();
832 const int32_t texsize_x_mm = texsize_x - 1;
833 const int32_t texsize_y_mm = texsize_y - 1;
834 const int32_t texstride = data.tex->stride();
835
836 // divide the texture coord by z * aera
837 T1 *= fP1a;
838 T2 *= fP2a;
839 T3 *= fP3a;
840 T1.x *= texsize_x;
841 T2.x *= texsize_x;
842 T3.x *= texsize_x;
843 T1.y *= texsize_y;
844 T2.y *= texsize_y;
845 T3.y *= texsize_y;
846
847 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
848 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
849
850 while ((uintptr_t)(buf) < end)
851 { // iterate over scanlines
852 int32_t bx = 0; // start offset
853 if (O1 < 0)
854 {
855 // we know that dx1 > 0
856 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
857 }
858 if (O2 < 0)
859 {
860 if (dx2 <= 0)
861 {
862 if (dy2 <= 0) return;
863 const int32_t by = (-O2 + dy2 - 1u) / dy2;
864 O1 += (by * dy1);
865 O2 += (by * dy2);
866 O3 += (by * dy3);
867 const int32_t offs = by * stride;
868 buf += offs;
869 zbuf += offs;
870 continue;
871 }
872 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
873 bx = max(bx, bx2);
874 }
875 if (O3 < 0)
876 {
877 if (dx3 <= 0)
878 {
879 if (dy3 <= 0) return;
880 const int32_t by = (-O3 + dy3 - 1u) / dy3;
881 O1 += (by * dy1);
882 O2 += (by * dy2);
883 O3 += (by * dy3);
884 const int32_t offs = by * stride;
885 buf += offs;
886 zbuf += offs;
887 continue;
888 }
889 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
890 bx = max(bx, bx3);
891 }
892
893 int32_t C1 = O1 + (dx1 * bx) + E;
894 int32_t C2 = O2 + (dx2 * bx);
895 int32_t C3 = O3 + (dx3 * bx);
896 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
897
898 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
899 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
900
901 while ((bx < lx) && ((C2 | C3) >= 0))
902 {
903 ZBUFFER_t& W = zbuf[bx];
904 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(cw * wa + wb)) : ((ZBUFFER_t)cw);
905 if (W < aa)
906 {
907 W = aa;
908 const float icw = fast_inv(cw);
909 color_t col;
910 if (TEXTURE_BILINEAR)
911 {
912 const float xx = tx * icw;
913 const float yy = ty * icw;
914 const int ttx = lfloorf(xx);
915 const int tty = lfloorf(yy);
916 const float ax = xx - ttx;
917 const float ay = yy - tty;
918 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
919 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
920 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
921 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
922 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
923 }
924 else
925 {
926 const int ttx = (TEXTURE_WRAP ? ((int)((tx * icw))) & (texsize_x_mm) : shaderclip((int)(tx * icw), texsize_x_mm));
927 const int tty = (TEXTURE_WRAP ? ((int)((ty * icw))) & (texsize_y_mm) : shaderclip((int)(ty * icw), texsize_y_mm));
928 col = tex[ttx + (tty)*texstride];
929 }
930
931 col.mult256(fPR, fPG, fPB);
932 buf[bx] = col;
933 }
934
935 C2 += dx2;
936 C3 += dx3;
937 cw += dw;
938
939 tx += dtx;
940 ty += dty;
941
942 bx++;
943 }
944
945 O1 += dy1;
946 O2 += dy2;
947 O3 += dy3;
948 buf += stride;
949 zbuf += zstride;
950 }
951 }
952
953
954
958 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
959 void shader_Gouraud_Texture_Zbuffer(const int32_t& offset, const int32_t& lx, const int32_t& ly,
960 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
961 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
962 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
963 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
964 {
965 color_t* buf = data.im->data() + offset;
966 ZBUFFER_t* zbuf = data.zbuf + offset;
967
968 const float wa = data.wa;
969 const float wb = data.wb;
970 (void)wa; // silence possible unused warnings
971 (void)wb; //
972
973 const int32_t stride = data.im->stride();
974 const int32_t zstride = data.im->lx();
975
976 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
977 const int32_t pa = O1 + O2 + O3;
978 const int32_t E = ((pa == 0) ? 1 : 0);
979 const int32_t aera = pa + E;
980
981 const float invaera = fast_inv((float)aera);
982 const float fP1a = fP1.w * invaera;
983 const float fP2a = fP2.w * invaera;
984 const float fP3a = fP3.w * invaera;
985
986 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
987
988 const RGBf& cf1 = (RGBf)fP1.color;
989 const RGBf& cf2 = (RGBf)fP2.color;
990 const RGBf& cf3 = (RGBf)fP3.color;
991 const int fP1R = (int)(256 * cf1.R);
992 const int fP1G = (int)(256 * cf1.G);
993 const int fP1B = (int)(256 * cf1.B);
994 const int fP21R = (int)(256 * (cf2.R - cf1.R));
995 const int fP21G = (int)(256 * (cf2.G - cf1.G));
996 const int fP21B = (int)(256 * (cf2.B - cf1.B));
997 const int fP31R = (int)(256 * (cf3.R - cf1.R));
998 const int fP31G = (int)(256 * (cf3.G - cf1.G));
999 const int fP31B = (int)(256 * (cf3.B - cf1.B));
1000
1001 // the texture coord
1002 fVec2 T1 = fP1.T;
1003 fVec2 T2 = fP2.T;
1004 fVec2 T3 = fP3.T;
1005
1006 const color_t* tex = data.tex->data();
1007 const int32_t texsize_x = data.tex->width();
1008 const int32_t texsize_y = data.tex->height();
1009 const int32_t texsize_x_mm = texsize_x - 1;
1010 const int32_t texsize_y_mm = texsize_y - 1;
1011 const int32_t texstride = data.tex->stride();
1012
1013 // divide the texture coord by z * aera
1014 T1 *= fP1a;
1015 T2 *= fP2a;
1016 T3 *= fP3a;
1017 T1.x *= texsize_x;
1018 T2.x *= texsize_x;
1019 T3.x *= texsize_x;
1020 T1.y *= texsize_y;
1021 T2.y *= texsize_y;
1022 T3.y *= texsize_y;
1023
1024 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
1025 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
1026
1027 while ((uintptr_t)(buf) < end)
1028 { // iterate over scanlines
1029 int32_t bx = 0; // start offset
1030 if (O1 < 0)
1031 {
1032 // we know that dx1 > 0
1033 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
1034 }
1035 if (O2 < 0)
1036 {
1037 if (dx2 <= 0)
1038 {
1039 if (dy2 <= 0) return;
1040 const int32_t by = (-O2 + dy2 - 1u) / dy2;
1041 O1 += (by * dy1);
1042 O2 += (by * dy2);
1043 O3 += (by * dy3);
1044 const int32_t offs = by * stride;
1045 buf += offs;
1046 zbuf += offs;
1047 continue;
1048 }
1049 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
1050 bx = max(bx, bx2);
1051 }
1052 if (O3 < 0)
1053 {
1054 if (dx3 <= 0)
1055 {
1056 if (dy3 <= 0) return;
1057 const int32_t by = (-O3 + dy3 - 1u) / dy3;
1058 O1 += (by * dy1);
1059 O2 += (by * dy2);
1060 O3 += (by * dy3);
1061 const int32_t offs = by * stride;
1062 buf += offs;
1063 zbuf += offs;
1064 continue;
1065 }
1066 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
1067 bx = max(bx, bx3);
1068 }
1069 int32_t C1 = O1 + (dx1 * bx) + E;
1070 int32_t C2 = O2 + (dx2 * bx);
1071 int32_t C3 = O3 + (dx3 * bx);
1072 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
1073
1074 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
1075 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
1076
1077 while ((bx < lx) && ((C2 | C3) >= 0))
1078 {
1079 ZBUFFER_t& W = zbuf[bx];
1080 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(cw * wa + wb)) : ((ZBUFFER_t)cw);
1081 if (W < aa)
1082 {
1083 W = aa;
1084 const float icw = fast_inv(cw);
1085
1086 color_t col;
1087 if (TEXTURE_BILINEAR)
1088 {
1089 const float xx = tx * icw;
1090 const float yy = ty * icw;
1091 const int ttx = lfloorf(xx);
1092 const int tty = lfloorf(yy);
1093 const float ax = xx - ttx;
1094 const float ay = yy - tty;
1095 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
1096 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
1097 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
1098 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
1099 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
1100 }
1101 else
1102 {
1103 const int ttx = (TEXTURE_WRAP ? ((int)((tx * icw))) & (texsize_x_mm) : shaderclip((int)(tx * icw), texsize_x_mm));
1104 const int tty = (TEXTURE_WRAP ? ((int)((ty * icw))) & (texsize_y_mm) : shaderclip((int)(ty * icw), texsize_y_mm));
1105 col = tex[ttx + (tty)*texstride];
1106 }
1107
1108 const int r = fP1R + ((C2 * fP21R + C3 * fP31R) / aera);
1109 const int g = fP1G + ((C2 * fP21G + C3 * fP31G) / aera);
1110 const int b = fP1B + ((C2 * fP21B + C3 * fP31B) / aera);
1111 col.mult256(r, g, b);
1112 buf[bx] = col;
1113 }
1114
1115 C2 += dx2;
1116 C3 += dx3;
1117 cw += dw;
1118
1119 tx += dtx;
1120 ty += dty;
1121
1122 bx++;
1123 }
1124
1125 O1 += dy1;
1126 O2 += dy2;
1127 O3 += dy3;
1128 buf += stride;
1129 zbuf += zstride;
1130 }
1131 }
1132
1133
1134
1138 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
1139 void shader_Flat_Texture_Ortho(const int32_t& offset, const int32_t& lx, const int32_t& ly,
1140 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
1141 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
1142 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
1143 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
1144 {
1145 color_t* buf = data.im->data() + offset;
1146 const int32_t stride = data.im->stride();
1147
1148 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
1149 const int32_t pa = O1 + O2 + O3;
1150 const int32_t E = ((pa == 0) ? 1 : 0);
1151 const int32_t aera = pa + E;
1152
1153 const float invaera = fast_inv((float)aera);
1154
1155 const RGBf& cf = (RGBf)data.facecolor;
1156 const int fPR = (int)(256 * cf.R);
1157 const int fPG = (int)(256 * cf.G);
1158 const int fPB = (int)(256 * cf.B);
1159
1160 // the texture coord
1161 fVec2 T1 = fP1.T;
1162 fVec2 T2 = fP2.T;
1163 fVec2 T3 = fP3.T;
1164
1165 const color_t* tex = data.tex->data();
1166 const int32_t texsize_x = data.tex->width();
1167 const int32_t texsize_y = data.tex->height();
1168 const int32_t texsize_x_mm = texsize_x - 1;
1169 const int32_t texsize_y_mm = texsize_y - 1;
1170 const int32_t texstride = data.tex->stride();
1171
1172 // divide the texture coord by aera
1173 T1 *= invaera;
1174 T2 *= invaera;
1175 T3 *= invaera;
1176 T1.x *= texsize_x;
1177 T2.x *= texsize_x;
1178 T3.x *= texsize_x;
1179 T1.y *= texsize_y;
1180 T2.y *= texsize_y;
1181 T3.y *= texsize_y;
1182
1183 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
1184 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
1185
1186 while ((uintptr_t)(buf) < end)
1187 { // iterate over scanlines
1188 int32_t bx = 0; // start offset
1189 if (O1 < 0)
1190 {
1191 // we know that dx1 > 0
1192 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
1193 }
1194 if (O2 < 0)
1195 {
1196 if (dx2 <= 0)
1197 {
1198 if (dy2 <= 0) return;
1199 const int32_t by = (-O2 + dy2 - 1u) / dy2;
1200 O1 += (by * dy1);
1201 O2 += (by * dy2);
1202 O3 += (by * dy3);
1203 const int32_t offs = by * stride;
1204 buf += offs;
1205 continue;
1206 }
1207 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
1208 bx = max(bx, bx2);
1209 }
1210 if (O3 < 0)
1211 {
1212 if (dx3 <= 0)
1213 {
1214 if (dy3 <= 0) return;
1215 const int32_t by = (-O3 + dy3 - 1u) / dy3;
1216 O1 += (by * dy1);
1217 O2 += (by * dy2);
1218 O3 += (by * dy3);
1219 const int32_t offs = by * stride;
1220 buf += offs;
1221 continue;
1222 }
1223 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
1224 bx = max(bx, bx3);
1225 }
1226 int32_t C1 = O1 + (dx1 * bx) + E;
1227 int32_t C2 = O2 + (dx2 * bx);
1228 int32_t C3 = O3 + (dx3 * bx);
1229
1230 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
1231 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
1232
1233 while ((bx < lx) && ((C2 | C3) >= 0))
1234 {
1235
1236 color_t col;
1237 if (TEXTURE_BILINEAR)
1238 {
1239 const float xx = tx;
1240 const float yy = ty;
1241 const int ttx = lfloorf(xx);
1242 const int tty = lfloorf(yy);
1243 const float ax = xx - ttx;
1244 const float ay = yy - tty;
1245 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
1246 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
1247 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
1248 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
1249 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
1250 }
1251 else
1252 {
1253 const int ttx = (TEXTURE_WRAP ? ((int)((tx))) & (texsize_x_mm) : shaderclip((int)(tx), texsize_x_mm));
1254 const int tty = (TEXTURE_WRAP ? ((int)((ty))) & (texsize_y_mm) : shaderclip((int)(ty), texsize_y_mm));
1255 col = tex[ttx + (tty)*texstride];
1256 }
1257
1258 col.mult256(fPR, fPG, fPB);
1259 buf[bx] = col;
1260
1261 C2 += dx2;
1262 C3 += dx3;
1263
1264 tx += dtx;
1265 ty += dty;
1266
1267 bx++;
1268 }
1269
1270 O1 += dy1;
1271 O2 += dy2;
1272 O3 += dy3;
1273 buf += stride;
1274 }
1275 }
1276
1277
1278
1282 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
1283 void shader_Gouraud_Texture_Ortho(const int32_t& offset, const int32_t& lx, const int32_t& ly,
1284 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
1285 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
1286 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
1287 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
1288 {
1289 color_t* buf = data.im->data() + offset;
1290 const int32_t stride = data.im->stride();
1291
1292 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
1293 const int32_t pa = O1 + O2 + O3;
1294 const int32_t E = ((pa == 0) ? 1 : 0);
1295 const int32_t aera = pa + E;
1296
1297 const float invaera = fast_inv((float)aera);
1298
1299 const RGBf& cf1 = (RGBf)fP1.color;
1300 const RGBf& cf2 = (RGBf)fP2.color;
1301 const RGBf& cf3 = (RGBf)fP3.color;
1302 const int fP1R = (int)(256 * cf1.R);
1303 const int fP1G = (int)(256 * cf1.G);
1304 const int fP1B = (int)(256 * cf1.B);
1305 const int fP21R = (int)(256 * (cf2.R - cf1.R));
1306 const int fP21G = (int)(256 * (cf2.G - cf1.G));
1307 const int fP21B = (int)(256 * (cf2.B - cf1.B));
1308 const int fP31R = (int)(256 * (cf3.R - cf1.R));
1309 const int fP31G = (int)(256 * (cf3.G - cf1.G));
1310 const int fP31B = (int)(256 * (cf3.B - cf1.B));
1311
1312 // the texture coord
1313 fVec2 T1 = fP1.T;
1314 fVec2 T2 = fP2.T;
1315 fVec2 T3 = fP3.T;
1316
1317 const color_t* tex = data.tex->data();
1318 const int32_t texsize_x = data.tex->width();
1319 const int32_t texsize_y = data.tex->height();
1320 const int32_t texsize_x_mm = texsize_x - 1;
1321 const int32_t texsize_y_mm = texsize_y - 1;
1322 const int32_t texstride = data.tex->stride();
1323
1324 // divide the texture coord by aera
1325 T1 *= invaera;
1326 T2 *= invaera;
1327 T3 *= invaera;
1328 T1.x *= texsize_x;
1329 T2.x *= texsize_x;
1330 T3.x *= texsize_x;
1331 T1.y *= texsize_y;
1332 T2.y *= texsize_y;
1333 T3.y *= texsize_y;
1334
1335 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
1336 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
1337
1338 while ((uintptr_t)(buf) < end)
1339 { // iterate over scanlines
1340 int32_t bx = 0; // start offset
1341 if (O1 < 0)
1342 {
1343 // we know that dx1 > 0
1344 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
1345 }
1346 if (O2 < 0)
1347 {
1348 if (dx2 <= 0)
1349 {
1350 if (dy2 <= 0) return;
1351 const int32_t by = (-O2 + dy2 - 1u) / dy2;
1352 O1 += (by * dy1);
1353 O2 += (by * dy2);
1354 O3 += (by * dy3);
1355 const int32_t offs = by * stride;
1356 buf += offs;
1357 continue;
1358 }
1359 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
1360 bx = max(bx, bx2);
1361 }
1362 if (O3 < 0)
1363 {
1364 if (dx3 <= 0)
1365 {
1366 if (dy3 <= 0) return;
1367 const int32_t by = (-O3 + dy3 - 1u) / dy3;
1368 O1 += (by * dy1);
1369 O2 += (by * dy2);
1370 O3 += (by * dy3);
1371 const int32_t offs = by * stride;
1372 buf += offs;
1373 continue;
1374 }
1375 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
1376 bx = max(bx, bx3);
1377 }
1378
1379 int32_t C1 = O1 + (dx1 * bx) + E;
1380 int32_t C2 = O2 + (dx2 * bx);
1381 int32_t C3 = O3 + (dx3 * bx);
1382
1383 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
1384 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
1385
1386 while ((bx < lx) && ((C2 | C3) >= 0))
1387 {
1388
1389 color_t col;
1390 if (TEXTURE_BILINEAR)
1391 {
1392 const float xx = tx;
1393 const float yy = ty;
1394 const int ttx = lfloorf(xx);
1395 const int tty = lfloorf(yy);
1396 const float ax = xx - ttx;
1397 const float ay = yy - tty;
1398 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
1399 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
1400 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
1401 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
1402 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
1403 }
1404 else
1405 {
1406 const int ttx = (TEXTURE_WRAP ? ((int)((tx))) & (texsize_x_mm) : shaderclip((int)(tx), texsize_x_mm));
1407 const int tty = (TEXTURE_WRAP ? ((int)((ty))) & (texsize_y_mm) : shaderclip((int)(ty), texsize_y_mm));
1408 col = tex[ttx + (tty)*texstride];
1409 }
1410
1411 const int r = fP1R + ((C2 * fP21R + C3 * fP31R) / aera);
1412 const int g = fP1G + ((C2 * fP21G + C3 * fP31G) / aera);
1413 const int b = fP1B + ((C2 * fP21B + C3 * fP31B) / aera);
1414 col.mult256(r, g, b);
1415 buf[bx] = col;
1416
1417 C2 += dx2;
1418 C3 += dx3;
1419
1420 tx += dtx;
1421 ty += dty;
1422
1423 bx++;
1424 }
1425
1426 O1 += dy1;
1427 O2 += dy2;
1428 O3 += dy3;
1429 buf += stride;
1430 }
1431 }
1432
1433
1434
1438 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
1439 void shader_Flat_Texture_Zbuffer_Ortho(const int32_t& offset, const int32_t& lx, const int32_t& ly,
1440 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
1441 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
1442 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
1443 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
1444 {
1445 color_t* buf = data.im->data() + offset;
1446 ZBUFFER_t* zbuf = data.zbuf + offset;
1447
1448 const float wa = data.wa;
1449 const float wb = data.wb;
1450 (void)wa; // silence possible unused warnings
1451 (void)wb; //
1452
1453 const int32_t stride = data.im->stride();
1454 const int32_t zstride = data.im->lx();
1455
1456 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
1457 const int32_t pa = O1 + O2 + O3;
1458 const int32_t E = ((pa == 0) ? 1 : 0);
1459 const int32_t aera = pa + E;
1460
1461 const float invaera = fast_inv((float)aera);
1462 const float fP1a = fP1.w * invaera;
1463 const float fP2a = fP2.w * invaera;
1464 const float fP3a = fP3.w * invaera;
1465
1466 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
1467
1468 const RGBf& cf = (RGBf)data.facecolor;
1469 const int fPR = (int)(256 * cf.R);
1470 const int fPG = (int)(256 * cf.G);
1471 const int fPB = (int)(256 * cf.B);
1472
1473 // the texture coord
1474 fVec2 T1 = fP1.T;
1475 fVec2 T2 = fP2.T;
1476 fVec2 T3 = fP3.T;
1477
1478 const color_t* tex = data.tex->data();
1479 const int32_t texsize_x = data.tex->width();
1480 const int32_t texsize_y = data.tex->height();
1481 const int32_t texsize_x_mm = texsize_x - 1;
1482 const int32_t texsize_y_mm = texsize_y - 1;
1483 const int32_t texstride = data.tex->stride();
1484
1485 // divide the texture coord by aera
1486 T1 *= invaera;
1487 T2 *= invaera;
1488 T3 *= invaera;
1489 T1.x *= texsize_x;
1490 T2.x *= texsize_x;
1491 T3.x *= texsize_x;
1492 T1.y *= texsize_y;
1493 T2.y *= texsize_y;
1494 T3.y *= texsize_y;
1495
1496 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
1497 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
1498
1499 while ((uintptr_t)(buf) < end)
1500 { // iterate over scanlines
1501 int32_t bx = 0; // start offset
1502 if (O1 < 0)
1503 {
1504 // we know that dx1 > 0
1505 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
1506 }
1507 if (O2 < 0)
1508 {
1509 if (dx2 <= 0)
1510 {
1511 if (dy2 <= 0) return;
1512 const int32_t by = (-O2 + dy2 - 1u) / dy2;
1513 O1 += (by * dy1);
1514 O2 += (by * dy2);
1515 O3 += (by * dy3);
1516 const int32_t offs = by * stride;
1517 buf += offs;
1518 zbuf += offs;
1519 continue;
1520 }
1521 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
1522 bx = max(bx, bx2);
1523 }
1524 if (O3 < 0)
1525 {
1526 if (dx3 <= 0)
1527 {
1528 if (dy3 <= 0) return;
1529 const int32_t by = (-O3 + dy3 - 1u) / dy3;
1530 O1 += (by * dy1);
1531 O2 += (by * dy2);
1532 O3 += (by * dy3);
1533 const int32_t offs = by * stride;
1534 buf += offs;
1535 zbuf += offs;
1536 continue;
1537 }
1538 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
1539 bx = max(bx, bx3);
1540 }
1541
1542 int32_t C1 = O1 + (dx1 * bx) + E;
1543 int32_t C2 = O2 + (dx2 * bx);
1544 int32_t C3 = O3 + (dx3 * bx);
1545 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
1546
1547 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
1548 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
1549
1550 while ((bx < lx) && ((C2 | C3) >= 0))
1551 {
1552 ZBUFFER_t& W = zbuf[bx];
1553 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(cw * wa + wb)) : ((ZBUFFER_t)cw);
1554 if (W < aa)
1555 {
1556 W = aa;
1557
1558 color_t col;
1559 if (TEXTURE_BILINEAR)
1560 {
1561 const float xx = tx;
1562 const float yy = ty;
1563 const int ttx = lfloorf(xx);
1564 const int tty = lfloorf(yy);
1565 const float ax = xx - ttx;
1566 const float ay = yy - tty;
1567 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
1568 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
1569 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
1570 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
1571 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
1572 }
1573 else
1574 {
1575 const int ttx = (TEXTURE_WRAP ? ((int)((tx))) & (texsize_x_mm) : shaderclip((int)(tx), texsize_x_mm));
1576 const int tty = (TEXTURE_WRAP ? ((int)((ty))) & (texsize_y_mm) : shaderclip((int)(ty), texsize_y_mm));
1577 col = tex[ttx + (tty)*texstride];
1578 }
1579
1580 col.mult256(fPR, fPG, fPB);
1581 buf[bx] = col;
1582 }
1583
1584 C2 += dx2;
1585 C3 += dx3;
1586 cw += dw;
1587
1588 tx += dtx;
1589 ty += dty;
1590
1591 bx++;
1592 }
1593
1594 O1 += dy1;
1595 O2 += dy2;
1596 O3 += dy3;
1597 buf += stride;
1598 zbuf += zstride;
1599 }
1600 }
1601
1602
1603
1607 template<typename color_t, typename ZBUFFER_t, bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
1608 void shader_Gouraud_Texture_Zbuffer_Ortho(const int32_t& offset, const int32_t& lx, const int32_t& ly,
1609 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
1610 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
1611 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
1612 const RasterizerParams<color_t, color_t, ZBUFFER_t>& data)
1613 {
1614 color_t* buf = data.im->data() + offset;
1615 ZBUFFER_t* zbuf = data.zbuf + offset;
1616
1617 const float wa = data.wa;
1618 const float wb = data.wb;
1619 (void)wa; // silence possible unused warnings
1620 (void)wb; //
1621
1622 const int32_t stride = data.im->stride();
1623 const int32_t zstride = data.im->lx();
1624
1625 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
1626 const int32_t pa = O1 + O2 + O3;
1627 const int32_t E = ((pa == 0) ? 1 : 0);
1628 const int32_t aera = pa + E;
1629
1630 const float invaera = fast_inv((float)aera);
1631 const float fP1a = fP1.w * invaera;
1632 const float fP2a = fP2.w * invaera;
1633 const float fP3a = fP3.w * invaera;
1634
1635 const float dw = (dx1 * fP1a) + (dx2 * fP2a) + (dx3 * fP3a);
1636
1637 const RGBf& cf1 = (RGBf)fP1.color;
1638 const RGBf& cf2 = (RGBf)fP2.color;
1639 const RGBf& cf3 = (RGBf)fP3.color;
1640 const int fP1R = (int)(256 * cf1.R);
1641 const int fP1G = (int)(256 * cf1.G);
1642 const int fP1B = (int)(256 * cf1.B);
1643 const int fP21R = (int)(256 * (cf2.R - cf1.R));
1644 const int fP21G = (int)(256 * (cf2.G - cf1.G));
1645 const int fP21B = (int)(256 * (cf2.B - cf1.B));
1646 const int fP31R = (int)(256 * (cf3.R - cf1.R));
1647 const int fP31G = (int)(256 * (cf3.G - cf1.G));
1648 const int fP31B = (int)(256 * (cf3.B - cf1.B));
1649
1650 // the texture coord
1651 fVec2 T1 = fP1.T;
1652 fVec2 T2 = fP2.T;
1653 fVec2 T3 = fP3.T;
1654
1655 const color_t* tex = data.tex->data();
1656 const int32_t texsize_x = data.tex->width();
1657 const int32_t texsize_y = data.tex->height();
1658 const int32_t texsize_x_mm = texsize_x - 1;
1659 const int32_t texsize_y_mm = texsize_y - 1;
1660 const int32_t texstride = data.tex->stride();
1661
1662 // divide the texture coord by aera
1663 T1 *= invaera;
1664 T2 *= invaera;
1665 T3 *= invaera;
1666 T1.x *= texsize_x;
1667 T2.x *= texsize_x;
1668 T3.x *= texsize_x;
1669 T1.y *= texsize_y;
1670 T2.y *= texsize_y;
1671 T3.y *= texsize_y;
1672
1673 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
1674 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
1675
1676 while ((uintptr_t)(buf) < end)
1677 { // iterate over scanlines
1678 int32_t bx = 0; // start offset
1679 if (O1 < 0)
1680 {
1681 // we know that dx1 > 0
1682 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
1683 }
1684 if (O2 < 0)
1685 {
1686 if (dx2 <= 0)
1687 {
1688 if (dy2 <= 0) return;
1689 const int32_t by = (-O2 + dy2 - 1u) / dy2;
1690 O1 += (by * dy1);
1691 O2 += (by * dy2);
1692 O3 += (by * dy3);
1693 const int32_t offs = by * stride;
1694 buf += offs;
1695 zbuf += offs;
1696 continue;
1697 }
1698 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
1699 bx = max(bx, bx2);
1700 }
1701 if (O3 < 0)
1702 {
1703 if (dx3 <= 0)
1704 {
1705 if (dy3 <= 0) return;
1706 const int32_t by = (-O3 + dy3 - 1u) / dy3;
1707 O1 += (by * dy1);
1708 O2 += (by * dy2);
1709 O3 += (by * dy3);
1710 const int32_t offs = by * stride;
1711 buf += offs;
1712 zbuf += offs;
1713 continue;
1714 }
1715 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
1716 bx = max(bx, bx3);
1717 }
1718
1719 int32_t C1 = O1 + (dx1 * bx) + E;
1720 int32_t C2 = O2 + (dx2 * bx);
1721 int32_t C3 = O3 + (dx3 * bx);
1722 float cw = ((C1 * fP1a) + (C2 * fP2a) + (C3 * fP3a));
1723
1724 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3));
1725 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3));
1726
1727 while ((bx < lx) && ((C2 | C3) >= 0))
1728 {
1729 ZBUFFER_t& W = zbuf[bx];
1730 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(cw * wa + wb)) : ((ZBUFFER_t)cw);
1731 if (W < aa)
1732 {
1733 W = aa;
1734
1735 color_t col;
1736 if (TEXTURE_BILINEAR)
1737 {
1738 const float xx = tx;
1739 const float yy = ty;
1740 const int ttx = lfloorf(xx);
1741 const int tty = lfloorf(yy);
1742 const float ax = xx - ttx;
1743 const float ay = yy - tty;
1744 const int minx = (TEXTURE_WRAP ? (ttx & (texsize_x_mm)) : shaderclip(ttx, texsize_x_mm));
1745 const int maxx = (TEXTURE_WRAP ? ((ttx + 1) & (texsize_x_mm)) : shaderclip(ttx + 1, texsize_x_mm));
1746 const int miny = (TEXTURE_WRAP ? ((tty & (texsize_y_mm)) * texstride) : shaderclip(tty, texsize_y_mm) * texstride);
1747 const int maxy = (TEXTURE_WRAP ? (((tty + 1) & (texsize_y_mm)) * texstride) : shaderclip(tty + 1, texsize_y_mm) * texstride);
1748 col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
1749 }
1750 else
1751 {
1752 const int ttx = (TEXTURE_WRAP ? ((int)((tx))) & (texsize_x_mm) : shaderclip((int)(tx), texsize_x_mm));
1753 const int tty = (TEXTURE_WRAP ? ((int)((ty))) & (texsize_y_mm) : shaderclip((int)(ty), texsize_y_mm));
1754 col = tex[ttx + (tty)*texstride];
1755 }
1756
1757 const int r = fP1R + ((C2 * fP21R + C3 * fP31R) / aera);
1758 const int g = fP1G + ((C2 * fP21G + C3 * fP31G) / aera);
1759 const int b = fP1B + ((C2 * fP21B + C3 * fP31B) / aera);
1760
1761 col.mult256(r, g, b);
1762 buf[bx] = col;
1763
1764 }
1765
1766 C2 += dx2;
1767 C3 += dx3;
1768 cw += dw;
1769
1770 tx += dtx;
1771 ty += dty;
1772
1773 bx++;
1774 }
1775
1776 O1 += dy1;
1777 O2 += dy2;
1778 O3 += dy3;
1779 buf += stride;
1780 zbuf += zstride;
1781 }
1782 }
1783
1784
1785
1786
1790 template<int SHADER_FLAGS_ENABLED, typename color_t, typename ZBUFFER_t> void shader_select(const int32_t& offset, const int32_t& lx, const int32_t& ly,
1791 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
1792 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
1793 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
1794 const RasterizerParams<color_t, color_t, ZBUFFER_t> & data)
1795 {
1796 int raster_type = data.shader_type;
1797 if (TGX_SHADER_HAS_ZBUFFER(SHADER_FLAGS_ENABLED) && (TGX_SHADER_HAS_ZBUFFER(raster_type)))
1798 { // USING ZBUFFER
1799 if (TGX_SHADER_HAS_ORTHO(SHADER_FLAGS_ENABLED) && (TGX_SHADER_HAS_ORTHO(raster_type)))
1800 { // USING ORTHOGRAPHIC PROJECTION
1801 if (TGX_SHADER_HAS_TEXTURE(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE(raster_type))
1802 {
1803 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1804 {
1805 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1806 {
1807 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1808 shader_Gouraud_Texture_Zbuffer_Ortho<color_t,ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1809 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1810 shader_Gouraud_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, true, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1811 }
1812 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1813 {
1814 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1815 shader_Gouraud_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1816 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1817 shader_Gouraud_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1818 }
1819 }
1820 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1821 {
1822 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1823 {
1824 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1825 shader_Flat_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1826 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1827 shader_Flat_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, true,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1828 }
1829 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1830 {
1831 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1832 shader_Flat_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1833 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1834 shader_Flat_Texture_Zbuffer_Ortho<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1835 }
1836 }
1837 }
1838 else if (TGX_SHADER_HAS_NOTEXTURE(SHADER_FLAGS_ENABLED))
1839 {
1840 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1841 shader_Gouraud_Zbuffer<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data); // same as perspective projection
1842 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1843 shader_Flat_Zbuffer<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data); // same as perspective projection
1844 }
1845 }
1846 else if (TGX_SHADER_HAS_PERSPECTIVE(SHADER_FLAGS_ENABLED))
1847 { // USING PERSPECTIVE PROJECTION
1848 if (TGX_SHADER_HAS_TEXTURE(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE(raster_type))
1849 {
1850 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1851 {
1852 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1853 {
1854 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1855 shader_Gouraud_Texture_Zbuffer<color_t, ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1856 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1857 shader_Gouraud_Texture_Zbuffer<color_t, ZBUFFER_t, true, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1858 }
1859 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1860 {
1861 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1862 shader_Gouraud_Texture_Zbuffer<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1863 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1864 shader_Gouraud_Texture_Zbuffer<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1865 }
1866 }
1867 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1868 {
1869 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1870 {
1871 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1872 shader_Flat_Texture_Zbuffer<color_t, ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1873 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1874 shader_Flat_Texture_Zbuffer<color_t, ZBUFFER_t, true,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1875 }
1876 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1877 {
1878 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1879 shader_Flat_Texture_Zbuffer<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1880 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1881 shader_Flat_Texture_Zbuffer<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1882 }
1883 }
1884 }
1885 else if (TGX_SHADER_HAS_NOTEXTURE(SHADER_FLAGS_ENABLED))
1886 {
1887 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1888 shader_Gouraud_Zbuffer<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1889 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1890 shader_Flat_Zbuffer<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1891 }
1892 }
1893 }
1894 else if (TGX_SHADER_HAS_NOZBUFFER(SHADER_FLAGS_ENABLED))
1895 { // NOT USING Z-BUFFER
1896 if (TGX_SHADER_HAS_ORTHO(SHADER_FLAGS_ENABLED) && (TGX_SHADER_HAS_ORTHO(raster_type)))
1897 { // USING ORTHOGRAPHIC PROJECTION
1898 if (TGX_SHADER_HAS_TEXTURE(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE(raster_type))
1899 {
1900 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1901 {
1902 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1903 {
1904 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1905 shader_Gouraud_Texture_Ortho<color_t, ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1906 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1907 shader_Gouraud_Texture_Ortho<color_t, ZBUFFER_t, true,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1908 }
1909 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1910 {
1911 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1912 shader_Gouraud_Texture_Ortho<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1913 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1914 shader_Gouraud_Texture_Ortho<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1915 }
1916 }
1917 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1918 {
1919 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1920 {
1921 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1922 shader_Flat_Texture_Ortho<color_t, ZBUFFER_t, true,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1923 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1924 shader_Flat_Texture_Ortho<color_t, ZBUFFER_t, true,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1925 }
1926 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1927 {
1928 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1929 shader_Flat_Texture_Ortho<color_t, ZBUFFER_t, false,false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1930 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1931 shader_Flat_Texture_Ortho<color_t, ZBUFFER_t, false,true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1932 }
1933 }
1934 }
1935 else if (TGX_SHADER_HAS_NOTEXTURE(SHADER_FLAGS_ENABLED))
1936 {
1937 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1938 shader_Gouraud<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data); // same as perspective projection
1939 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1940 shader_Flat<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data); // same as perspective projection
1941 }
1942 }
1943 else if (TGX_SHADER_HAS_PERSPECTIVE(SHADER_FLAGS_ENABLED))
1944 { // USING PERSPECTIVE PROJECTION
1945 if (TGX_SHADER_HAS_TEXTURE(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE(raster_type))
1946 {
1947 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1948 {
1949 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1950 {
1951 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1952 shader_Gouraud_Texture<color_t, ZBUFFER_t, true, false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1953 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1954 shader_Gouraud_Texture<color_t, ZBUFFER_t, true, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1955 }
1956 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1957 {
1958 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1959 shader_Gouraud_Texture<color_t, ZBUFFER_t, false, false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1960 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1961 shader_Gouraud_Texture<color_t, ZBUFFER_t, false, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1962 }
1963 }
1964 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1965 {
1966 if (TGX_SHADER_HAS_TEXTURE_BILINEAR(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_BILINEAR(raster_type))
1967 {
1968 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1969 shader_Flat_Texture<color_t, ZBUFFER_t, true, false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1970 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1971 shader_Flat_Texture<color_t, ZBUFFER_t, true, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1972 }
1973 else if (TGX_SHADER_HAS_TEXTURE_NEAREST(SHADER_FLAGS_ENABLED))
1974 {
1975 if (TGX_SHADER_HAS_TEXTURE_CLAMP(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_TEXTURE_CLAMP(raster_type))
1976 shader_Flat_Texture<color_t, ZBUFFER_t, false, false>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1977 else if (TGX_SHADER_HAS_TEXTURE_WRAP_POW2(SHADER_FLAGS_ENABLED))
1978 shader_Flat_Texture<color_t, ZBUFFER_t, false, true>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1979 }
1980 }
1981 }
1982 else if (TGX_SHADER_HAS_NOTEXTURE(SHADER_FLAGS_ENABLED))
1983 {
1984 if (TGX_SHADER_HAS_GOURAUD(SHADER_FLAGS_ENABLED) && TGX_SHADER_HAS_GOURAUD(raster_type))
1985 shader_Gouraud<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1986 else if (TGX_SHADER_HAS_FLAT(SHADER_FLAGS_ENABLED))
1987 shader_Flat<color_t, ZBUFFER_t>(offset, lx, ly, dx1, dy1, O1, fP1, dx2, dy2, O2, fP2, dx3, dy3, O3, fP3, data);
1988 }
1989 }
1990 }
1991 }
1992
1993
1994
1995
1996
2000 template<bool USE_BLENDING, typename color_t_im>
2001 void shader_2D_gradient(const int32_t& offset, const int32_t& lx, const int32_t& ly,
2002 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
2003 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
2004 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
2005 const RasterizerParams<color_t_im, color_t_im, float> & data)
2006 {
2007 color_t_im * buf = data.im->data() + offset;
2008 const int32_t stride = data.im->stride();
2009
2010 // use RGB32 (could use RGB64 be it would be slower).
2011 const RGB32 col1 = RGB64(fP1.color.R, fP1.color.G, fP1.color.B, fP1.A);
2012 const RGB32 col2 = RGB64(fP2.color.R, fP2.color.G, fP2.color.B, fP2.A);
2013 const RGB32 col3 = RGB64(fP3.color.R, fP3.color.G, fP3.color.B, fP3.A);
2014
2015 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
2016 const int32_t pa = O1 + O2 + O3;
2017 const int32_t E = ((pa == 0) ? 1 : 0);
2018 const int32_t aera = pa + E;
2019 const int shiftC = (aera > (1 << 22)) ? 10 : 0; // prevent overflow during color interpolation
2020
2021 while ((uintptr_t)(buf) < end)
2022 { // iterate over scanlines
2023 int32_t bx = 0; // start offset
2024 if (O1 < 0)
2025 {
2026 // we know that dx1 > 0
2027 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
2028 }
2029 if (O2 < 0)
2030 {
2031 if (dx2 <= 0)
2032 {
2033 if (dy2 <= 0) return;
2034 const int32_t by = (-O2 + dy2 - 1u) / dy2;
2035 O1 += (by * dy1);
2036 O2 += (by * dy2);
2037 O3 += (by * dy3);
2038 const int32_t offs = by * stride;
2039 buf += offs;
2040 continue;
2041 }
2042 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
2043 bx = max(bx, bx2);
2044 }
2045 if (O3 < 0)
2046 {
2047 if (dx3 <= 0)
2048 {
2049 if (dy3 <= 0) return;
2050 const int32_t by = (-O3 + dy3 - 1u) / dy3;
2051 O1 += (by * dy1);
2052 O2 += (by * dy2);
2053 O3 += (by * dy3);
2054 const int32_t offs = by * stride;
2055 buf += offs;
2056 continue;
2057 }
2058 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
2059 bx = max(bx, bx3);
2060 }
2061
2062 int32_t C2 = O2 + (dx2 * bx);
2063 int32_t C3 = O3 + (dx3 * bx);
2064 while ((bx < lx) && ((C2 | C3) >= 0))
2065 {
2066 if (USE_BLENDING)
2067 {
2068 RGB32 c(buf[bx]); // could use RGB64 instead but would be slower
2069 c.blend(interpolateColorsTriangle(col2, C2 >> shiftC, col3, C3 >> shiftC, col1, aera >> shiftC), data.opacity);
2070 buf[bx] = color_t_im(c);
2071 }
2072 else
2073 {
2074 buf[bx] = color_t_im(interpolateColorsTriangle(col2, C2 >> shiftC, col3, C3 >> shiftC, col1, aera >> shiftC));
2075 }
2076 C2 += dx2;
2077 C3 += dx3;
2078 bx++;
2079 }
2080
2081 O1 += dy1;
2082 O2 += dy2;
2083 O3 += dy3;
2084 buf += stride;
2085 }
2086 }
2087
2088
2089
2093 template<bool USE_BLENDING, bool USE_MASKING, bool USE_GRADIENT, typename color_t_im, typename color_t_tex>
2094 void shader_2D_texture(const int32_t& offset, const int32_t& lx, const int32_t& ly,
2095 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
2096 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
2097 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
2098 const RasterizerParams<color_t_im, color_t_tex, float> & data)
2099 {
2100
2101 color_t_im * buf = data.im->data() + offset;
2102 const int32_t stride = data.im->stride();
2103
2104 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
2105 const int32_t pa = O1 + O2 + O3;
2106 const int32_t E = ((pa == 0) ? 1 : 0);
2107 const int32_t aera = pa + E;
2108
2109 const float invaera = fast_inv((float)aera);
2110
2111 const color_t_tex mask_color = data.mask_color;
2112
2113 const RGBf& cf1 = (RGBf)fP1.color;
2114 const RGBf& cf2 = (RGBf)fP2.color;
2115 const RGBf& cf3 = (RGBf)fP3.color;
2116
2117 // the texture coord
2118 fVec2 T1 = fP1.T;
2119 fVec2 T2 = fP2.T;
2120 fVec2 T3 = fP3.T;
2121
2122 const color_t_tex * tex = data.tex->data();
2123 const int32_t texsize_x = data.tex->width();
2124 const int32_t texsize_y = data.tex->height();
2125 const int32_t texsize_x_mm = data.tex->width() - 1;
2126 const int32_t texsize_y_mm = data.tex->height() - 1;
2127 const int32_t texstride = data.tex->stride();
2128
2129 // divide the texture coord by aera
2130 T1 *= invaera;
2131 T2 *= invaera;
2132 T3 *= invaera;
2133 T1.x *= texsize_x;
2134 T2.x *= texsize_x;
2135 T3.x *= texsize_x;
2136 T1.y *= texsize_y;
2137 T2.y *= texsize_y;
2138 T3.y *= texsize_y;
2139
2140 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
2141 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
2142
2143 while ((uintptr_t)(buf) < end)
2144 { // iterate over scanlines
2145 int32_t bx = 0; // start offset
2146 if (O1 < 0)
2147 {
2148 // we know that dx1 > 0
2149 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
2150 }
2151 if (O2 < 0)
2152 {
2153 if (dx2 <= 0)
2154 {
2155 if (dy2 <= 0) return;
2156 const int32_t by = (-O2 + dy2 - 1u) / dy2;
2157 O1 += (by * dy1);
2158 O2 += (by * dy2);
2159 O3 += (by * dy3);
2160 const int32_t offs = by * stride;
2161 buf += offs;
2162 continue;
2163 }
2164 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
2165 bx = max(bx, bx2);
2166 }
2167 if (O3 < 0)
2168 {
2169 if (dx3 <= 0)
2170 {
2171 if (dy3 <= 0) return;
2172 const int32_t by = (-O3 + dy3 - 1u) / dy3;
2173 O1 += (by * dy1);
2174 O2 += (by * dy2);
2175 O3 += (by * dy3);
2176 const int32_t offs = by * stride;
2177 buf += offs;
2178 continue;
2179 }
2180 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
2181 bx = max(bx, bx3);
2182 }
2183
2184 int32_t C1 = O1 + (dx1 * bx) + E;
2185 int32_t C2 = O2 + (dx2 * bx);
2186 int32_t C3 = O3 + (dx3 * bx);
2187
2188 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3)) - 0.5f;
2189 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3)) - 0.5f;
2190
2191 while ((bx < lx) && ((C2 | C3) >= 0))
2192 {
2193 const float xx = tx;
2194 const float yy = ty;
2195 const int ttx = lfloorf(xx);
2196 const int tty = lfloorf(yy);
2197 const float ax = xx - ttx;
2198 const float ay = yy - tty;
2199
2200 const int minx = shaderclip(ttx, texsize_x_mm);
2201 const int maxx = shaderclip(ttx + 1, texsize_x_mm);
2202 const int miny = shaderclip(tty, texsize_y_mm) * texstride;
2203 const int maxy = shaderclip(tty + 1, texsize_y_mm) * texstride;
2204
2205 if (USE_MASKING)
2206 { //
2207 auto col00 = tex[minx + miny];
2208 tgx::RGB32 acol00 = (col00 == mask_color) ? tgx::RGB32((uint32_t)0) : tgx::RGB32(col00);
2209
2210 auto col10 = tex[maxx + miny];
2211 tgx::RGB32 acol10 = (col10 == mask_color) ? tgx::RGB32((uint32_t)0) : tgx::RGB32(col10);
2212
2213 auto col01 = tex[minx + maxy];
2214 tgx::RGB32 acol01 = (col01 == mask_color) ? tgx::RGB32((uint32_t)0) : tgx::RGB32(col01);
2215
2216 auto col11 = tex[maxx + maxy];
2217 tgx::RGB32 acol11 = (col11 == mask_color) ? tgx::RGB32((uint32_t)0) : tgx::RGB32(col11);
2218
2219 tgx::RGB32 col = interpolateColorsBilinear(acol00, acol10, acol01, acol11, ax, ay);
2220
2221 if (USE_GRADIENT)
2222 {
2223 const int sC2 = C2;
2224 const int sC3 = C3;
2225 const int sC1 = aera - C3 - C2;
2226 const float m = 256.0f / aera;
2227 const int r = (int)((sC1 * cf1.R + sC2 * cf2.R + sC3 * cf3.R) * m);
2228 const int g = (int)((sC1 * cf1.G + sC2 * cf2.G + sC3 * cf3.G) * m);
2229 const int b = (int)((sC1 * cf1.B + sC2 * cf2.B + sC3 * cf3.B) * m);
2230 const int a = (int)((sC1 * fP1.A + sC2 * fP2.A + sC3 * fP3.A) * m);
2231 col.mult256(r, g, b, a);
2232 }
2233 if (USE_BLENDING)
2234 {
2235 tgx::RGB32 c = tgx::RGB32(buf[bx]);
2236 c.blend(col, data.opacity);
2237 buf[bx] = color_t_im(c);
2238 }
2239 else
2240 {
2241 buf[bx] = color_t_im(col);
2242 }
2243 }
2244 else
2245 {
2246 color_t_tex col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
2247 if (USE_GRADIENT)
2248 {
2249 const int sC2 = C2;
2250 const int sC3 = C3;
2251 const int sC1 = aera - C3 - C2;
2252 const float m = 256.0f / aera;
2253 const int r = (int)((sC1 * cf1.R + sC2 * cf2.R + sC3 * cf3.R) * m);
2254 const int g = (int)((sC1 * cf1.G + sC2 * cf2.G + sC3 * cf3.G) * m);
2255 const int b = (int)((sC1 * cf1.B + sC2 * cf2.B + sC3 * cf3.B) * m);
2256 const int a = (int)((sC1 * fP1.A + sC2 * fP2.A + sC3 * fP3.A) * m);
2257 col.mult256(r, g, b, a);
2258 }
2259 if (USE_BLENDING)
2260 {
2261 color_t_tex c = color_t_tex(buf[bx]);
2262 c.blend(col, data.opacity);
2263 buf[bx] = color_t_im(c);
2264 }
2265 else
2266 {
2267 buf[bx] = color_t_im(col);
2268 }
2269 }
2270
2271 C2 += dx2;
2272 C3 += dx3;
2273
2274 tx += dtx;
2275 ty += dty;
2276
2277 bx++;
2278 }
2279
2280 O1 += dy1;
2281 O2 += dy2;
2282 O3 += dy3;
2283 buf += stride;
2284 }
2285 }
2286
2287
2288
2289
2293 template<typename BLEND_OP, typename color_t_im, typename color_t_tex>
2294 void shader_2D_texture_blend_op(const int32_t& offset, const int32_t& lx, const int32_t& ly,
2295 const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4& fP1,
2296 const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4& fP2,
2297 const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4& fP3,
2298 const RasterizerParams<color_t_im, color_t_tex, float, BLEND_OP> & data)
2299 {
2300
2301 color_t_im * buf = data.im->data() + offset;
2302 const int32_t stride = data.im->stride();
2303
2304 const uintptr_t end = (uintptr_t)(buf + (ly * stride));
2305 const int32_t pa = O1 + O2 + O3;
2306 const int32_t E = ((pa == 0) ? 1 : 0);
2307 const int32_t aera = pa + E;
2308
2309 const float invaera = fast_inv((float)aera);
2310
2311 // the texture coord
2312 fVec2 T1 = fP1.T;
2313 fVec2 T2 = fP2.T;
2314 fVec2 T3 = fP3.T;
2315
2316
2317 const color_t_tex * tex = data.tex->data();
2318 const int32_t texsize_x = data.tex->width();
2319 const int32_t texsize_y = data.tex->height();
2320 const int32_t texsize_x_mm = data.tex->width() - 1;
2321 const int32_t texsize_y_mm = data.tex->height() - 1;
2322 const int32_t texstride = data.tex->stride();
2323
2324 // divide the texture coord by aera
2325 T1 *= invaera;
2326 T2 *= invaera;
2327 T3 *= invaera;
2328 T1.x *= texsize_x;
2329 T2.x *= texsize_x;
2330 T3.x *= texsize_x;
2331 T1.y *= texsize_y;
2332 T2.y *= texsize_y;
2333 T3.y *= texsize_y;
2334
2335 const float dtx = ((T1.x * dx1) + (T2.x * dx2) + (T3.x * dx3));
2336 const float dty = ((T1.y * dx1) + (T2.y * dx2) + (T3.y * dx3));
2337
2338 while ((uintptr_t)(buf) < end)
2339 { // iterate over scanlines
2340 int32_t bx = 0; // start offset
2341 if (O1 < 0)
2342 {
2343 // we know that dx1 > 0
2344 bx = (-O1 + dx1 - 1u) / dx1; // first index where it becomes positive
2345 }
2346 if (O2 < 0)
2347 {
2348 if (dx2 <= 0)
2349 {
2350 if (dy2 <= 0) return;
2351 const int32_t by = (-O2 + dy2 - 1u) / dy2;
2352 O1 += (by * dy1);
2353 O2 += (by * dy2);
2354 O3 += (by * dy3);
2355 const int32_t offs = by * stride;
2356 buf += offs;
2357 continue;
2358 }
2359 const int32_t bx2 = (-O2 + dx2 - 1u) / dx2;
2360 bx = max(bx, bx2);
2361 }
2362 if (O3 < 0)
2363 {
2364 if (dx3 <= 0)
2365 {
2366 if (dy3 <= 0) return;
2367 const int32_t by = (-O3 + dy3 - 1u) / dy3;
2368 O1 += (by * dy1);
2369 O2 += (by * dy2);
2370 O3 += (by * dy3);
2371 const int32_t offs = by * stride;
2372 buf += offs;
2373 continue;
2374 }
2375 const int32_t bx3 = (-O3 + dx3 - 1u) / dx3;
2376 bx = max(bx, bx3);
2377 }
2378
2379 int32_t C1 = O1 + (dx1 * bx) + E;
2380 int32_t C2 = O2 + (dx2 * bx);
2381 int32_t C3 = O3 + (dx3 * bx);
2382
2383 float tx = ((T1.x * C1) + (T2.x * C2) + (T3.x * C3)) - 0.5f;
2384 float ty = ((T1.y * C1) + (T2.y * C2) + (T3.y * C3)) - 0.5f;
2385
2386 while ((bx < lx) && ((C2 | C3) >= 0))
2387 {
2388 const float xx = tx;
2389 const float yy = ty;
2390 const int ttx = lfloorf(xx);
2391 const int tty = lfloorf(yy);
2392 const float ax = xx - ttx;
2393 const float ay = yy - tty;
2394
2395 const int minx = shaderclip(ttx, texsize_x_mm);
2396 const int maxx = shaderclip(ttx + 1, texsize_x_mm);
2397 const int miny = shaderclip(tty, texsize_y_mm) * texstride;
2398 const int maxy = shaderclip(tty + 1, texsize_y_mm) * texstride;
2399
2400 color_t_tex col = interpolateColorsBilinear(tex[minx + miny], tex[maxx + miny], tex[minx + maxy], tex[maxx + maxy], ax, ay);
2401
2402 buf[bx] = (color_t_im)((*data.p_blend_op)(col, buf[bx]));
2403
2404 C2 += dx2;
2405 C3 += dx3;
2406
2407 tx += dtx;
2408 ty += dty;
2409
2410 bx++;
2411 }
2412
2413 O1 += dy1;
2414 O2 += dy2;
2415 O3 += dy3;
2416 buf += stride;
2417 }
2418 }
2419
2420
2421}
2422
2423#endif
2424
2425#endif
2426
tgx::RGB32_Red
const RGB32 RGB32_Red
Color red in RGB32 format.
tgx::interpolateColorsBilinear
RGB565 interpolateColorsBilinear(const RGB565 &C00, const RGB565 &C10, const RGB565 &C01, const RGB565 &C11, const float ax, const float ay)
Bilinear interpolation between 4 colors.
Definition: Color.h:621
tgx::interpolateColorsTriangle
RGB565 interpolateColorsTriangle(const RGB565 &col1, int32_t C1, const RGB565 &col2, int32_t C2, const RGB565 &col3, const int32_t totC)
Interpolate between 3 colors.
Definition: Color.h:591
tgx::lfloorf
TGX_INLINE int32_t lfloorf(float x)
Compute (int32_t)floorf(x).
Definition: Misc.h:374
tgx::max
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:136
tgx::fast_inv
TGX_INLINE float fast_inv(float x)
Fast (approximate) computation of 1/x.
Definition: Misc.h:180
ShaderParams.h
Triangle shader parameters.
tgx::shader_test
void shader_test(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t &dx1, const int32_t &dy1, int32_t O1, const tgx::RasterizerVec4 &fP1, const int32_t &dx2, const int32_t &dy2, int32_t O2, const tgx::RasterizerVec4 &fP2, const int32_t &dx3, const int32_t &dy3, int32_t O3, const tgx::RasterizerVec4 &fP3, const tgx::RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
For test purposes...
Definition: Shaders.h:45
tgx::shader_select
void shader_select(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
META-Shader THAT DISPATCH TO THE CORRECT Shader ABOVE (IF ENABLED).
Definition: Shaders.h:1790
tgx::shader_Gouraud_Texture
void shader_Gouraud_Texture(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
TEXTURE + GOURAUD SHADING (NO ZBUFFER)
Definition: Shaders.h:388
tgx::shader_2D_texture
void shader_2D_texture(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t_im, color_t_tex, float > &data)
2D shader (texture)
Definition: Shaders.h:2094
tgx::shader_Flat
void shader_Flat(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t &dx1, const int32_t &dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t &dx2, const int32_t &dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t &dx3, const int32_t &dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
FLAT SHADING (NO ZBUFFER)
Definition: Shaders.h:74
tgx::shader_Flat_Texture
void shader_Flat_Texture(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
TEXTURE + FLAT SHADING (NO ZBUFFER)
Definition: Shaders.h:234
tgx::shader_Gouraud
void shader_Gouraud(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t &dx1, const int32_t &dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t &dx2, const int32_t &dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t &dx3, const int32_t &dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
GOURAUD SHADING (NO Z BUFFER)
Definition: Shaders.h:151
tgx::shader_Flat_Texture_Zbuffer_Ortho
void shader_Flat_Texture_Zbuffer_Ortho(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + TEXTURE + FLAT SHADING + ORTHOGRAPHIC.
Definition: Shaders.h:1439
tgx::shader_Gouraud_Texture_Ortho
void shader_Gouraud_Texture_Ortho(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
TEXTURE + GOURAUD SHADING (NO ZBUFFER) + ORTHOGRAPHIC.
Definition: Shaders.h:1283
tgx::shader_Flat_Texture_Zbuffer
void shader_Flat_Texture_Zbuffer(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + TEXTURE + FLAT SHADING.
Definition: Shaders.h:789
tgx::shader_Flat_Texture_Ortho
void shader_Flat_Texture_Ortho(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
TEXTURE + FLAT SHADING (NO ZBUFFER) + ORTHOGRAPHIC.
Definition: Shaders.h:1139
tgx::shader_Gouraud_Texture_Zbuffer_Ortho
void shader_Gouraud_Texture_Zbuffer_Ortho(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + TEXTURE + GOURAUD SHADING + ORTHOGRAPHIC.
Definition: Shaders.h:1608
tgx::shader_Gouraud_Zbuffer
void shader_Gouraud_Zbuffer(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + GOURAUD SHADING.
Definition: Shaders.h:766
tgx::shader_2D_gradient
void shader_2D_gradient(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t_im, color_t_im, float > &data)
2D shader (gradient)
Definition: Shaders.h:2001
tgx::shaderclip
TGX_INLINE int shaderclip(int v, int maxv)
for texture clamping
Definition: Shaders.h:34
tgx::shader_Flat_Zbuffer
void shader_Flat_Zbuffer(const int32_t offset, const int32_t &lx, const int32_t &ly, const int32_t &dx1, const int32_t &dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t &dx2, const int32_t &dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t &dx3, const int32_t &dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + FLAT SHADING.
Definition: Shaders.h:555
tgx::shader_Gouraud_Zbuffer_sub
void shader_Gouraud_Zbuffer_sub(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + GOURAUD SHADING (sub-procedure, templated on shiftC)
Definition: Shaders.h:659
tgx::shader_Gouraud_Texture_Zbuffer
void shader_Gouraud_Texture_Zbuffer(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t, color_t, ZBUFFER_t > &data)
ZBUFFER + TEXTURE + GOURAUD SHADING.
Definition: Shaders.h:959
tgx::shader_2D_texture_blend_op
void shader_2D_texture_blend_op(const int32_t &offset, const int32_t &lx, const int32_t &ly, const int32_t dx1, const int32_t dy1, int32_t O1, const RasterizerVec4 &fP1, const int32_t dx2, const int32_t dy2, int32_t O2, const RasterizerVec4 &fP2, const int32_t dx3, const int32_t dy3, int32_t O3, const RasterizerVec4 &fP3, const RasterizerParams< color_t_im, color_t_tex, float, BLEND_OP > &data)
2D shader (texture with custom blending operator)
Definition: Shaders.h:2294
tgx::RGB32
Color in R8/G8/B8/A8 format.
Definition: Color.h:1176
tgx::RGB32::mult256
void mult256(int mr, int mg, int mb)
Multiply each color component by a given factor m/256 with m in [0,256] except the A component.
Definition: Color.h:1590
tgx::RGB32::blend256
void blend256(const RGB32 &fg_col, uint32_t alpha)
alpha-blend fg_col over this one with a given opacity in the range 0.0f (fully transparent) to 1....
Definition: Color.h:1561
tgx::RGB32::blend
void blend(const RGB32 &fg_col, float alpha)
alpha-blend fg_col over this one with a given opacity in the range 0.0f (fully transparent) to 1....
Definition: Color.h:1546
tgx::RGB32::opacity
float opacity() const
Return the opacity (alpha channel value) of this color in the range [0,1] (0=fully transparent,...
Definition: Color.h:1629
tgx::RGB565::opacity
float opacity() const
Dummy function for compatibility with color types having an alpha channel.
Definition: Color.h:565
tgx::RGB64
Color in R16/G16/B16/A16 format.
Definition: Color.h:1791
tgx::RGBf
Color in R,G,B float format.
Definition: Color.h:2407
tgx::RGBf::R
float R
Red channel.
Definition: Color.h:2420
tgx::RGBf::B
float B
Blue channel.
Definition: Color.h:2422
tgx::RGBf::G
float G
Green channel.
Definition: Color.h:2421
tgx::Vec2< float >
tgx::Vec2::x
T x
'x' coordinate (first dimension)
Definition: Vec2.h:72
tgx::Vec2::y
T y
'y' coordinate (second dimension)
Definition: Vec2.h:73