deepstone
view src/mglrast.c @ 38:17a5107b6fa4
- added perspective correct interpolation
- added recording functionality
- added video capture functionality
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 10 Mar 2014 17:24:42 +0200 |
parents | 11d14f688485 |
children |
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 #ifdef TEXMAP_PERSP_CORRECT
191 for(i=0; i<numv; i++) {
192 v[i].tc.x /= v[i].pos.w;
193 v[i].tc.y /= v[i].pos.w;
194 v[i].pos.w = 1.0 / v[i].pos.w;
195 }
196 #endif
198 for(i=0; i<numv; i++) {
199 struct vertex *v0 = v + i;
200 struct vertex *v1 = v + (i + 1) % numv;
201 int y = (int)ROUND(v0->pos.y);
203 scan_edge(v0, v1);
205 if(y > yend) yend = y;
206 if(y < ybeg) ybeg = y;
207 }
209 if(ybeg < 0) ybeg = 0;
210 if(yend >= fb->height) yend = fb->height - 1;
212 sline = fb->pixels + ybeg * fb->width;
213 for(i=ybeg; i<yend; i++) {
214 scan_line(i, sline);
215 sline += fb->width;
216 }
217 #else
218 int ybeg, yend, i;
219 unsigned char *sline;
221 ybeg = fb->height;
222 yend = 0;
224 for(i=0; i<numv; i++) {
225 int y;
226 struct vertex *v0 = v + i;
227 struct vertex *v1 = v + (i + 1) % numv;
228 struct fixed_vertex vx0, vx1;
230 vertex_to_fixedvertex(*v0, vx0);
231 vertex_to_fixedvertex(*v1, vx1);
233 y = fixed_round(vx0.pos.y);
235 scan_edge(&vx0, &vx1);
237 if(y > yend) yend = y;
238 if(y < ybeg) ybeg = y;
239 }
241 if(ybeg < 0) ybeg = 0;
242 if(yend >= fb->height) yend = fb->height - 1;
244 sline = fb->pixels + ybeg * fb->width;
245 for(i=ybeg; i<yend; i++) {
246 scan_line(i, sline);
247 sline += fb->width;
248 }
249 #endif
250 }