1 static uint32_t SCANEDGE(struct pvertex *v0, struct pvertex *v1, struct pvertex *edge)
4 int32_t x, dx, dy, slope;
6 int r, g, b, dr, dg, db;
7 int32_t rslope, gslope, bslope;
13 int32_t u, v, du, dv, uslope, vslope;
16 int32_t z, dz, zslope;
18 int32_t start_idx, end_idx;
21 struct pvertex *tmp = v0;
29 slope = (dx << 8) / dy;
31 r = (v0->r << COLOR_SHIFT);
32 g = (v0->g << COLOR_SHIFT);
33 b = (v0->b << COLOR_SHIFT);
34 dr = (v1->r << COLOR_SHIFT) - r;
35 dg = (v1->g << COLOR_SHIFT) - g;
36 db = (v1->b << COLOR_SHIFT) - b;
37 rslope = (dr << 8) / dy;
38 gslope = (dg << 8) / dy;
39 bslope = (db << 8) / dy;
41 a = (v0->a << COLOR_SHIFT);
42 da = (v1->a << COLOR_SHIFT) - a;
43 aslope = (da << 8) / dy;
44 #endif /* BLEND_ALPHA */
51 uslope = (du << 8) / dy;
52 vslope = (dv << 8) / dy;
57 zslope = (dz << 8) / dy;
60 start_idx = v0->y >> 8;
63 for(i=start_idx; i<end_idx; i++) {
68 /* we'll store the color in the edge tables with COLOR_SHIFT extra bits of precision */
92 return (uint32_t)start_idx | ((uint32_t)(end_idx - 1) << 16);
95 void POLYFILL(struct pvertex *pv, int nverts)
98 int topidx = 0, botidx = 0, sltop = pfill_fb.height, slbot = 0;
100 /* the following variables are used for interpolating horizontally accros scanlines */
101 #if defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF)
106 int32_t r, g, b, dr, dg, db, rslope, gslope, bslope;
108 int32_t a, da, aslope;
112 int32_t u, v, du, dv, uslope, vslope;
115 int32_t z, dz, zslope;
118 #if !defined(GOURAUD) && !defined(TEXMAP)
119 /* flat version, just pack the color now */
120 color = G3D_PACK_RGB(pv[0].r, pv[0].g, pv[0].b);
123 for(i=1; i<nverts; i++) {
124 if(pv[i].y < pv[topidx].y) topidx = i;
125 if(pv[i].y > pv[botidx].y) botidx = i;
129 for(i=0; i<nverts; i++) {
130 int next = NEXTIDX(i);
131 winding += ((pv[next].x - pv[i].x) >> 4) * ((pv[next].y + pv[i].y) >> 4);
134 for(i=0; i<nverts; i++) {
135 int next = NEXTIDX(i);
136 int32_t y0 = pv[i].y;
137 int32_t y1 = pv[next].y;
139 if((y0 >> 8) == (y1 >> 8)) {
143 if(pv[i].x < pv[next].x) {
151 left[idx].x = pv[i0].x;
152 right[idx].x = pv[i1].x;
154 left[idx].r = pv[i0].r << COLOR_SHIFT;
155 left[idx].g = pv[i0].g << COLOR_SHIFT;
156 left[idx].b = pv[i0].b << COLOR_SHIFT;
157 right[idx].r = pv[i1].r << COLOR_SHIFT;
158 right[idx].g = pv[i1].g << COLOR_SHIFT;
159 right[idx].b = pv[i1].b << COLOR_SHIFT;
161 left[idx].a = pv[i0].a << COLOR_SHIFT;
162 right[idx].a = pv[i1].a << COLOR_SHIFT;
163 #endif /* BLEND_ALPHA */
166 left[idx].u = pv[i0].u;
167 left[idx].v = pv[i0].v;
168 right[idx].u = pv[i1].u;
169 right[idx].v = pv[i1].v;
172 left[idx].z = pv[i0].z;
173 right[idx].z = pv[i1].z;
176 if(idx > slbot) slbot = idx;
177 if(idx < sltop) sltop = idx;
180 struct pvertex *edge;
185 edge = y0 > y1 ? left : right;
187 /* counter-clockwise */
188 edge = y0 > y1 ? right : left;
190 res = SCANEDGE(pv + i, pv + next, edge);
191 tmp = (res >> 16) & 0xffff;
192 if(tmp > slbot) slbot = tmp;
193 if((tmp = res & 0xffff) < sltop) {
199 /* calculate the slopes of all attributes across the largest span out
200 * of the three: middle, top, or bottom.
203 #if defined(GOURAUD) || defined(TEXMAP)
204 mid = (sltop + slbot) >> 1;
208 dx = right[mid].x - left[mid].x;
209 if((tmp = right[sltop].x - left[sltop].x) > dx) {
213 if((tmp = right[slbot].x - left[slbot].x) > dx) {
217 if(!dx) dx = 256; /* avoid division by zero */
221 dr = right[mid].r - left[mid].r;
222 dg = right[mid].g - left[mid].g;
223 db = right[mid].b - left[mid].b;
224 rslope = (dr << 8) / dx;
225 gslope = (dg << 8) / dx;
226 bslope = (db << 8) / dx;
228 da = right[mid].a - left[mid].a;
229 aslope = (da << 8) / dx;
230 #endif /* BLEND_ALPHA */
233 du = right[mid].u - left[mid].u;
234 dv = right[mid].v - left[mid].v;
235 uslope = (du << 8) / dx;
236 vslope = (dv << 8) / dx;
239 dz = right[mid].z - left[mid].z;
240 zslope = (dz << 8) / dx;
242 #endif /* !defined(HIGH_QUALITY) */
244 /* for each scanline ... */
245 for(i=sltop; i<=slbot; i++) {
254 pixptr = pfill_fb.pixels + i * pfill_fb.width + (x >> 8);
262 #endif /* BLEND_ALPHA */
270 zptr = pfill_zbuf + i * pfill_fb.width + (x >> 8);
274 #if defined(HIGH_QUALITY) && (defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF))
275 if(!(dx = right[i].x - left[i].x)) dx = 256;
279 dr = right[i].r - left[i].r;
280 dg = right[i].g - left[i].g;
281 db = right[i].b - left[i].b;
282 rslope = (dr << 8) / dx;
283 gslope = (dg << 8) / dx;
284 bslope = (db << 8) / dx;
286 da = right[i].a - left[i].a;
287 aslope = (da << 8) / dx;
288 #endif /* BLEND_ALPHA */
291 du = right[i].u - left[i].u;
292 dv = right[i].v - left[i].v;
293 uslope = (du << 8) / dx;
294 vslope = (dv << 8) / dx;
297 dz = right[i].z - left[i].z;
298 zslope = (dz << 8) / dx;
300 #endif /* HIGH_QUALITY */
303 /* go across the scanline interpolating if necessary */
304 while(x <= right[i].x) {
305 /*if(x == (180 << 8) && i == 174) {
308 #if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD)
311 #if defined(BLEND_ALPHA) || defined(BLEND_ADD)
315 int alpha, inv_alpha;
346 /* we upped the color precision to while interpolating the
347 * edges, now drop the extra bits before packing
349 cr = r < 0 ? 0 : (r >> COLOR_SHIFT);
350 cg = g < 0 ? 0 : (g >> COLOR_SHIFT);
351 cb = b < 0 ? 0 : (b >> COLOR_SHIFT);
358 if(cr > 255) cr = 255;
359 if(cg > 255) cg = 255;
360 if(cb > 255) cb = 255;
361 #endif /* BLEND_ALPHA */
365 int tx = (u >> (16 - pfill_tex.xshift)) & pfill_tex.xmask;
366 int ty = (v >> (16 - pfill_tex.yshift)) & pfill_tex.ymask;
367 g3d_pixel texel = pfill_tex.pixels[(ty << pfill_tex.xshift) + tx];
369 /* This is not correct, should be /255, but it's much faster
370 * to shift by 8 (/256), and won't make a huge difference
372 cr = (cr * G3D_UNPACK_R(texel)) >> 8;
373 cg = (cg * G3D_UNPACK_G(texel)) >> 8;
374 cb = (cb * G3D_UNPACK_B(texel)) >> 8;
376 cr = G3D_UNPACK_R(texel);
377 cg = G3D_UNPACK_G(texel);
378 cb = G3D_UNPACK_B(texel);
385 #if defined(BLEND_ALPHA) || defined(BLEND_ADD)
386 #if !defined(GOURAUD) && !defined(TEXMAP)
387 /* flat version: cr,cg,cb are uninitialized so far */
396 alpha = a >> COLOR_SHIFT;
400 inv_alpha = 255 - alpha;
401 cr = (cr * alpha + G3D_UNPACK_R(fbcol) * inv_alpha) >> 8;
402 cg = (cg * alpha + G3D_UNPACK_G(fbcol) * inv_alpha) >> 8;
403 cb = (cb * alpha + G3D_UNPACK_B(fbcol) * inv_alpha) >> 8;
404 #else /* !BLEND_ALPHA (so BLEND_ADD) */
405 cr += G3D_UNPACK_R(fbcol);
406 cg += G3D_UNPACK_R(fbcol);
407 cb += G3D_UNPACK_R(fbcol);
409 if(cr > 255) cr = 255;
410 if(cg > 255) cg = 255;
411 if(cb > 255) cb = 255;
412 #endif /* BLEND(ALPHA|ADD) */
414 #if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD)
415 color = G3D_PACK_RGB(cr, cg, cb);
418 #ifdef DEBUG_OVERDRAW
419 *pixptr++ += DEBUG_OVERDRAW;