deepstone
view src/mglrast.c @ 36:e234f2a4b6fa
ops
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 23 Sep 2013 07:42:56 +0300 |
parents | 5ff8ce78059a |
children | 17a5107b6fa4 |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <assert.h>
6 #include "mingl.h"
7 #include "mglimpl.h"
10 #ifdef RAST_FLOAT
11 typedef struct vertex VERTEX;
12 #else
13 typedef struct fixed_vertex VERTEX;
14 #endif
16 static VERTEX *vleft, *vright;
17 static struct framebuffer *fb;
18 static struct state *st;
21 #define SCAN_EDGE scan_edge_flat
22 #define SCAN_LINE scan_line_flat
23 #undef INTERP_DEPTH
24 #undef INTERP_ENERGY
25 #undef INTERP_TEX
26 #include "scantmpl.h"
27 #undef SCAN_EDGE
28 #undef SCAN_LINE
30 #define SCAN_EDGE scan_edge_z
31 #define SCAN_LINE scan_line_z
32 #define INTERP_DEPTH
33 #undef INTERP_ENERGY
34 #undef INTERP_TEX
35 #include "scantmpl.h"
36 #undef SCAN_EDGE
37 #undef SCAN_LINE
39 #define SCAN_EDGE scan_edge_e
40 #define SCAN_LINE scan_line_e
41 #undef INTERP_DEPTH
42 #define INTERP_ENERGY
43 #undef INTERP_TEX
44 #include "scantmpl.h"
45 #undef SCAN_EDGE
46 #undef SCAN_LINE
48 #define SCAN_EDGE scan_edge_ze
49 #define SCAN_LINE scan_line_ze
50 #define INTERP_DEPTH
51 #define INTERP_ENERGY
52 #undef INTERP_TEX
53 #include "scantmpl.h"
54 #undef SCAN_EDGE
55 #undef SCAN_LINE
57 #define SCAN_EDGE scan_edge_t
58 #define SCAN_LINE scan_line_t
59 #undef INTERP_DEPTH
60 #undef INTERP_ENERGY
61 #define INTERP_TEX
62 #include "scantmpl.h"
63 #undef SCAN_EDGE
64 #undef SCAN_LINE
66 #define SCAN_EDGE scan_edge_zt
67 #define SCAN_LINE scan_line_zt
68 #define INTERP_DEPTH
69 #undef INTERP_ENERGY
70 #define INTERP_TEX
71 #include "scantmpl.h"
72 #undef SCAN_EDGE
73 #undef SCAN_LINE
75 #define SCAN_EDGE scan_edge_et
76 #define SCAN_LINE scan_line_et
77 #undef INTERP_DEPTH
78 #define INTERP_ENERGY
79 #define INTERP_TEX
80 #include "scantmpl.h"
81 #undef SCAN_EDGE
82 #undef SCAN_LINE
84 #define SCAN_EDGE scan_edge_zet
85 #define SCAN_LINE scan_line_zet
86 #define INTERP_DEPTH
87 #define INTERP_ENERGY
88 #define INTERP_TEX
89 #include "scantmpl.h"
90 #undef SCAN_EDGE
91 #undef SCAN_LINE
94 static void (*scan_edge)(VERTEX*, VERTEX*);
95 static void (*scan_line)(int, unsigned char*);
98 int mgl_rast_init(struct state *state, struct framebuffer *fbuf)
99 {
100 fb = fbuf;
101 st = state;
103 if(!(vleft = malloc(fb->height * sizeof *vleft))) {
104 return -1;
105 }
106 if(!(vright = malloc(fb->height * sizeof *vright))) {
107 free(vleft);
108 return -1;
109 }
111 scan_edge = scan_edge_flat;
112 scan_line = scan_line_flat;
114 return 0;
115 }
117 void mgl_rast_cleanup(void)
118 {
119 free(vleft);
120 free(vright);
121 }
123 void mgl_rast_prepare(void)
124 {
125 static void (*sedge[])(VERTEX*, VERTEX*) = {
126 /* tez */
127 scan_edge_flat, /* 000 */
128 scan_edge_z, /* 001 */
129 scan_edge_e, /* 010 */
130 scan_edge_ze, /* 011 */
131 scan_edge_t, /* 100 */
132 scan_edge_zt, /* 101 */
133 scan_edge_et, /* 110 */
134 scan_edge_zet /* 111 */
135 };
136 static void (*sline[])(int, unsigned char*) = {
137 /* tez */
138 scan_line_flat, /* 000 */
139 scan_line_z, /* 001 */
140 scan_line_e, /* 010 */
141 scan_line_ze, /* 011 */
142 scan_line_t, /* 100 */
143 scan_line_zt, /* 101 */
144 scan_line_et, /* 110 */
145 scan_line_zet /* 111 */
146 };
147 int bits = 0;
149 if(IS_ENABLED(st->flags, MGL_TEXTURE_2D) && st->tex.pixels) {
150 bits |= 4;
151 }
152 if(IS_ENABLED(st->flags, MGL_SMOOTH)) {
153 bits |= 2;
154 }
155 if(IS_ENABLED(st->flags, MGL_DEPTH_TEST) && fb->zbuf) {
156 bits |= 1;
157 }
159 scan_edge = sedge[bits];
160 scan_line = sline[bits];
161 }
163 void mgl_draw_point(struct vertex *v)
164 {
165 int x = (int)ROUND(v->pos.x);
166 int y = (int)ROUND(v->pos.y);
168 if(x >= 0 && x < fb->width && y >= 0 && y < fb->height) {
169 int cidx = v->cidx + v->energy * st->col_range;
170 fb->pixels[y * fb->width + x] = cidx;
171 }
172 }
174 void mgl_draw_line(struct vertex *v0, struct vertex *v1)
175 {
176 /* TODO */
177 fprintf(stderr, "draw_line unimplemented\n");
178 abort();
179 }
181 void mgl_draw_poly(struct vertex *v, int numv)
182 {
183 #ifdef RAST_FLOAT
184 int ybeg, yend, i;
185 unsigned char *sline;
187 ybeg = fb->height;
188 yend = 0;
190 for(i=0; i<numv; i++) {
191 struct vertex *v0 = v + i;
192 struct vertex *v1 = v + (i + 1) % numv;
193 int y = (int)ROUND(v0->pos.y);
195 scan_edge(v0, v1);
197 if(y > yend) yend = y;
198 if(y < ybeg) ybeg = y;
199 }
201 if(ybeg < 0) ybeg = 0;
202 if(yend >= fb->height) yend = fb->height - 1;
204 sline = fb->pixels + ybeg * fb->width;
205 for(i=ybeg; i<yend; i++) {
206 scan_line(i, sline);
207 sline += fb->width;
208 }
209 #else
210 int ybeg, yend, i;
211 unsigned char *sline;
213 ybeg = fb->height;
214 yend = 0;
216 for(i=0; i<numv; i++) {
217 int y;
218 struct vertex *v0 = v + i;
219 struct vertex *v1 = v + (i + 1) % numv;
220 struct fixed_vertex vx0, vx1;
222 vertex_to_fixedvertex(*v0, vx0);
223 vertex_to_fixedvertex(*v1, vx1);
225 y = fixed_round(vx0.pos.y);
227 scan_edge(&vx0, &vx1);
229 if(y > yend) yend = y;
230 if(y < ybeg) ybeg = y;
231 }
233 if(ybeg < 0) ybeg = 0;
234 if(yend >= fb->height) yend = fb->height - 1;
236 sline = fb->pixels + ybeg * fb->width;
237 for(i=ybeg; i<yend; i++) {
238 scan_line(i, sline);
239 sline += fb->width;
240 }
241 #endif
242 }