X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2F3dgfx%2Fpolytmpl.h;fp=src%2F3dgfx%2Fpolytmpl.h;h=2072e2b5f19e01b4279084b83f2278e847f3f7b5;hp=0000000000000000000000000000000000000000;hb=57bd2dc519c47f434e3e5acf998fb9c72448cbce;hpb=d956a9d9273eebfacfda58cb3bafff017269d5dc diff --git a/src/3dgfx/polytmpl.h b/src/3dgfx/polytmpl.h new file mode 100644 index 0000000..2072e2b --- /dev/null +++ b/src/3dgfx/polytmpl.h @@ -0,0 +1,363 @@ +static uint32_t SCANEDGE(struct pvertex *v0, struct pvertex *v1, struct pvertex *edge) +{ + int i; + int32_t x, dx, dy, slope; +#ifdef GOURAUD + int r, g, b, dr, dg, db; + int32_t rslope, gslope, bslope; +#ifdef BLEND_ALPHA + int32_t a, da, aslope; +#endif +#endif /* GOURAUD */ +#ifdef TEXMAP + int32_t u, v, du, dv, uslope, vslope; +#endif + int32_t start_idx, end_idx; + + if(v0->y > v1->y) { + struct pvertex *tmp = v0; + v0 = v1; + v1 = tmp; + } + + x = v0->x; + dy = v1->y - v0->y; + dx = v1->x - v0->x; + slope = (dx << 8) / dy; +#ifdef GOURAUD + r = (v0->r << COLOR_SHIFT); + g = (v0->g << COLOR_SHIFT); + b = (v0->b << COLOR_SHIFT); + dr = (v1->r << COLOR_SHIFT) - r; + dg = (v1->g << COLOR_SHIFT) - g; + db = (v1->b << COLOR_SHIFT) - b; + rslope = (dr << 8) / dy; + gslope = (dg << 8) / dy; + bslope = (db << 8) / dy; +#ifdef BLEND_ALPHA + a = (v0->a << COLOR_SHIFT); + da = (v1->a << COLOR_SHIFT) - a; + aslope = (da << 8) / dy; +#endif /* BLEND_ALPHA */ +#endif /* GOURAUD */ +#ifdef TEXMAP + u = v0->u; + v = v0->v; + du = v1->u - v0->u; + dv = v1->v - v0->v; + uslope = (du << 8) / dy; + vslope = (dv << 8) / dy; +#endif + + start_idx = v0->y >> 8; + end_idx = v1->y >> 8; + + for(i=start_idx; i pv[botidx].y) botidx = i; + } + + winding = 0; + for(i=0; i> 4) * ((pv[next].y + pv[i].y) >> 4); + } + + for(i=0; i> 8) == (y1 >> 8)) { + /*if(y0 > y1) {*/ + int i0, i1; + int idx = y0 >> 8; + if(pv[i].x < pv[next].x) { + i0 = i; + i1 = next; + } else { + i0 = next; + i1 = i; + } + CHECKEDGE(idx); + left[idx].x = pv[i0].x; + right[idx].x = pv[i1].x; +#ifdef GOURAUD + left[idx].r = pv[i0].r << COLOR_SHIFT; + left[idx].g = pv[i0].g << COLOR_SHIFT; + left[idx].b = pv[i0].b << COLOR_SHIFT; + right[idx].r = pv[i1].r << COLOR_SHIFT; + right[idx].g = pv[i1].g << COLOR_SHIFT; + right[idx].b = pv[i1].b << COLOR_SHIFT; +#ifdef BLEND_ALPHA + left[idx].a = pv[i0].a << COLOR_SHIFT; + right[idx].a = pv[i1].a << COLOR_SHIFT; +#endif /* BLEND_ALPHA */ +#endif +#ifdef TEXMAP + left[idx].u = pv[i0].u; + left[idx].v = pv[i0].v; + right[idx].u = pv[i1].u; + right[idx].v = pv[i1].v; +#endif + CHECKEDGE(idx); + if(idx > slbot) slbot = idx; + if(idx < sltop) sltop = idx; + /*}*/ + } else { + struct pvertex *edge; + uint32_t res, tmp; + + if(winding < 0) { + /* clockwise */ + edge = y0 > y1 ? left : right; + } else { + /* counter-clockwise */ + edge = y0 > y1 ? right : left; + } + res = SCANEDGE(pv + i, pv + next, edge); + tmp = (res >> 16) & 0xffff; + if(tmp > slbot) slbot = tmp; + if((tmp = res & 0xffff) < sltop) { + sltop = tmp; + } + } + } + + /* calculate the slopes of all attributes across the largest span out + * of the three: middle, top, or bottom. + */ +#ifndef HIGH_QUALITY +#if defined(GOURAUD) || defined(TEXMAP) + mid = (sltop + slbot) >> 1; + CHECKEDGE(sltop); + CHECKEDGE(slbot); + CHECKEDGE(mid); + dx = right[mid].x - left[mid].x; + if((tmp = right[sltop].x - left[sltop].x) > dx) { + dx = tmp; + mid = sltop; + } + if((tmp = right[slbot].x - left[slbot].x) > dx) { + dx = tmp; + mid = slbot; + } + if(!dx) dx = 256; /* avoid division by zero */ +#endif + CHECKEDGE(idx); +#ifdef GOURAUD + dr = right[mid].r - left[mid].r; + dg = right[mid].g - left[mid].g; + db = right[mid].b - left[mid].b; + rslope = (dr << 8) / dx; + gslope = (dg << 8) / dx; + bslope = (db << 8) / dx; +#ifdef BLEND_ALPHA + da = right[mid].a - left[mid].a; + aslope = (da << 8) / dx; +#endif /* BLEND_ALPHA */ +#endif +#ifdef TEXMAP + du = right[mid].u - left[mid].u; + dv = right[mid].v - left[mid].v; + uslope = (du << 8) / dx; + vslope = (dv << 8) / dx; +#endif +#endif /* !defined(HIGH_QUALITY) */ + + /* for each scanline ... */ + for(i=sltop; i<=slbot; i++) { + g3d_pixel *pixptr; + int32_t x; + + CHECKEDGE(i); + x = left[i].x; + pixptr = pfill_fb.pixels + i * pfill_fb.width + (x >> 8); + +#ifdef GOURAUD + r = left[i].r; + g = left[i].g; + b = left[i].b; +#ifdef BLEND_ALPHA + a = left[i].a; +#endif /* BLEND_ALPHA */ +#endif +#ifdef TEXMAP + u = left[i].u; + v = left[i].v; +#endif + CHECKEDGE(i); + +#if defined(HIGH_QUALITY) && (defined(GOURAUD) || defined(TEXMAP)) + if(!(dx = right[i].x - left[i].x)) dx = 256; + + CHECKEDGE(i); +#ifdef GOURAUD + dr = right[i].r - left[i].r; + dg = right[i].g - left[i].g; + db = right[i].b - left[i].b; + rslope = (dr << 8) / dx; + gslope = (dg << 8) / dx; + bslope = (db << 8) / dx; +#ifdef BLEND_ALPHA + da = right[i].a - left[i].a; + aslope = (da << 8) / dx; +#endif /* BLEND_ALPHA */ +#endif /* GOURAUD */ +#ifdef TEXMAP + du = right[i].u - left[i].u; + dv = right[i].v - left[i].v; + uslope = (du << 8) / dx; + vslope = (dv << 8) / dx; +#endif +#endif /* HIGH_QUALITY */ + CHECKEDGE(i); + + /* go across the scanline interpolating if necessary */ + while(x <= right[i].x) { +#if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD) + int cr, cg, cb; +#endif +#if defined(BLEND_ALPHA) || defined(BLEND_ADD) + g3d_pixel fbcol; +#endif +#ifdef BLEND_ALPHA + int alpha, inv_alpha; +#endif +#ifdef GOURAUD + /* we upped the color precision to while interpolating the + * edges, now drop the extra bits before packing + */ + cr = r < 0 ? 0 : (r >> COLOR_SHIFT); + cg = g < 0 ? 0 : (g >> COLOR_SHIFT); + cb = b < 0 ? 0 : (b >> COLOR_SHIFT); + r += rslope; + g += gslope; + b += bslope; +#ifdef BLEND_ALPHA + a += aslope; +#else + if(cr > 255) cr = 255; + if(cg > 255) cg = 255; + if(cb > 255) cb = 255; +#endif /* BLEND_ALPHA */ +#endif /* GOURAUD */ +#ifdef TEXMAP + { + int tx = (u >> (16 - pfill_tex.xshift)) & pfill_tex.xmask; + int ty = (v >> (16 - pfill_tex.yshift)) & pfill_tex.ymask; + g3d_pixel texel = pfill_tex.pixels[(ty << pfill_tex.xshift) + tx]; +#ifdef GOURAUD + /* This is not correct, should be /255, but it's much faster + * to shift by 8 (/256), and won't make a huge difference + */ + cr = (cr * G3D_UNPACK_R(texel)) >> 8; + cg = (cg * G3D_UNPACK_G(texel)) >> 8; + cb = (cb * G3D_UNPACK_B(texel)) >> 8; +#else + cr = G3D_UNPACK_R(texel); + cg = G3D_UNPACK_G(texel); + cb = G3D_UNPACK_B(texel); +#endif + } + u += uslope; + v += vslope; +#endif + +#if defined(BLEND_ALPHA) || defined(BLEND_ADD) +#if !defined(GOURAUD) && !defined(TEXMAP) + /* flat version: cr,cg,cb are uninitialized so far */ + cr = pv[0].r; + cg = pv[0].g; + cb = pv[0].b; +#endif + fbcol = *pixptr; + +#ifdef BLEND_ALPHA +#ifdef GOURAUD + alpha = a >> COLOR_SHIFT; +#else + alpha = pv[0].a; +#endif + inv_alpha = 255 - alpha; + cr = (cr * alpha + G3D_UNPACK_R(fbcol) * inv_alpha) >> 8; + cg = (cg * alpha + G3D_UNPACK_G(fbcol) * inv_alpha) >> 8; + cb = (cb * alpha + G3D_UNPACK_B(fbcol) * inv_alpha) >> 8; +#else /* !BLEND_ALPHA (so BLEND_ADD) */ + cr += G3D_UNPACK_R(fbcol); + cg += G3D_UNPACK_R(fbcol); + cb += G3D_UNPACK_R(fbcol); +#endif + if(cr > 255) cr = 255; + if(cg > 255) cg = 255; + if(cb > 255) cb = 255; +#endif /* BLEND(ALPHA|ADD) */ + +#if defined(GOURAUD) || defined(TEXMAP) || defined(BLEND_ALPHA) || defined(BLEND_ADD) + color = G3D_PACK_RGB(cr, cg, cb); +#endif + +#ifdef DEBUG_OVERDRAW + *pixptr++ += DEBUG_OVERDRAW; +#else + *pixptr++ = color; +#endif + x += 256; + } + } +} +