1.
{ // just dumping the 2d scene (yay we have enough dimensions!) TGAImage scene(width, height, TGAImage::RGB); // scene "2d mesh" line(Vec2i(20, 34), Vec2i(744, 400), scene, red); line(Vec2i(120, 434), Vec2i(444, 400), scene, green); line(Vec2i(330, 463), Vec2i(594, 200), scene, blue); // screen line line(Vec2i(10, 10), Vec2i(790, 10), scene, white); scene.flip_vertically(); // i want to have the origin at the left bottom corner of the image scene.write_tga_file("scene.tga"); }
2.
TGAImage render(width, 16, TGAImage::RGB); int ybuffer[width]; for (int i=0; i<width; i++) { ybuffer[i] = std::numeric_limits<int>::min(); } rasterize(Vec2i(20, 34), Vec2i(744, 400), render, red, ybuffer); rasterize(Vec2i(120, 434), Vec2i(444, 400), render, green, ybuffer); rasterize(Vec2i(330, 463), Vec2i(594, 200), render, blue, ybuffer);
void rasterize(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color, int ybuffer[]) { if (p0.x>p1.x) { std::swap(p0, p1); } for (int x=p0.x; x<=p1.x; x++) { float t = (x-p0.x)/(float)(p1.x-p0.x); int y = p0.y*(1.-t) + p1.y*t; if (ybuffer[x]<y) { ybuffer[x] = y; image.set(x, 0, color); } } }
3.
triangle(screen_coords, float *zbuffer, image, TGAColor(intensity*255, intensity*255, intensity*255, 255), zbuffer); [...] void triangle(Vec3f *pts, float *zbuffer, TGAImage &image, TGAColor color) { Vec2f bboxmin( std::numeric_limits<float>::max(), std::numeric_limits<float>::max()); Vec2f bboxmax(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max()); Vec2f clamp(image.get_width()-1, image.get_height()-1); for (int i=0; i<3; i++) { for (int j=0; j<2; j++) { bboxmin[j] = std::max(0.f, std::min(bboxmin[j], pts[i][j])); bboxmax[j] = std::min(clamp[j], std::max(bboxmax[j], pts[i][j])); } } Vec3f P; for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) { for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) { Vec3f bc_screen = barycentric(pts[0], pts[1], pts[2], P); if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0) continue; P.z = 0; for (int i=0; i<3; i++) P.z += pts[i][2]*bc_screen[i]; if (zbuffer[int(P.x+P.y*width)]<P.z) { zbuffer[int(P.x+P.y*width)] = P.z; image.set(P.x, P.y, color); } } } }