2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
24 /*#define DEBUG_OVERDRAW PACK_RGB(10, 10, 10)*/
26 #define FILL_POLY_BITS 0x03
29 /* mode bits: 00-wire 01-flat 10-gouraud 11-reserved
31 * bit 3-4: blend mode: 00-none 01-alpha 10-additive 11-reserved
34 void (*fillfunc[])(struct pvertex*, int) = {
45 polyfill_alpha_gouraud,
47 polyfill_alpha_tex_wire,
48 polyfill_alpha_tex_flat,
49 polyfill_alpha_tex_gouraud,
55 polyfill_add_tex_wire,
56 polyfill_add_tex_flat,
57 polyfill_add_tex_gouraud,
58 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 polyfill_gouraud_zbuf,
64 polyfill_tex_flat_zbuf,
65 polyfill_tex_gouraud_zbuf,
68 polyfill_alpha_flat_zbuf,
69 polyfill_alpha_gouraud_zbuf,
71 polyfill_alpha_tex_wire,
72 polyfill_alpha_tex_flat_zbuf,
73 polyfill_alpha_tex_gouraud_zbuf,
76 polyfill_add_flat_zbuf,
77 polyfill_add_gouraud_zbuf,
79 polyfill_add_tex_wire,
80 polyfill_add_tex_flat_zbuf,
81 polyfill_add_tex_gouraud_zbuf,
82 0, 0, 0, 0, 0, 0, 0, 0, 0
85 struct pimage pfill_fb, pfill_tex;
89 static struct pvertex *edgebuf, *left, *right;
90 static int edgebuf_size;
94 #define CHECKEDGE(x) \
97 assert(x < fbheight); \
103 void polyfill_fbheight(int height)
105 int newsz = (height * 2 + EDGEPAD * 3) * sizeof *edgebuf;
107 if(newsz > edgebuf_size) {
109 if(!(edgebuf = malloc(newsz))) {
110 fprintf(stderr, "failed to allocate edge table buffer (%d bytes)\n", newsz);
113 edgebuf_size = newsz;
115 left = edgebuf + EDGEPAD;
116 right = edgebuf + height + EDGEPAD * 2;
119 memset(edgebuf, 0xaa, EDGEPAD * sizeof *edgebuf);
120 memset(edgebuf + height + EDGEPAD, 0xaa, EDGEPAD * sizeof *edgebuf);
121 memset(edgebuf + height * 2 + EDGEPAD * 2, 0xaa, EDGEPAD * sizeof *edgebuf);
128 void polyfill(int mode, struct pvertex *verts, int nverts)
131 if(!fillfunc[mode]) {
132 fprintf(stderr, "polyfill mode %d not implemented\n", mode);
137 fillfunc[mode](verts, nverts);
140 void polyfill_wire(struct pvertex *verts, int nverts)
143 int i, x0, y0, x1, y1;
144 struct pvertex *v = verts;
145 uint32_t color = PACK_RGB(v->r, v->g, v->b);
147 for(i=0; i<nverts - 1; i++) {
153 if(clip_line(&x0, &y0, &x1, &y1, 0, 0, pfill_fb.width, pfill_fb.height)) {
154 draw_line(x0, y0, x1, y1, color);
157 x0 = verts[0].x >> 8;
158 y0 = verts[0].y >> 8;
159 if(clip_line(&x1, &y1, &x0, &y0, 0, 0, pfill_fb.width, pfill_fb.height)) {
160 draw_line(x1, y1, x0, y0, color);
165 void polyfill_tex_wire(struct pvertex *verts, int nverts)
167 polyfill_wire(verts, nverts); /* TODO */
170 void polyfill_alpha_wire(struct pvertex *verts, int nverts)
172 polyfill_wire(verts, nverts); /* TODO */
175 void polyfill_alpha_tex_wire(struct pvertex *verts, int nverts)
177 polyfill_wire(verts, nverts); /* TODO */
180 void polyfill_add_wire(struct pvertex *verts, int nverts)
182 polyfill_wire(verts, nverts); /* TODO */
185 void polyfill_add_tex_wire(struct pvertex *verts, int nverts)
187 polyfill_wire(verts, nverts); /* TODO */
190 #define VNEXT(p) (((p) == vlast) ? varr : (p) + 1)
191 #define VPREV(p) ((p) == varr ? vlast : (p) - 1)
192 #define VSUCC(p, side) ((side) == 0 ? VNEXT(p) : VPREV(p))
194 /* extra bits of precision to use when interpolating colors.
195 * try tweaking this if you notice strange quantization artifacts.
197 #define COLOR_SHIFT 12
200 #define POLYFILL polyfill_flat
206 #include "polytmpl.h"
209 #define POLYFILL polyfill_gouraud
215 #include "polytmpl.h"
218 #define POLYFILL polyfill_tex_flat
224 #include "polytmpl.h"
227 #define POLYFILL polyfill_tex_gouraud
233 #include "polytmpl.h"
236 #define POLYFILL polyfill_alpha_flat
242 #include "polytmpl.h"
245 #define POLYFILL polyfill_alpha_gouraud
251 #include "polytmpl.h"
254 #define POLYFILL polyfill_alpha_tex_flat
260 #include "polytmpl.h"
263 #define POLYFILL polyfill_alpha_tex_gouraud
269 #include "polytmpl.h"
272 #define POLYFILL polyfill_add_flat
278 #include "polytmpl.h"
281 #define POLYFILL polyfill_add_gouraud
287 #include "polytmpl.h"
290 #define POLYFILL polyfill_add_tex_flat
296 #include "polytmpl.h"
299 #define POLYFILL polyfill_add_tex_gouraud
305 #include "polytmpl.h"
308 /* ---- zbuffer variants ----- */
310 #define POLYFILL polyfill_flat_zbuf
316 #include "polytmpl.h"
319 #define POLYFILL polyfill_gouraud_zbuf
325 #include "polytmpl.h"
328 #define POLYFILL polyfill_tex_flat_zbuf
334 #include "polytmpl.h"
337 #define POLYFILL polyfill_tex_gouraud_zbuf
343 #include "polytmpl.h"
346 #define POLYFILL polyfill_alpha_flat_zbuf
352 #include "polytmpl.h"
355 #define POLYFILL polyfill_alpha_gouraud_zbuf
361 #include "polytmpl.h"
364 #define POLYFILL polyfill_alpha_tex_flat_zbuf
370 #include "polytmpl.h"
373 #define POLYFILL polyfill_alpha_tex_gouraud_zbuf
379 #include "polytmpl.h"
382 #define POLYFILL polyfill_add_flat_zbuf
388 #include "polytmpl.h"
391 #define POLYFILL polyfill_add_gouraud_zbuf
397 #include "polytmpl.h"
400 #define POLYFILL polyfill_add_tex_flat_zbuf
406 #include "polytmpl.h"
409 #define POLYFILL polyfill_add_tex_gouraud_zbuf
415 #include "polytmpl.h"