X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=raster.cc;fp=raster.c;h=66109e756406ca78f37ed71457d0d5a36ef262e6;hb=03be53bf14d0c2e1e3e19356376491945cdd78c8;hp=dcbe76fe767015fff447f1d5206a35618fc1fb17;hpb=bc662e293c854e1bdc9d46e9a410fe220247e6d4;p=chaz%2Frasterize diff --git a/raster.c b/raster.cc similarity index 50% rename from raster.c rename to raster.cc index dcbe76f..66109e7 100644 --- a/raster.c +++ b/raster.cc @@ -5,40 +5,19 @@ * mcgarvey@eng.utah.edu */ -#include -#include -#include -#include +#include +#include +#include +#include -#include "list.h" -#include "raster.h" +#include "raster.hh" struct raster { color_t* pixels; - scal_t* zbuf; int w, h; int left, right, bottom, top; - mat_t model; - mat_t view; - mat_t projection; - mat_t modelviewprojection; - mat_t viewport; - bool dirty; - const model_t* current; -#if LIGHTING - list_t* lights; - color_t ambient; - vec_t eye; - color_t specular; - scal_t shininess; -#endif -#if VERBOSITY >= 2 - unsigned total; - unsigned clipped; - unsigned culled; -#endif }; @@ -53,21 +32,6 @@ raster_t* raster_alloc(int width, int height, color_t fill) p->h = height; raster_clear(p, fill); raster_viewport(p, 0, 0, width, height); - p->model = p->view = p->projection = MAT_IDENTITY; - p->dirty = false; - p->current = NULL; - -#if LIGHTING - p->ambient = color_new(S(0.2), S(0.2), S(0.2), S(1.0)); - p->lights = NULL; - p->specular = COLOR_WHITE; - p->shininess = S(1.0); -#endif - - p->zbuf = (scal_t*)mem_alloc(sizeof(scal_t) * size); - for (size_t i = 0; i < size; ++i) { - p->zbuf[i] = S(1.0); - } return p; } @@ -75,32 +39,13 @@ raster_t* raster_alloc(int width, int height, color_t fill) void raster_destroy(raster_t* p) { mem_free(p->pixels); - mem_free(p->zbuf); -#if LIGHTING - list_destroy(&p->lights); -#endif mem_free(p); } -void raster_printstats(raster_t* p) -{ -#if VERBOSITY >= 2 - unsigned drawn = p->total - p->clipped - p->culled; - float percent = 100.0f * (float)drawn / (float)p->total; - printf("culled\t%u\n" - "clipped\t%u\n" - "drawn\t%u (%6.2f%%)\n" - "total\t%u\n", p->culled, p->clipped, drawn, percent, p->total); -#endif -} - - -color_t raster_color(const raster_t* p, vec_t pt) +color_t* raster_color(const raster_t* p, int x, int y) { - int u = (int)((scal_t)p->w * pt.x); - int v = (int)((scal_t)p->h * pt.y); - return p->pixels[p->w * (p->h - v - 1) + u]; + return p->pixels + p->w * y + x; } int raster_width(const raster_t* p) @@ -116,7 +61,7 @@ int raster_height(const raster_t* p) void* raster_data(const raster_t* p) { size_t size = p->w * p->h; - rgba_t* data = mem_alloc(size * sizeof(rgba_t)); + rgba_t* data = (rgba_t*)mem_alloc(size * sizeof(rgba_t)); for (int i = 0; i < size; ++i) { data[i] = rgba_from_color(p->pixels[i]); @@ -131,11 +76,6 @@ void raster_clear(raster_t* p, color_t fill) for (int i = 0; i < size; ++i) { p->pixels[i] = fill; } -#if VERBOSITY >= 2 - p->total = 0; - p->clipped = 0; - p->culled = 0; -#endif } @@ -145,56 +85,6 @@ void raster_viewport(raster_t* p, int x, int y, int width, int height) p->right = x + width; p->bottom = y; p->top = y + height; - p->viewport = MAT_VIEWPORT(x, y, width, height); -} - -void raster_model(raster_t* p, const mat_t* transform) -{ - p->model = *transform; - p->dirty = true; -} - -void raster_view(raster_t* p, const mat_t* transform) -{ - p->view = *transform; - p->dirty = true; -} - -void raster_projection(raster_t* p, const mat_t* transform) -{ - p->projection = *transform; - p->dirty = true; -} - - -void raster_eye(raster_t* p, vec_t eye) -{ -#if LIGHTING - p->eye = eye; -#endif -} - -void raster_ambient(raster_t* p, color_t ambient) -{ -#if LIGHTING - p->ambient = ambient; -#endif -} - -void raster_light(raster_t* p, light_t light) -{ -#if LIGHTING - light_t* l = light_copy(light); - list_push2(&p->lights, l, mem_free); -#endif -} - -void raster_material(raster_t* p, color_t specular, scal_t shininess) -{ -#if LIGHTING - p->specular = specular; - p->shininess = shininess; -#endif } @@ -287,8 +177,8 @@ fail: fprintf(stderr, "Cannot write to %s: %s\n", filename, strerror(errno)); raster_t* raster_import(const char* filename) { - int type = 0; - char* ext = strrchr(filename, '.'); + int type = 0; + const char* ext = strrchr(filename, '.'); if (ext == NULL) { goto fail; } @@ -362,6 +252,8 @@ raster_t* raster_import_bmp(const char* filename) return NULL; } + size_t size; + uint16_t magicNumber; uint16_t reserved0;//0x4D41; uint16_t reserved1;//0x5454; @@ -400,7 +292,7 @@ raster_t* raster_import_bmp(const char* filename) p = raster_alloc((int)width, (int)height, COLOR_WHITE); - size_t size = width * height; + size = width * height; for (int i = 0; i < size; ++i) { union { @@ -438,220 +330,3 @@ fail: #undef _DO_OR_DIE - -void raster_draw_model(raster_t* p, const model_t* model) -{ -#if VERBOSITY >= 4 -#define PROGRESS_FMT "\033[80D\033[2K %s\t %9d / %d" - int tri; -#endif - - model_transformation(model, &p->model); - p->dirty = true; - raster_material(p, model_specular(model), model_shininess(model)); - p->current = model; - IF_RENDER_PROGRESS(tri = 0); - array_it_t it = array_begin(model_geometry(model)); - for (tri_t* t; t = array_it_tri_next(&it);) { -#if VERBOSITY >= 4 - if (++tri % 100 == 0) { - printf(PROGRESS_FMT, model_name(model), tri, model_size(model)); - fflush(stdout); - } -#endif - raster_draw_tri(p, t); - } -#if VERBOSITY >= 4 - printf(PROGRESS_FMT"\n", model_name(model), tri, model_size(model)); -#endif -} - - -/* - * See if the triangle is at all visible in the viewport. Also, minimize the - * rectangle around the area that includes the triangle. - */ -INLINE_MAYBE -bool _try_clip(tri_t t, int* left, int* right, int* bottom, int* top) -{ -#if CLIPPING - aabb_t box = tri_aabb(t); - if (box.min.z < S(-1.0) || S(1.0) < box.max.z) { - return false; - } - *left = imax((int)scal_floor(box.min.x), *left); - *right = imin((int)scal_ceil(box.max.x), *right); - if (*right <= *left) { - return false; - } - *bottom = imax((int)scal_floor(box.min.y), *bottom); - *top = imin((int)scal_ceil(box.max.y), *top); - if (*top <= *bottom) { - return false; - } -#endif // CLIPPING - return true; -} - -/* - * See whether or not we need to draw based on the orientation of the - * triangle. - */ -INLINE_MAYBE -bool _try_cull_backface(tri_t t) -{ -#if BACKFACE_CULLING - vec_t n = tri_normal(t); - if (n.z < S(0.0)) { - return false; - } -#endif - return true; -} - -/* - * Determine what color is associated with the given vertex. - */ -INLINE_MAYBE -color_t _do_phong_lighting(raster_t* p, vert_t vert) -{ -#if TEXTURING - vert.c = color_mult(vert.c, model_tcolor(p->current, vert.t)); -#endif -#if LIGHTING - color_t color = COLOR_BLACK; - color.a = vert.c.a; - for (list_t* i = p->lights; i; i = i->link) { - light_t light = *(light_t*)i->val; - vec_t mpos = vert.v; - vec_t lpos = light.v; - vec_t vpos = p->eye; - vec_t n = vert.n; - vec_t l = vec_normalize(vec_sub(lpos, mpos)); - vec_t r = vec_normalize(vec_sub(vec_scale(n, S(2.0) * vec_dot(n, l)), l)); - vec_t v = vec_normalize(vec_sub(vpos, mpos)); - - scal_t kd = scal_max(vec_dot(l, n), S(0.0)); - color_t Id = color_scale2(light.d, vert.c, kd); - scal_t ks = scal_pow(scal_max(vec_dot(r, v), S(0.0)), p->shininess); - color_t Is = color_scale2(light.s, p->specular, ks); - - color = color_add2(color, Id, Is); - } - color_t Ia = color_mult(p->ambient, vert.c); - return color_clamp(color_add(color, Ia)); -#else - return vert.c; -#endif // LIGHTING -} - -void raster_draw_tri(raster_t* p, const tri_t* triangle) -{ - IF_RASTER_STATS(++p->total); - tri_t t = *triangle; - - // need to recalculate the model-view-projection matrix if any one of its - // composing matrices have been changed - if (p->dirty) { - p->modelviewprojection = mat_mult(p->view, p->model); - p->modelviewprojection = mat_mult(p->projection, p->modelviewprojection); - p->dirty = false; - } - - t = tri_transform(t, p->modelviewprojection); - - // save w-values for texture mapping perspective correction - scal_t w1 = t.a.v.w; - scal_t w2 = t.b.v.w; - scal_t w3 = t.c.v.w; - - t = tri_homodiv(t); - - if (!_try_cull_backface(t)) { - IF_RASTER_STATS(++p->culled); - return; - } - - t = tri_transform(t, p->viewport); - - int left = p->left; - int right = p->right; - int bottom = p->bottom; - int top = p->top; - - if (!_try_clip(t, &left, &right, &bottom, &top)) { - IF_RASTER_STATS(++p->clipped); - return; - } - -#if LIGHTING >= 1 - tri_t tl = tri_transform(*triangle, p->model); - tl.a.t.w = w1; - tl.b.t.w = w2; - tl.c.t.w = w3; -#endif - -#if LIGHTING == 1 - vert_t tv = vert_new(tri_midpoint(tl)); - tv.n = vec_normalize(tri_normal(tl)); - tv.c = tri_color(tl); - color_t color = _do_phong_lighting(p, tv); -#elif LIGHTING == 2 && SMOOTH_COLOR - color_t color1 = _do_phong_lighting(p, tl.a); - color_t color2 = _do_phong_lighting(p, tl.b); - color_t color3 = _do_phong_lighting(p, tl.c); -#elif LIGHTING == 2 && !SMOOTH_COLOR - color_t c = tri_color(t); - tl.a.c = tl.b.c = tl.c.c = c; - color_t color1 = _do_phong_lighting(p, tl.a); - color_t color2 = _do_phong_lighting(p, tl.b); - color_t color3 = _do_phong_lighting(p, tl.c); -#elif !LIGHTING && SMOOTH_COLOR - color_t color1 = t.a.c; - color_t color2 = t.b.c; - color_t color3 = t.c.c; -#else - color_t color = tri_color(t); -#endif - - for (int y = bottom; y < top; ++y) { - for (int x = left; x < right; ++x) { - vec_t v = vec_new((scal_t)x, (scal_t)y, S(0.0)); - scal_t b[3]; - if (tri_barycentric(t, b, v)) { -#if DEPTH_TEST - v.z = tri_z(t, b); - scal_t* n = p->zbuf + y * p->w + x; - if (S(-1.0) < v.z && v.z < *n) { -#endif - color_t* c = p->pixels + y * p->w + x; - color_t newC; - -#if LIGHTING == 2 || (!LIGHTING && SMOOTH_COLOR) - newC = color_interp2(color1, color2, color3, b); -#elif LIGHTING == 3 && SMOOTH_COLOR - newC = _do_phong_lighting(p, tri_interp(tl, b)); -#elif LIGHTING == 3 && !SMOOTH_COLOR - vert_t d = vert_new(tri_point(t, b)); - d.c = tri_color(t); - d.n = tri_normal2(t, b); - newC = _do_phong_lighting(p, d); -#else - newC = color; -#endif - -#if BLENDING - *c = color_blend(*c, newC); -#else - *c = newC; -#endif - -#if DEPTH_TEST - *n = v.z; - } -#endif - } - } - } -} -