gba-x3dtest

view src/polyfill.c @ 6:73b5f2e5d18a

first triangle on screen
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 18 Jun 2014 04:13:02 +0300
parents 850be43b3135
children fb0a0d6a8b52
line source
1 #include "config.h"
2 #include <string.h>
3 #include <assert.h>
4 #include "polyfill.h"
5 #include "fixed.h"
6 #include "gbasys.h"
8 static void fill_scanline(int y, int x0, int x1, uint16_t color);
10 void draw_poly(int num, const pvec3 *verts, uint16_t color)
11 {
12 int i, topidx = 0, botidx = 0;
13 int lidx[2], ridx[2];
14 int32_t y, topy, boty;
15 int32_t ldy, rdy, ldxdy, rdxdy;
16 int32_t lx, rx;
17 int start, end;
19 topy = boty = verts[0].y;
20 for(i=1; i<num; i++) {
21 int32_t y = verts[i].y;
22 if(y < topy) {
23 topy = y;
24 topidx = i;
25 }
26 if(y > boty) {
27 boty = y;
28 botidx = i;
29 }
30 }
32 lidx[0] = ridx[0] = topidx;
33 lidx[1] = topidx ? topidx - 1 : num - 1;
34 ridx[1] = (topidx + 1) % num;
36 if(verts[ridx[1]].x < verts[lidx[1]].x) {
37 return; /* backface (CCW) */
38 }
40 lx = rx = verts[lidx[0]].x;
42 /* TODO handle ldy == 0 or rdy == 0 */
43 ldy = verts[lidx[1]].y - verts[lidx[0]].y;
44 ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
46 rdy = verts[ridx[1]].y - verts[ridx[0]].y;
47 rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
49 start = topy >> 16;
50 end = boty >> 16;
52 if(end >= HEIGHT) end = HEIGHT - 1;
54 y = topy;
55 for(i=start; i<end; i++) {
56 unsigned short x0, x1;
58 x0 = lx < 0 ? 0 : (lx >> 16);
59 x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16);
61 if(i >= 0 && x1 > x0) {
62 fill_scanline(i, x0, x1, color);
63 }
65 if(y >= verts[lidx[1]].y) {
66 lidx[0] = lidx[1];
67 lidx[1] = lidx[1] ? lidx[1] - 1 : num - 1;
68 ldy = verts[lidx[1]].y - verts[lidx[0]].y;
69 if(ldy < 0) {
70 break;
71 }
72 ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
73 }
74 if(y >= verts[ridx[1]].y) {
75 ridx[0] = ridx[1];
76 ridx[1] = (ridx[1] + 1) % num;
77 rdy = verts[ridx[1]].y - verts[ridx[0]].y;
78 if(rdy < 0) {
79 break;
80 }
81 rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
82 }
84 lx += ldxdy;
85 rx += rdxdy;
86 y += 65536;
87 }
88 }
90 static void fill_scanline(int y, int x0, int x1, uint16_t color)
91 {
92 int i;
93 uint16_t *pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0;
95 for(i=x0; i<x1; i++) {
96 *pixels++ = color;
97 }
98 }