void SoftwareRendererImp::draw_point( Point& point ) { Vector2D p = transform(point.position); std::cout << point.transform << std::endl; rasterize_point( p.x, p.y, point.style.fillColor ); }
void SoftwareRendererImp::rasterize_triangle( float x0, float y0, float x1, float y1, float x2, float y2, Color color ) { //modify task 2: scale up the point location: /* x0 = 100.0 + 000.0; y0 = 000.0; x1 = 100.0 + 000.0; y1 = 100.0; x2 = 100.0 + 100.0; y2 = 100.0; */ //printf("Color: (%f, %f, %f, %f)\n", color.r, color.g, color.b, color.a); scale_point(x0, y0, sample_rate); scale_point(x1, y1, sample_rate); scale_point(x2, y2, sample_rate); // Task 2: // Implement triangle rasterization // Method 1: use bounding box, does not consider "edge rule" if (!cclock(x0, y0, x1, y1, x2, y2)) { //printf("before swap: (%f, %f, %f, %f)", x0, y0, x1, y1); swapPoints(x1, y1, x2, y2); //printf("after swap: (%f, %f, %f, %f)", x0, y0, x1, y1); } float lowX, highX, lowY, highY; lowX = (floor(min(min(x0, x1), x2))) + 0.5; lowY = (floor(min(min(y0, y1), y2))) + 0.5; highX = (ceil(max(max(x0, x1), x2))) - 0.5; highY = (ceil(max(max(y0, y1), y2))) - 0.5; for ( float x = lowX; x <= highX; x += 1 ) { for (float y = lowY; y <= highY; y += 1 ) { if (lineSide(x, y, x0, y0, x1, y1) && lineSide(x, y, x1, y1, x2, y2) && lineSide(x, y, x2, y2, x0, y0)) { rasterize_point(x, y, color); } } } }
void SoftwareRendererImp::rasterize_image( float x0, float y0, float x1, float y1, Texture& tex ) { // Problem: a slight offset from ref solution // Task ?: // Implement image rasterization //printf("(x0, y0, x1, y1): (%f, %f, %f, %f)\n", x0, y0, x1, y1); float x_start = floor(x0) + 0.5; float y_start = floor(y0) + 0.5; float x_end = ceil(x1) - 0.5; float y_end = ceil(y1) - 0.5; float scale_u = 1 / (x1 - x0); float scale_v = 1 / (y1 - y0); //printf("scale_u = %f, scale_v = %f\n", scale_u, scale_v); float u00, v00, u01, v01, u10, v10; float dux, dvx, duy, dvy; int d; Color c; //Sampler2DImp s2d (NEAREST); Sampler2DImp s2d (BILINEAR); Matrix3x3 scale; scale(0,0) = scale_u; scale(0,1) = 0.0 ; scale(0,2) = 0.0; scale(1,0) = 0.0 ; scale(1,1) = scale_v ; scale(1,2) = 0.0; scale(2,0) = 0.0 ; scale(2,1) = 0.0 ; scale(2,2) = 1.0; //std::cout << "scale: \n" << scale << std::endl; //change to identity Matrix3x3 move = Matrix3x3::identity(); move(0,2) = 0 - x0; move(1,2) = 0 - y0; //std::cout << "move: \n" << move << std::endl; /* for debug for ( float x = x_start; x <= x_start + 2; x++ ) { for (float y = y_start; y <= y_start + 2; y++ ) { */ for ( float x = x_start; x <= x_end - 1.0; x++ ) { for (float y = y_start; y <= y_end - 1.0; y++ ) { //printf("tex.width = %zu\n", tex.width); Vector3D s_space0 (x, y, 1.0); Vector3D t_space0 = scale * move * s_space0; u00 = t_space0.x / t_space0.z; v00 = t_space0.y / t_space0.z; Vector3D s_space1 (x + 1, y, 1.0); Vector3D t_space1 = scale * move * s_space1; u10 = t_space1.x / t_space1.z; v10 = t_space1.y / t_space1.z; Vector3D s_space2 (x, y + 1, 1.0); Vector3D t_space2 = scale * move * s_space2; u01 = t_space2.x / t_space2.z; v01 = t_space2.y / t_space2.z; //printf("(u00, v00), (u10, v10), (u01, v01): \n(%f, %f), (%f, %f), (%f, %f)\n", u00, v00, u10, v10, u01, v01); dux = u10 - u00; duy = u01 - u00; dvx = v10 - v00; dvy = v01 - v00; d = (int) log2(ceil(max(sqrt(dux * dux + dvx * dvx), sqrt(duy * duy + dvy * dvy)))); //printf("level d: %d\n", d); u00 = (x - x0) * scale_u; v00 = (y - y0) * scale_v; //c = s2d.sample_nearest(tex, u00, v00, d); c = s2d.sample_bilinear(tex, u00, v00, d); rasterize_point(x, y, c); } } }
void SoftwareRendererImp::rasterize_line(float x0, float y0, float x1, float y1, Color color) { // Task 1: // Implement line rasterization float temp; int steep = abs(y1 - y0) > abs(x1 - x0); if (steep) { temp = x0; x0 = y0; y0 = temp; temp = x1; x1 = y1; y1 = temp; } if (x0 > x1) { temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } float dx = x1 - x0; float dy = y1 - y0; float slope = dy / dx; // handle first end point float x, y, xgap, y_inter; float xstart, ystart, xend, yend; x = round(x0); y = y0 + slope * (x - x0); xgap = RFRAC_PART(x0 + 0.5); xstart = x; ystart = y; if (steep) { rasterize_point(ystart, xstart, RFRAC_PART(y) * xgap * color); rasterize_point(ystart + 1, xstart, FRAC_PART(y) * xgap * color); } else { rasterize_point(xstart, ystart, RFRAC_PART(y) * xgap * color); rasterize_point(xstart, ystart + 1, FRAC_PART(y) * xgap * color); } y_inter = y + slope; // handle second end point x = round(x1); y = y1 + slope * (x - x1); xgap = FRAC_PART(x1 + 0.5); xend = x; yend = y; if (steep) { rasterize_point(yend, xend, RFRAC_PART(y) * xgap * color); rasterize_point(yend + 1, xend, FRAC_PART(y) * xgap * color); } else { rasterize_point(xend, yend, RFRAC_PART(y) * xgap * color); rasterize_point(xend, yend + 1, FRAC_PART(y) * xgap * color); } y = y_inter; // handle points on the line for (x = xstart; x <= xend; x++) { if (steep) { rasterize_point(y, x, RFRAC_PART(y) * color); rasterize_point(y + 1, x, FRAC_PART(y) * color); } else { rasterize_point(x, y, RFRAC_PART(y) * color); rasterize_point(x, y + 1, FRAC_PART(y) * color); } y += slope; } }