nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@9: #include nuclear@0: #include nuclear@0: #include "mingl.h" nuclear@0: #include "mglimpl.h" nuclear@0: nuclear@0: nuclear@25: #ifdef RAST_FLOAT nuclear@25: typedef struct vertex VERTEX; nuclear@25: #else nuclear@25: typedef struct fixed_vertex VERTEX; nuclear@25: #endif nuclear@25: nuclear@25: static VERTEX *vleft, *vright; nuclear@0: static struct framebuffer *fb; nuclear@0: static struct state *st; nuclear@0: nuclear@0: nuclear@0: #define SCAN_EDGE scan_edge_flat nuclear@0: #define SCAN_LINE scan_line_flat nuclear@0: #undef INTERP_DEPTH nuclear@0: #undef INTERP_ENERGY nuclear@3: #undef INTERP_TEX nuclear@0: #include "scantmpl.h" nuclear@0: #undef SCAN_EDGE nuclear@0: #undef SCAN_LINE nuclear@0: nuclear@0: #define SCAN_EDGE scan_edge_z nuclear@0: #define SCAN_LINE scan_line_z nuclear@0: #define INTERP_DEPTH nuclear@0: #undef INTERP_ENERGY nuclear@3: #undef INTERP_TEX nuclear@0: #include "scantmpl.h" nuclear@0: #undef SCAN_EDGE nuclear@0: #undef SCAN_LINE nuclear@0: nuclear@0: #define SCAN_EDGE scan_edge_e nuclear@0: #define SCAN_LINE scan_line_e nuclear@0: #undef INTERP_DEPTH nuclear@0: #define INTERP_ENERGY nuclear@3: #undef INTERP_TEX nuclear@0: #include "scantmpl.h" nuclear@0: #undef SCAN_EDGE nuclear@0: #undef SCAN_LINE nuclear@0: nuclear@0: #define SCAN_EDGE scan_edge_ze nuclear@0: #define SCAN_LINE scan_line_ze nuclear@0: #define INTERP_DEPTH nuclear@0: #define INTERP_ENERGY nuclear@3: #undef INTERP_TEX nuclear@0: #include "scantmpl.h" nuclear@0: #undef SCAN_EDGE nuclear@0: #undef SCAN_LINE nuclear@0: nuclear@3: #define SCAN_EDGE scan_edge_t nuclear@3: #define SCAN_LINE scan_line_t nuclear@3: #undef INTERP_DEPTH nuclear@3: #undef INTERP_ENERGY nuclear@3: #define INTERP_TEX nuclear@3: #include "scantmpl.h" nuclear@3: #undef SCAN_EDGE nuclear@3: #undef SCAN_LINE nuclear@3: nuclear@3: #define SCAN_EDGE scan_edge_zt nuclear@3: #define SCAN_LINE scan_line_zt nuclear@3: #define INTERP_DEPTH nuclear@3: #undef INTERP_ENERGY nuclear@3: #define INTERP_TEX nuclear@3: #include "scantmpl.h" nuclear@3: #undef SCAN_EDGE nuclear@3: #undef SCAN_LINE nuclear@3: nuclear@3: #define SCAN_EDGE scan_edge_et nuclear@3: #define SCAN_LINE scan_line_et nuclear@3: #undef INTERP_DEPTH nuclear@3: #define INTERP_ENERGY nuclear@3: #define INTERP_TEX nuclear@3: #include "scantmpl.h" nuclear@3: #undef SCAN_EDGE nuclear@3: #undef SCAN_LINE nuclear@3: nuclear@3: #define SCAN_EDGE scan_edge_zet nuclear@3: #define SCAN_LINE scan_line_zet nuclear@3: #define INTERP_DEPTH nuclear@3: #define INTERP_ENERGY nuclear@3: #define INTERP_TEX nuclear@3: #include "scantmpl.h" nuclear@3: #undef SCAN_EDGE nuclear@3: #undef SCAN_LINE nuclear@3: nuclear@3: nuclear@25: static void (*scan_edge)(VERTEX*, VERTEX*); nuclear@0: static void (*scan_line)(int, unsigned char*); nuclear@0: nuclear@25: nuclear@0: int mgl_rast_init(struct state *state, struct framebuffer *fbuf) nuclear@0: { nuclear@0: fb = fbuf; nuclear@0: st = state; nuclear@0: nuclear@0: if(!(vleft = malloc(fb->height * sizeof *vleft))) { nuclear@0: return -1; nuclear@0: } nuclear@0: if(!(vright = malloc(fb->height * sizeof *vright))) { nuclear@0: free(vleft); nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@0: scan_edge = scan_edge_flat; nuclear@0: scan_line = scan_line_flat; nuclear@0: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void mgl_rast_cleanup(void) nuclear@0: { nuclear@0: free(vleft); nuclear@0: free(vright); nuclear@0: } nuclear@0: nuclear@0: void mgl_rast_prepare(void) nuclear@0: { nuclear@25: static void (*sedge[])(VERTEX*, VERTEX*) = { nuclear@3: /* tez */ nuclear@3: scan_edge_flat, /* 000 */ nuclear@3: scan_edge_z, /* 001 */ nuclear@3: scan_edge_e, /* 010 */ nuclear@3: scan_edge_ze, /* 011 */ nuclear@3: scan_edge_t, /* 100 */ nuclear@3: scan_edge_zt, /* 101 */ nuclear@3: scan_edge_et, /* 110 */ nuclear@3: scan_edge_zet /* 111 */ nuclear@0: }; nuclear@0: static void (*sline[])(int, unsigned char*) = { nuclear@3: /* tez */ nuclear@3: scan_line_flat, /* 000 */ nuclear@3: scan_line_z, /* 001 */ nuclear@3: scan_line_e, /* 010 */ nuclear@3: scan_line_ze, /* 011 */ nuclear@3: scan_line_t, /* 100 */ nuclear@3: scan_line_zt, /* 101 */ nuclear@3: scan_line_et, /* 110 */ nuclear@3: scan_line_zet /* 111 */ nuclear@0: }; nuclear@0: int bits = 0; nuclear@0: nuclear@28: if(IS_ENABLED(st->flags, MGL_TEXTURE_2D) && st->tex.pixels) { nuclear@3: bits |= 4; nuclear@3: } nuclear@28: if(IS_ENABLED(st->flags, MGL_SMOOTH)) { nuclear@0: bits |= 2; nuclear@0: } nuclear@28: if(IS_ENABLED(st->flags, MGL_DEPTH_TEST) && fb->zbuf) { nuclear@0: bits |= 1; nuclear@0: } nuclear@0: nuclear@0: scan_edge = sedge[bits]; nuclear@0: scan_line = sline[bits]; nuclear@0: } nuclear@0: nuclear@0: void mgl_draw_point(struct vertex *v) nuclear@0: { nuclear@0: int x = (int)ROUND(v->pos.x); nuclear@0: int y = (int)ROUND(v->pos.y); nuclear@0: nuclear@0: if(x >= 0 && x < fb->width && y >= 0 && y < fb->height) { nuclear@0: int cidx = v->cidx + v->energy * st->col_range; nuclear@0: fb->pixels[y * fb->width + x] = cidx; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void mgl_draw_line(struct vertex *v0, struct vertex *v1) nuclear@0: { nuclear@0: /* TODO */ nuclear@0: fprintf(stderr, "draw_line unimplemented\n"); nuclear@0: abort(); nuclear@0: } nuclear@0: nuclear@0: void mgl_draw_poly(struct vertex *v, int numv) nuclear@0: { nuclear@25: #ifdef RAST_FLOAT nuclear@0: int ybeg, yend, i; nuclear@0: unsigned char *sline; nuclear@0: nuclear@0: ybeg = fb->height; nuclear@0: yend = 0; nuclear@0: nuclear@0: for(i=0; ipos.y); nuclear@0: nuclear@0: scan_edge(v0, v1); nuclear@0: nuclear@0: if(y > yend) yend = y; nuclear@0: if(y < ybeg) ybeg = y; nuclear@0: } nuclear@0: nuclear@0: if(ybeg < 0) ybeg = 0; nuclear@0: if(yend >= fb->height) yend = fb->height - 1; nuclear@0: nuclear@0: sline = fb->pixels + ybeg * fb->width; nuclear@0: for(i=ybeg; iwidth; nuclear@0: } nuclear@25: #else nuclear@25: int ybeg, yend, i; nuclear@25: unsigned char *sline; nuclear@25: nuclear@25: ybeg = fb->height; nuclear@25: yend = 0; nuclear@25: nuclear@25: for(i=0; i yend) yend = y; nuclear@25: if(y < ybeg) ybeg = y; nuclear@25: } nuclear@25: nuclear@25: if(ybeg < 0) ybeg = 0; nuclear@25: if(yend >= fb->height) yend = fb->height - 1; nuclear@25: nuclear@25: sline = fb->pixels + ybeg * fb->width; nuclear@25: for(i=ybeg; iwidth; nuclear@25: } nuclear@25: #endif nuclear@0: }