|
|
1.1 root 1: // d_polyset.c: routines for drawing sets of polygons sharing the same
2: // texture (used for Alias models)
3:
4: #include "quakedef.h"
5: #include "r_local.h"
6: #include "d_local.h"
7:
8: // TODO: put in span spilling to shrink list size
9: // !!! if this is changed, it must be changed in d_polysa.s too !!!
10: #define DPS_MAXSPANS MAXHEIGHT+1
11: // 1 extra for spanpackage that marks end
12:
13: // !!! if this is changed, it must be changed in asm_draw.h too !!!
14: typedef struct {
15: void *pdest;
16: short *pz;
17: int count;
18: byte *ptex;
19: int sfrac, tfrac, light, zi;
20: } spanpackage_t;
21:
22: typedef struct {
23: int isflattop;
24: int numleftedges;
25: int *pleftedgevert0;
26: int *pleftedgevert1;
27: int *pleftedgevert2;
28: int numrightedges;
29: int *prightedgevert0;
30: int *prightedgevert1;
31: int *prightedgevert2;
32: } edgetable;
33:
34: int r_p0[6], r_p1[6], r_p2[6];
35:
36: byte *d_pcolormap;
37:
38: int d_aflatcolor;
39: int d_xdenom;
40:
41: edgetable *pedgetable;
42:
43: edgetable edgetables[12] = {
44: {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
45: {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},
46: {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
47: {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
48: {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},
49: {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
50: {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
51: {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},
52: {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
53: {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
54: {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
55: {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
56: };
57:
58: // FIXME: some of these can become statics
59: int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
60: int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
61: int r_zistepx, r_zistepy;
62: int d_aspancount, d_countextrastep;
63:
64: spanpackage_t *a_spans;
65: spanpackage_t *d_pedgespanpackage;
66: static int ystart;
67: byte *d_pdest, *d_ptex;
68: short *d_pz;
69: int d_sfrac, d_tfrac, d_light, d_zi;
70: int d_ptexextrastep, d_sfracextrastep;
71: int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
72: int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
73: int d_sfracbasestep, d_tfracbasestep;
74: int d_ziextrastep, d_zibasestep;
75: int d_pzextrastep, d_pzbasestep;
76:
77: typedef struct {
78: int quotient;
79: int remainder;
80: } adivtab_t;
81:
82: static adivtab_t adivtab[32*32] = {
83: #include "adivtab.h"
84: };
85:
86: byte *skintable[MAX_LBM_HEIGHT];
87: int skinwidth;
88: byte *skinstart;
89:
90: void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
91: void D_PolysetCalcGradients (int skinwidth);
92: void D_DrawSubdiv (void);
93: void D_DrawNonSubdiv (void);
94: void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
95: void D_PolysetSetEdgeTable (void);
96: void D_RasterizeAliasPolySmooth (void);
97: void D_PolysetScanLeftEdge (int height);
98:
99: #if !id386
100:
101: /*
102: ================
103: D_PolysetDraw
104: ================
105: */
106: void D_PolysetDraw (void)
107: {
108: spanpackage_t spans[DPS_MAXSPANS + 1 +
109: ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];
110: // one extra because of cache line pretouching
111:
112: a_spans = (spanpackage_t *)
113: (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
114:
115: if (r_affinetridesc.drawtype)
116: {
117: D_DrawSubdiv ();
118: }
119: else
120: {
121: D_DrawNonSubdiv ();
122: }
123: }
124:
125:
126: /*
127: ================
128: D_PolysetDrawFinalVerts
129: ================
130: */
131: void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
132: {
133: int i, z;
134: short *zbuf;
135:
136: for (i=0 ; i<numverts ; i++, fv++)
137: {
138: // valid triangle coordinates for filling can include the bottom and
139: // right clip edges, due to the fill rule; these shouldn't be drawn
140: if ((fv->v[0] < r_refdef.vrectright) &&
141: (fv->v[1] < r_refdef.vrectbottom))
142: {
143: z = fv->v[5]>>16;
144: zbuf = zspantable[fv->v[1]] + fv->v[0];
145: if (z >= *zbuf)
146: {
147: int pix;
148:
149: *zbuf = z;
150: pix = skintable[fv->v[3]>>16][fv->v[2]>>16];
151: pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ];
152: d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix;
153: }
154: }
155: }
156: }
157:
158:
159: /*
160: ================
161: D_DrawSubdiv
162: ================
163: */
164: void D_DrawSubdiv (void)
165: {
166: mtriangle_t *ptri;
167: finalvert_t *pfv, *index0, *index1, *index2;
168: int i;
169: int lnumtriangles;
170:
171: pfv = r_affinetridesc.pfinalverts;
172: ptri = r_affinetridesc.ptriangles;
173: lnumtriangles = r_affinetridesc.numtriangles;
174:
175: for (i=0 ; i<lnumtriangles ; i++)
176: {
177: index0 = pfv + ptri[i].vertindex[0];
178: index1 = pfv + ptri[i].vertindex[1];
179: index2 = pfv + ptri[i].vertindex[2];
180:
181: if (((index0->v[1]-index1->v[1]) *
182: (index0->v[0]-index2->v[0]) -
183: (index0->v[0]-index1->v[0]) *
184: (index0->v[1]-index2->v[1])) >= 0)
185: {
186: continue;
187: }
188:
189: d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
190:
191: if (ptri[i].facesfront)
192: {
193: D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
194: }
195: else
196: {
197: int s0, s1, s2;
198:
199: s0 = index0->v[2];
200: s1 = index1->v[2];
201: s2 = index2->v[2];
202:
203: if (index0->flags & ALIAS_ONSEAM)
204: index0->v[2] += r_affinetridesc.seamfixupX16;
205: if (index1->flags & ALIAS_ONSEAM)
206: index1->v[2] += r_affinetridesc.seamfixupX16;
207: if (index2->flags & ALIAS_ONSEAM)
208: index2->v[2] += r_affinetridesc.seamfixupX16;
209:
210: D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
211:
212: index0->v[2] = s0;
213: index1->v[2] = s1;
214: index2->v[2] = s2;
215: }
216: }
217: }
218:
219:
220: /*
221: ================
222: D_DrawNonSubdiv
223: ================
224: */
225: void D_DrawNonSubdiv (void)
226: {
227: mtriangle_t *ptri;
228: finalvert_t *pfv, *index0, *index1, *index2;
229: int i;
230: int lnumtriangles;
231:
232: pfv = r_affinetridesc.pfinalverts;
233: ptri = r_affinetridesc.ptriangles;
234: lnumtriangles = r_affinetridesc.numtriangles;
235:
236: for (i=0 ; i<lnumtriangles ; i++, ptri++)
237: {
238: index0 = pfv + ptri->vertindex[0];
239: index1 = pfv + ptri->vertindex[1];
240: index2 = pfv + ptri->vertindex[2];
241:
242: d_xdenom = (index0->v[1]-index1->v[1]) *
243: (index0->v[0]-index2->v[0]) -
244: (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]);
245:
246: if (d_xdenom >= 0)
247: {
248: continue;
249: }
250:
251: r_p0[0] = index0->v[0]; // u
252: r_p0[1] = index0->v[1]; // v
253: r_p0[2] = index0->v[2]; // s
254: r_p0[3] = index0->v[3]; // t
255: r_p0[4] = index0->v[4]; // light
256: r_p0[5] = index0->v[5]; // iz
257:
258: r_p1[0] = index1->v[0];
259: r_p1[1] = index1->v[1];
260: r_p1[2] = index1->v[2];
261: r_p1[3] = index1->v[3];
262: r_p1[4] = index1->v[4];
263: r_p1[5] = index1->v[5];
264:
265: r_p2[0] = index2->v[0];
266: r_p2[1] = index2->v[1];
267: r_p2[2] = index2->v[2];
268: r_p2[3] = index2->v[3];
269: r_p2[4] = index2->v[4];
270: r_p2[5] = index2->v[5];
271:
272: if (!ptri->facesfront)
273: {
274: if (index0->flags & ALIAS_ONSEAM)
275: r_p0[2] += r_affinetridesc.seamfixupX16;
276: if (index1->flags & ALIAS_ONSEAM)
277: r_p1[2] += r_affinetridesc.seamfixupX16;
278: if (index2->flags & ALIAS_ONSEAM)
279: r_p2[2] += r_affinetridesc.seamfixupX16;
280: }
281:
282: D_PolysetSetEdgeTable ();
283: D_RasterizeAliasPolySmooth ();
284: }
285: }
286:
287:
288: /*
289: ================
290: D_PolysetRecursiveTriangle
291: ================
292: */
293: void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
294: {
295: int *temp;
296: int d;
297: int new[6];
298: int z;
299: short *zbuf;
300:
301: d = lp2[0] - lp1[0];
302: if (d < -1 || d > 1)
303: goto split;
304: d = lp2[1] - lp1[1];
305: if (d < -1 || d > 1)
306: goto split;
307:
308: d = lp3[0] - lp2[0];
309: if (d < -1 || d > 1)
310: goto split2;
311: d = lp3[1] - lp2[1];
312: if (d < -1 || d > 1)
313: goto split2;
314:
315: d = lp1[0] - lp3[0];
316: if (d < -1 || d > 1)
317: goto split3;
318: d = lp1[1] - lp3[1];
319: if (d < -1 || d > 1)
320: {
321: split3:
322: temp = lp1;
323: lp1 = lp3;
324: lp3 = lp2;
325: lp2 = temp;
326:
327: goto split;
328: }
329:
330: return; // entire tri is filled
331:
332: split2:
333: temp = lp1;
334: lp1 = lp2;
335: lp2 = lp3;
336: lp3 = temp;
337:
338: split:
339: // split this edge
340: new[0] = (lp1[0] + lp2[0]) >> 1;
341: new[1] = (lp1[1] + lp2[1]) >> 1;
342: new[2] = (lp1[2] + lp2[2]) >> 1;
343: new[3] = (lp1[3] + lp2[3]) >> 1;
344: new[5] = (lp1[5] + lp2[5]) >> 1;
345:
346: // draw the point if splitting a leading edge
347: if (lp2[1] > lp1[1])
348: goto nodraw;
349: if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
350: goto nodraw;
351:
352:
353: z = new[5]>>16;
354: zbuf = zspantable[new[1]] + new[0];
355: if (z >= *zbuf)
356: {
357: int pix;
358:
359: *zbuf = z;
360: pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]];
361: d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;
362: }
363:
364: nodraw:
365: // recursively continue
366: D_PolysetRecursiveTriangle (lp3, lp1, new);
367: D_PolysetRecursiveTriangle (lp3, new, lp2);
368: }
369:
370: #endif // !id386
371:
372:
373: /*
374: ================
375: D_PolysetUpdateTables
376: ================
377: */
378: void D_PolysetUpdateTables (void)
379: {
380: int i;
381: byte *s;
382:
383: if (r_affinetridesc.skinwidth != skinwidth ||
384: r_affinetridesc.pskin != skinstart)
385: {
386: skinwidth = r_affinetridesc.skinwidth;
387: skinstart = r_affinetridesc.pskin;
388: s = skinstart;
389: for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
390: skintable[i] = s;
391: }
392: }
393:
394:
395: #if !id386
396:
397: /*
398: ===================
399: D_PolysetScanLeftEdge
400: ====================
401: */
402: void D_PolysetScanLeftEdge (int height)
403: {
404:
405: do
406: {
407: d_pedgespanpackage->pdest = d_pdest;
408: d_pedgespanpackage->pz = d_pz;
409: d_pedgespanpackage->count = d_aspancount;
410: d_pedgespanpackage->ptex = d_ptex;
411:
412: d_pedgespanpackage->sfrac = d_sfrac;
413: d_pedgespanpackage->tfrac = d_tfrac;
414:
415: // FIXME: need to clamp l, s, t, at both ends?
416: d_pedgespanpackage->light = d_light;
417: d_pedgespanpackage->zi = d_zi;
418:
419: d_pedgespanpackage++;
420:
421: errorterm += erroradjustup;
422: if (errorterm >= 0)
423: {
424: d_pdest += d_pdestextrastep;
425: d_pz += d_pzextrastep;
426: d_aspancount += d_countextrastep;
427: d_ptex += d_ptexextrastep;
428: d_sfrac += d_sfracextrastep;
429: d_ptex += d_sfrac >> 16;
430:
431: d_sfrac &= 0xFFFF;
432: d_tfrac += d_tfracextrastep;
433: if (d_tfrac & 0x10000)
434: {
435: d_ptex += r_affinetridesc.skinwidth;
436: d_tfrac &= 0xFFFF;
437: }
438: d_light += d_lightextrastep;
439: d_zi += d_ziextrastep;
440: errorterm -= erroradjustdown;
441: }
442: else
443: {
444: d_pdest += d_pdestbasestep;
445: d_pz += d_pzbasestep;
446: d_aspancount += ubasestep;
447: d_ptex += d_ptexbasestep;
448: d_sfrac += d_sfracbasestep;
449: d_ptex += d_sfrac >> 16;
450: d_sfrac &= 0xFFFF;
451: d_tfrac += d_tfracbasestep;
452: if (d_tfrac & 0x10000)
453: {
454: d_ptex += r_affinetridesc.skinwidth;
455: d_tfrac &= 0xFFFF;
456: }
457: d_light += d_lightbasestep;
458: d_zi += d_zibasestep;
459: }
460: } while (--height);
461: }
462:
463: #endif // !id386
464:
465:
466: /*
467: ===================
468: D_PolysetSetUpForLineScan
469: ====================
470: */
471: void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
472: fixed8_t endvertu, fixed8_t endvertv)
473: {
474: double dm, dn;
475: int tm, tn;
476: adivtab_t *ptemp;
477:
478: // TODO: implement x86 version
479:
480: errorterm = -1;
481:
482: tm = endvertu - startvertu;
483: tn = endvertv - startvertv;
484:
485: if (((tm <= 16) && (tm >= -15)) &&
486: ((tn <= 16) && (tn >= -15)))
487: {
488: ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
489: ubasestep = ptemp->quotient;
490: erroradjustup = ptemp->remainder;
491: erroradjustdown = tn;
492: }
493: else
494: {
495: dm = (double)tm;
496: dn = (double)tn;
497:
498: FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
499:
500: erroradjustdown = dn;
501: }
502: }
503:
504:
505: #if !id386
506:
507: /*
508: ================
509: D_PolysetCalcGradients
510: ================
511: */
512: void D_PolysetCalcGradients (int skinwidth)
513: {
514: float xstepdenominv, ystepdenominv, t0, t1;
515: float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
516:
517: p00_minus_p20 = r_p0[0] - r_p2[0];
518: p01_minus_p21 = r_p0[1] - r_p2[1];
519: p10_minus_p20 = r_p1[0] - r_p2[0];
520: p11_minus_p21 = r_p1[1] - r_p2[1];
521:
522: xstepdenominv = 1.0 / (float)d_xdenom;
523:
524: ystepdenominv = -xstepdenominv;
525:
526: // ceil () for light so positive steps are exaggerated, negative steps
527: // diminished, pushing us away from underflow toward overflow. Underflow is
528: // very visible, overflow is very unlikely, because of ambient lighting
529: t0 = r_p0[4] - r_p2[4];
530: t1 = r_p1[4] - r_p2[4];
531: r_lstepx = (int)
532: ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
533: r_lstepy = (int)
534: ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
535:
536: t0 = r_p0[2] - r_p2[2];
537: t1 = r_p1[2] - r_p2[2];
538: r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
539: xstepdenominv);
540: r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
541: ystepdenominv);
542:
543: t0 = r_p0[3] - r_p2[3];
544: t1 = r_p1[3] - r_p2[3];
545: r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
546: xstepdenominv);
547: r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
548: ystepdenominv);
549:
550: t0 = r_p0[5] - r_p2[5];
551: t1 = r_p1[5] - r_p2[5];
552: r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
553: xstepdenominv);
554: r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
555: ystepdenominv);
556:
557: #if id386
558: a_sstepxfrac = r_sstepx << 16;
559: a_tstepxfrac = r_tstepx << 16;
560: #else
561: a_sstepxfrac = r_sstepx & 0xFFFF;
562: a_tstepxfrac = r_tstepx & 0xFFFF;
563: #endif
564:
565: a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
566: }
567:
568: #endif // !id386
569:
570:
571: byte gelmap[256];
572: void InitGel (byte *palette)
573: {
574: int i;
575: int r;
576:
577: for (i=0 ; i<256 ; i++)
578: {
579: // r = (palette[i*3]>>4);
580: r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
581: gelmap[i] = /* 64 */ 0 + r;
582: }
583: }
584:
585:
586: #if !id386
587:
588: /*
589: ================
590: D_PolysetDrawSpans8
591: ================
592: */
593: void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
594: {
595: int lcount;
596: byte *lpdest;
597: byte *lptex;
598: int lsfrac, ltfrac;
599: int llight;
600: int lzi;
601: short *lpz;
602:
603: do
604: {
605: lcount = d_aspancount - pspanpackage->count;
606:
607: errorterm += erroradjustup;
608: if (errorterm >= 0)
609: {
610: d_aspancount += d_countextrastep;
611: errorterm -= erroradjustdown;
612: }
613: else
614: {
615: d_aspancount += ubasestep;
616: }
617:
618: if (lcount)
619: {
620: lpdest = pspanpackage->pdest;
621: lptex = pspanpackage->ptex;
622: lpz = pspanpackage->pz;
623: lsfrac = pspanpackage->sfrac;
624: ltfrac = pspanpackage->tfrac;
625: llight = pspanpackage->light;
626: lzi = pspanpackage->zi;
627:
628: do
629: {
630: if ((lzi >> 16) >= *lpz)
631: {
632: *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
633: // gel mapping *lpdest = gelmap[*lpdest];
634: *lpz = lzi >> 16;
635: }
636: lpdest++;
637: lzi += r_zistepx;
638: lpz++;
639: llight += r_lstepx;
640: lptex += a_ststepxwhole;
641: lsfrac += a_sstepxfrac;
642: lptex += lsfrac >> 16;
643: lsfrac &= 0xFFFF;
644: ltfrac += a_tstepxfrac;
645: if (ltfrac & 0x10000)
646: {
647: lptex += r_affinetridesc.skinwidth;
648: ltfrac &= 0xFFFF;
649: }
650: } while (--lcount);
651: }
652:
653: pspanpackage++;
654: } while (pspanpackage->count != -999999);
655: }
656: #endif // !id386
657:
658:
659: /*
660: ================
661: D_PolysetFillSpans8
662: ================
663: */
664: void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
665: {
666: int color;
667:
668: // FIXME: do z buffering
669:
670: color = d_aflatcolor++;
671:
672: while (1)
673: {
674: int lcount;
675: byte *lpdest;
676:
677: lcount = pspanpackage->count;
678:
679: if (lcount == -1)
680: return;
681:
682: if (lcount)
683: {
684: lpdest = pspanpackage->pdest;
685:
686: do
687: {
688: *lpdest++ = color;
689: } while (--lcount);
690: }
691:
692: pspanpackage++;
693: }
694: }
695:
696: /*
697: ================
698: D_RasterizeAliasPolySmooth
699: ================
700: */
701: void D_RasterizeAliasPolySmooth (void)
702: {
703: int initialleftheight, initialrightheight;
704: int *plefttop, *prighttop, *pleftbottom, *prightbottom;
705: int working_lstepx, originalcount;
706:
707: plefttop = pedgetable->pleftedgevert0;
708: prighttop = pedgetable->prightedgevert0;
709:
710: pleftbottom = pedgetable->pleftedgevert1;
711: prightbottom = pedgetable->prightedgevert1;
712:
713: initialleftheight = pleftbottom[1] - plefttop[1];
714: initialrightheight = prightbottom[1] - prighttop[1];
715:
716: //
717: // set the s, t, and light gradients, which are consistent across the triangle
718: // because being a triangle, things are affine
719: //
720: D_PolysetCalcGradients (r_affinetridesc.skinwidth);
721:
722: //
723: // rasterize the polygon
724: //
725:
726: //
727: // scan out the top (and possibly only) part of the left edge
728: //
729: D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
730: pleftbottom[0], pleftbottom[1]);
731:
732: d_pedgespanpackage = a_spans;
733:
734: ystart = plefttop[1];
735: d_aspancount = plefttop[0] - prighttop[0];
736:
737: d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
738: (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
739: #if id386
740: d_sfrac = (plefttop[2] & 0xFFFF) << 16;
741: d_tfrac = (plefttop[3] & 0xFFFF) << 16;
742: d_pzbasestep = (d_zwidth + ubasestep) << 1;
743: d_pzextrastep = d_pzbasestep + 2;
744: #else
745: d_sfrac = plefttop[2] & 0xFFFF;
746: d_tfrac = plefttop[3] & 0xFFFF;
747: d_pzbasestep = d_zwidth + ubasestep;
748: d_pzextrastep = d_pzbasestep + 1;
749: #endif
750: d_light = plefttop[4];
751: d_zi = plefttop[5];
752:
753: d_pdestbasestep = screenwidth + ubasestep;
754: d_pdestextrastep = d_pdestbasestep + 1;
755: d_pdest = (byte *)d_viewbuffer +
756: ystart * screenwidth + plefttop[0];
757: d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
758:
759: // TODO: can reuse partial expressions here
760:
761: // for negative steps in x along left edge, bias toward overflow rather than
762: // underflow (sort of turning the floor () we did in the gradient calcs into
763: // ceil (), but plus a little bit)
764: if (ubasestep < 0)
765: working_lstepx = r_lstepx - 1;
766: else
767: working_lstepx = r_lstepx;
768:
769: d_countextrastep = ubasestep + 1;
770: d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
771: ((r_tstepy + r_tstepx * ubasestep) >> 16) *
772: r_affinetridesc.skinwidth;
773: #if id386
774: d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
775: d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
776: #else
777: d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
778: d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
779: #endif
780: d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
781: d_zibasestep = r_zistepy + r_zistepx * ubasestep;
782:
783: d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
784: ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
785: r_affinetridesc.skinwidth;
786: #if id386
787: d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
788: d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
789: #else
790: d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
791: d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
792: #endif
793: d_lightextrastep = d_lightbasestep + working_lstepx;
794: d_ziextrastep = d_zibasestep + r_zistepx;
795:
796: D_PolysetScanLeftEdge (initialleftheight);
797:
798: //
799: // scan out the bottom part of the left edge, if it exists
800: //
801: if (pedgetable->numleftedges == 2)
802: {
803: int height;
804:
805: plefttop = pleftbottom;
806: pleftbottom = pedgetable->pleftedgevert2;
807:
808: D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
809: pleftbottom[0], pleftbottom[1]);
810:
811: height = pleftbottom[1] - plefttop[1];
812:
813: // TODO: make this a function; modularize this function in general
814:
815: ystart = plefttop[1];
816: d_aspancount = plefttop[0] - prighttop[0];
817: d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
818: (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
819: d_sfrac = 0;
820: d_tfrac = 0;
821: d_light = plefttop[4];
822: d_zi = plefttop[5];
823:
824: d_pdestbasestep = screenwidth + ubasestep;
825: d_pdestextrastep = d_pdestbasestep + 1;
826: d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
827: #if id386
828: d_pzbasestep = (d_zwidth + ubasestep) << 1;
829: d_pzextrastep = d_pzbasestep + 2;
830: #else
831: d_pzbasestep = d_zwidth + ubasestep;
832: d_pzextrastep = d_pzbasestep + 1;
833: #endif
834: d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
835:
836: if (ubasestep < 0)
837: working_lstepx = r_lstepx - 1;
838: else
839: working_lstepx = r_lstepx;
840:
841: d_countextrastep = ubasestep + 1;
842: d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
843: ((r_tstepy + r_tstepx * ubasestep) >> 16) *
844: r_affinetridesc.skinwidth;
845: #if id386
846: d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
847: d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
848: #else
849: d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
850: d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
851: #endif
852: d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
853: d_zibasestep = r_zistepy + r_zistepx * ubasestep;
854:
855: d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
856: ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
857: r_affinetridesc.skinwidth;
858: #if id386
859: d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
860: d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
861: #else
862: d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
863: d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
864: #endif
865: d_lightextrastep = d_lightbasestep + working_lstepx;
866: d_ziextrastep = d_zibasestep + r_zistepx;
867:
868: D_PolysetScanLeftEdge (height);
869: }
870:
871: // scan out the top (and possibly only) part of the right edge, updating the
872: // count field
873: d_pedgespanpackage = a_spans;
874:
875: D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
876: prightbottom[0], prightbottom[1]);
877: d_aspancount = 0;
878: d_countextrastep = ubasestep + 1;
879: originalcount = a_spans[initialrightheight].count;
880: a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
881: D_PolysetDrawSpans8 (a_spans);
882:
883: // scan out the bottom part of the right edge, if it exists
884: if (pedgetable->numrightedges == 2)
885: {
886: int height;
887: spanpackage_t *pstart;
888:
889: pstart = a_spans + initialrightheight;
890: pstart->count = originalcount;
891:
892: d_aspancount = prightbottom[0] - prighttop[0];
893:
894: prighttop = prightbottom;
895: prightbottom = pedgetable->prightedgevert2;
896:
897: height = prightbottom[1] - prighttop[1];
898:
899: D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
900: prightbottom[0], prightbottom[1]);
901:
902: d_countextrastep = ubasestep + 1;
903: a_spans[initialrightheight + height].count = -999999;
904: // mark end of the spanpackages
905: D_PolysetDrawSpans8 (pstart);
906: }
907: }
908:
909:
910: /*
911: ================
912: D_PolysetSetEdgeTable
913: ================
914: */
915: void D_PolysetSetEdgeTable (void)
916: {
917: int edgetableindex;
918:
919: edgetableindex = 0; // assume the vertices are already in
920: // top to bottom order
921:
922: //
923: // determine which edges are right & left, and the order in which
924: // to rasterize them
925: //
926: if (r_p0[1] >= r_p1[1])
927: {
928: if (r_p0[1] == r_p1[1])
929: {
930: if (r_p0[1] < r_p2[1])
931: pedgetable = &edgetables[2];
932: else
933: pedgetable = &edgetables[5];
934:
935: return;
936: }
937: else
938: {
939: edgetableindex = 1;
940: }
941: }
942:
943: if (r_p0[1] == r_p2[1])
944: {
945: if (edgetableindex)
946: pedgetable = &edgetables[8];
947: else
948: pedgetable = &edgetables[9];
949:
950: return;
951: }
952: else if (r_p1[1] == r_p2[1])
953: {
954: if (edgetableindex)
955: pedgetable = &edgetables[10];
956: else
957: pedgetable = &edgetables[11];
958:
959: return;
960: }
961:
962: if (r_p0[1] > r_p2[1])
963: edgetableindex += 2;
964:
965: if (r_p1[1] > r_p2[1])
966: edgetableindex += 4;
967:
968: pedgetable = &edgetables[edgetableindex];
969: }
970:
971:
972: #if 0
973:
974: void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
975: {
976: int d;
977: int new[6];
978: int ofs;
979:
980: d = lp2[0] - lp1[0];
981: if (d < -1 || d > 1)
982: goto split;
983: d = lp2[1] - lp1[1];
984: if (d < -1 || d > 1)
985: goto split;
986:
987: return; // line is completed
988:
989: split:
990: // split this edge
991: new[0] = (lp1[0] + lp2[0]) >> 1;
992: new[1] = (lp1[1] + lp2[1]) >> 1;
993: new[5] = (lp1[5] + lp2[5]) >> 1;
994: new[2] = (lp1[2] + lp2[2]) >> 1;
995: new[3] = (lp1[3] + lp2[3]) >> 1;
996: new[4] = (lp1[4] + lp2[4]) >> 1;
997:
998: // draw the point
999: ofs = d_scantable[new[1]] + new[0];
1000: if (new[5] > d_pzbuffer[ofs])
1001: {
1002: int pix;
1003:
1004: d_pzbuffer[ofs] = new[5];
1005: pix = skintable[new[3]>>16][new[2]>>16];
1006: // pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)];
1007: d_viewbuffer[ofs] = pix;
1008: }
1009:
1010: // recursively continue
1011: D_PolysetRecursiveDrawLine (lp1, new);
1012: D_PolysetRecursiveDrawLine (new, lp2);
1013: }
1014:
1015: void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
1016: {
1017: int d;
1018: int new[4];
1019:
1020: d = lp2[0] - lp1[0];
1021: if (d < -1 || d > 1)
1022: goto split;
1023: d = lp2[1] - lp1[1];
1024: if (d < -1 || d > 1)
1025: goto split;
1026: return;
1027:
1028: split:
1029: // split this edge
1030: new[0] = (lp1[0] + lp2[0]) >> 1;
1031: new[1] = (lp1[1] + lp2[1]) >> 1;
1032: new[5] = (lp1[5] + lp2[5]) >> 1;
1033: new[2] = (lp1[2] + lp2[2]) >> 1;
1034: new[3] = (lp1[3] + lp2[3]) >> 1;
1035: new[4] = (lp1[4] + lp2[4]) >> 1;
1036:
1037: D_PolysetRecursiveDrawLine (new, lp3);
1038:
1039: // recursively continue
1040: D_PolysetRecursiveTriangle (lp1, new, lp3);
1041: D_PolysetRecursiveTriangle (new, lp2, lp3);
1042: }
1043:
1044: #endif
1045:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.