1393cd200fc0b1b1906f51236cf229adb966d344
[dosdemo] / src / polyfill.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__)
6 #include <malloc.h>
7 #else
8 #include <alloca.h>
9 #endif
10 #include "polyfill.h"
11 #include "gfxutil.h"
12 #include "demo.h"
13
14 void (*fillfunc[])(struct pvertex*, int) = {
15         polyfill_wire,
16         polyfill_flat,
17         polyfill_gouraud,
18         polyfill_tex,
19         polyfill_tex_gouraud
20 };
21
22 struct pimage pfill_fb, pfill_tex;
23
24 void polyfill(int mode, struct pvertex *verts, int nverts)
25 {
26 #ifndef NDEBUG
27         if(!fillfunc[mode]) {
28                 fprintf(stderr, "polyfill mode %d not implemented\n", mode);
29                 abort();
30         }
31 #endif
32
33         fillfunc[mode](verts, nverts);
34 }
35
36 void polyfill_wire(struct pvertex *verts, int nverts)
37 {
38         int i, x0, y0, x1, y1;
39         struct pvertex *v = verts;
40         unsigned short color = ((v->r << 8) & 0xf800) |
41                 ((v->g << 3) & 0x7e0) | ((v->b >> 3) & 0x1f);
42
43         for(i=0; i<nverts - 1; i++) {
44                 x0 = v->x >> 8;
45                 y0 = v->y >> 8;
46                 ++v;
47                 x1 = v->x >> 8;
48                 y1 = v->y >> 8;
49                 if(clip_line(&x0, &y0, &x1, &y1, 0, 0, pfill_fb.width, pfill_fb.height)) {
50                         draw_line(x0, y0, x1, y1, color);
51                 }
52         }
53         x0 = verts[0].x >> 8;
54         y0 = verts[0].y >> 8;
55         if(clip_line(&x1, &y1, &x0, &y0, 0, 0, pfill_fb.width, pfill_fb.height)) {
56                 draw_line(x1, y1, x0, y0, color);
57         }
58 }
59
60 #define NEXTIDX(x) (((x) - 1 + nverts) % nverts)
61 #define PREVIDX(x) (((x) + 1) % nverts)
62
63 /* XXX
64  * When HIGH_QUALITY is defined, the rasterizer calculates slopes for attribute
65  * interpolation on each scanline separately; otherwise the slope for each
66  * attribute would be calculated once for the whole polygon, which is faster,
67  * but produces some slight quantization artifacts, due to the limited precision
68  * of fixed-point calculations.
69  */
70 #define HIGH_QUALITY
71
72 /* extra bits of precision to use when interpolating colors.
73  * try tweaking this if you notice strange quantization artifacts.
74  */
75 #define COLOR_SHIFT     12
76
77
78 #define POLYFILL polyfill_flat
79 #define SCANEDGE scanedge_flat
80 #undef GOURAUD
81 #undef TEXMAP
82 #include "polytmpl.h"
83 #undef POLYFILL
84 #undef SCANEDGE
85
86 #define POLYFILL polyfill_gouraud
87 #define SCANEDGE scanedge_gouraud
88 #define GOURAUD
89 #undef TEXMAP
90 #include "polytmpl.h"
91 #undef POLYFILL
92 #undef SCANEDGE
93
94 #define POLYFILL polyfill_tex
95 #define SCANEDGE scanedge_tex
96 #undef GOURAUD
97 #define TEXMAP
98 #include "polytmpl.h"
99 #undef POLYFILL
100 #undef SCANEDGE
101
102 #define POLYFILL polyfill_tex_gouraud
103 #define SCANEDGE scanedge_tex_gouraud
104 #define GOURAUD
105 #define TEXMAP
106 #include "polytmpl.h"
107 #undef POLYFILL
108 #undef SCANEDGE