@@ -13,10 +13,10 @@ void viewport(int x, int y, int w, int h) {
1313 Viewport = Matrix::identity ();
1414 Viewport[0 ][3 ] = x+w/2 .f ;
1515 Viewport[1 ][3 ] = y+h/2 .f ;
16- Viewport[2 ][3 ] = depth/ 2 .f ;
16+ Viewport[2 ][3 ] = 1 .f ;
1717 Viewport[0 ][0 ] = w/2 .f ;
1818 Viewport[1 ][1 ] = h/2 .f ;
19- Viewport[2 ][2 ] = depth/ 2 . f ;
19+ Viewport[2 ][2 ] = 0 ;
2020}
2121
2222void projection (float coeff) {
@@ -28,13 +28,15 @@ void lookat(Vec3f eye, Vec3f center, Vec3f up) {
2828 Vec3f z = (eye-center).normalize ();
2929 Vec3f x = cross (up,z).normalize ();
3030 Vec3f y = cross (z,x).normalize ();
31- ModelView = Matrix::identity ();
31+ Matrix Minv = Matrix::identity ();
32+ Matrix Tr = Matrix::identity ();
3233 for (int i=0 ; i<3 ; i++) {
33- ModelView [0 ][i] = x[i];
34- ModelView [1 ][i] = y[i];
35- ModelView [2 ][i] = z[i];
36- ModelView [i][3 ] = -center[i];
34+ Minv [0 ][i] = x[i];
35+ Minv [1 ][i] = y[i];
36+ Minv [2 ][i] = z[i];
37+ Tr [i][3 ] = -center[i];
3738 }
39+ ModelView = Minv*Tr;
3840}
3941
4042Vec3f barycentric (Vec2f A, Vec2f B, Vec2f C, Vec2f P) {
@@ -50,25 +52,30 @@ Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) {
5052 return Vec3f (-1 ,1 ,1 ); // in this case generate negative coordinates, it will be thrown away by the rasterizator
5153}
5254
53- void triangle (Vec4f *pts, IShader &shader, TGAImage &image, float *zbuffer) {
55+ void triangle (mat<4 ,3 ,float > &clipc, IShader &shader, TGAImage &image, float *zbuffer) {
56+ mat<3 ,4 ,float > pts = (Viewport*clipc).transpose (); // transposed to ease access to each of the points
57+ mat<3 ,2 ,float > pts2;
58+ for (int i=0 ; i<3 ; i++) pts2[i] = proj<2 >(pts[i]/pts[i][3 ]);
59+
5460 Vec2f bboxmin ( std::numeric_limits<float >::max (), std::numeric_limits<float >::max ());
5561 Vec2f bboxmax (-std::numeric_limits<float >::max (), -std::numeric_limits<float >::max ());
62+ Vec2f clamp (image.get_width ()-1 , image.get_height ()-1 );
5663 for (int i=0 ; i<3 ; i++) {
5764 for (int j=0 ; j<2 ; j++) {
58- bboxmin[j] = std::min (bboxmin[j], pts [i][j]/pts[i][ 3 ] );
59- bboxmax[j] = std::max (bboxmax[j], pts [i][j]/pts[i][ 3 ] );
65+ bboxmin[j] = std::max ( 0 . f , std:: min (bboxmin[j], pts2 [i][j]) );
66+ bboxmax[j] = std::min (clamp[j], std:: max (bboxmax[j], pts2 [i][j]) );
6067 }
6168 }
6269 Vec2i P;
6370 TGAColor color;
6471 for (P.x =bboxmin.x ; P.x <=bboxmax.x ; P.x ++) {
6572 for (P.y =bboxmin.y ; P.y <=bboxmax.y ; P.y ++) {
66- Vec3f c = barycentric (proj< 2 >(pts [0 ]/pts[ 0 ][ 3 ]), proj< 2 >(pts [1 ]/pts[ 1 ][ 3 ]), proj< 2 >(pts [2 ]/pts[ 2 ][ 3 ]), proj< 2 >(P) );
67- float z = pts[0 ][2 ]*c. x + pts[1 ][2 ]*c. y + pts[2 ][2 ]*c. z ;
68- float w = pts[ 0 ][ 3 ]*c. x + pts[ 1 ][ 3 ]*c. y + pts[ 2 ][ 3 ]*c. z ;
69- int frag_depth = z/w ;
70- if (c .x <0 || c .y <0 || c .z <0 || zbuffer[P.x +P.y *image.get_width ()]>frag_depth) continue ;
71- bool discard = shader.fragment (c , color);
73+ Vec3f bc_screen = barycentric (pts2 [0 ], pts2 [1 ], pts2 [2 ], P );
74+ Vec3f bc_clip = Vec3f (bc_screen. x / pts[0 ][3 ], bc_screen. y / pts[1 ][3 ], bc_screen. z / pts[2 ][3 ]) ;
75+ bc_clip = bc_clip/(bc_clip. x +bc_clip. y +bc_clip. z ) ;
76+ float frag_depth = clipc[ 2 ]*bc_clip ;
77+ if (bc_screen .x <0 || bc_screen .y <0 || bc_screen .z <0 || zbuffer[P.x +P.y *image.get_width ()]>frag_depth) continue ;
78+ bool discard = shader.fragment (Vec3f (P. x , P. y , frag_depth), bc_clip , color);
7279 if (!discard) {
7380 zbuffer[P.x +P.y *image.get_width ()] = frag_depth;
7481 image.set (P.x , P.y , color);
0 commit comments