void unblack (Bit2_T bitmap, int cur_x, int cur_y) { int w_pixels = Bit2_width (bitmap); int h_pixels = Bit2_height (bitmap); Seq_T point_queue = Seq_new(w_pixels*h_pixels); assert(point_queue); assert(0 <= cur_x && cur_x < w_pixels); assert(0 <= cur_y && cur_y < h_pixels); if (Bit2_get(bitmap, cur_x, cur_y) != 1) { // if pixel is white assert(point_queue); Seq_free(&point_queue); return; } else { Seq_addhi(point_queue, (void*)makePoint(cur_x,cur_y)); while (Seq_length(point_queue) > 0) { PointPair temp = (PointPair)Seq_remlo(point_queue); assert(temp); int i = temp->i; int j = temp->j; freePoint(temp); if (Bit2_get(bitmap, i, j) == 1) { // if current is black pixel Bit2_put(bitmap, i, j, 0); // set current to white assert(0 <= i && i < w_pixels); assert(0 <= j && j < h_pixels); if (j != 0 && j != h_pixels-1) { // if not a top/bottom pixel if (i+1 < w_pixels && Bit2_get(bitmap, i+1, j) == 1) { // if Seq_addhi(point_queue, (void*)makePoint(i+1,j)); } if (i > 0 && Bit2_get(bitmap, i-1, j) == 1) { Seq_addhi(point_queue, (void*)makePoint(i-1,j)); } } if (i != 0 && i != w_pixels-1) { if (j+1 < h_pixels && Bit2_get(bitmap, i, j+1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j+1)); } if (j > 0 && Bit2_get(bitmap, i, j-1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j-1)); } } } } assert(point_queue); Seq_free(&point_queue); return; } }
/* in is the direction of the incoming ray and d is the recusive depth */ void shade(point* p, vector* n, material* m, vector* in, color* c, int d) { /* so far, just finds ambient component of color */ c->r = m->amb * m->r * (1-m->a); c->g = m->amb * m->g * (1-m->a); c->b = m->amb * m->b * (1-m->a); for(unsigned i = 0; i < lights.size(); i++) { lighting* light = lights[i]; vector* li = (vector*)makePoint(light->p->x - p->x, light->p->y - p->y, light->p->z - p->z); normalize(li); GLfloat dot = dotProduct(li,n); vector* rm = (vector*)makePoint(2*dot*n->x - li->x, 2*dot*n->y - li->y, 2*dot*n->z - li->z); vector* v = (vector*)makePoint(-p->x, -p->y, -p->z); normalize(v); GLfloat specDot = dotProduct(rm, v); point n_p; /* next intersection point */ vector n_n; material* n_m; ray r; r.start = p; r.dir = li; n_p.w = 0.0; /* inialize to "no intersection" */ firstHit(&r,&n_p,&n_n,&n_m); if(n_p.w == 0.0) { if(dot > 0) { c->r += m->diff * light->c->r * dot; c->g += m->diff * light->c->g * dot; c->b += m->diff * light->c->b * dot; } if(specDot > 0) { specDot = pow(specDot, 16); c->r += m->spec * light->c->r * specDot; c->g += m->spec * light->c->g * specDot; c->b += m->spec * light->c->b * specDot; } } freePoint(li); freePoint(rm); freePoint(v); } if(d > 0) { color n_c; vector* in_r = (vector*)makePoint(-in->x, -in->y, -in->z); normalize(in_r); GLfloat dot = dotProduct(n,in_r); vector* ref = (vector*)makePoint(2*dot*n->x - in_r->x, 2*dot*n->y - in_r->y, 2*dot*n->z - in_r->z); point n_p; /* next intersection point */ vector n_n; material* n_m; ray r; r.start = p; r.dir = ref; n_p.w = 0.0; /* inialize to "no intersection" */ firstHit(&r,&n_p,&n_n,&n_m); //reflection if (n_p.w != 0.0) { shade(&n_p,&n_n,n_m,ref,&n_c,d-1); c->r += (d/(double)RAYDEPTH) * m->spec * n_c.r; c->g += (d/(double)RAYDEPTH) * m->spec * n_c.g; c->b += (d/(double)RAYDEPTH) * m->spec * n_c.b; } //refraction n_p.w = 0.0; r.dir = in; firstHit(&r, &n_p, &n_n, &n_m); if (n_p.w != 0.0) { shade(&n_p,&n_n,n_m,in,&n_c,d-1); c->r += (d/(double)RAYDEPTH) * m->a * n_c.r; c->g += (d/(double)RAYDEPTH) * m->a * n_c.g; c->b += (d/(double)RAYDEPTH) * m->a * n_c.b; } freePoint(in_r); freePoint(ref); } /* clamp color values to 1.0 */ if (c->r > 1.0) c->r = 1.0; if (c->g > 1.0) c->g = 1.0; if (c->b > 1.0) c->b = 1.0; }