Games101 作业2

需要填写三个地方的代码:

main.cpp 里面的 get_projection_matrix函数:

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
    // TODO: Copy-paste your implementation from the previous assignment.
    Eigen::Matrix4f projection;

    float n = zNear;
	float f = zFar;

	float t = tan(eye_fov/2) * abs(n);
    float b = -t;

	float r = aspect_ratio * t;
    float l = -r;

    Eigen::Matrix4f M_ortho_1,M_ortho_2,M_ortho;
	M_ortho_2 << 	2/(r-l), 0.0, 0.0, 0.0,
					0.0, 2/(t-b), 0.0, 0.0,
					0.0, 0.0, 2/(n-f), 0.0,
					0.0, 0.0, 0.0, 		1.0;

	M_ortho_1 << 	1.0, 0.0, 0.0, -(r+l)/2,
					0.0, 1.0, 0.0, -(t+b)/2,
					0.0, 0.0, 1.0, -(n+f)/2,
					0.0, 0.0, 0.0, 1.0;
	M_ortho = M_ortho_2 * M_ortho_1;

	Eigen::Matrix4f M_persp_ortho;
	M_persp_ortho << n, 0.0, 0.0, 0.0,
					0.0, n, 0.0, 0.0,
					0.0, 0.0, n+f, -n*f,
					0.0, 0.0, 1.0, 0.0;
	M_ortho = M_ortho_2 * M_ortho_1;

    projection = M_ortho * M_persp_ortho * projection;

    return projection;
}

rasterizer.cpp里面的 insideTriangle 函数:

static bool mySymbol(float x){
    return x > 0;
}

static bool insideTriangle(int x, int y, const Vector3f* _v)
{   
    // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
    // t1 = PA^PB,
    // t2 = PB^PC,
    // t3 = PC^PA,
    // t1=t2=t3同号,则在三角形内部
    auto A = _v[0];
    auto B = _v[1];
    auto C = _v[2];
    auto P = Vector2f(x,y);

    auto PA = Vector2f(A[0]-P[0],A[1]-P[1]);
    auto PB = Vector2f(B[0]-P[0],B[1]-P[1]);
    auto PC = Vector2f(C[0]-P[0],C[1]-P[1]);
    
    auto PA_PB = PA[0]*PB[1]-PA[1]*PB[0];
    auto PB_PC = PB[0]*PC[1]-PB[1]*PC[0];
    auto PC_PA = PC[0]*PA[1]-PC[1]*PA[0];

    return mySymbol(PA_PB) == mySymbol(PB_PC) == mySymbol(PC_PA);
    
}

rasterizer.cpp里面的 rasterize_triangle 函数:

//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    // cout << t.v <<endl;
    // cout << insideTriangle(0,1,t.v) <<endl;
    
    // TODO : Find out the bounding box of current triangle.
    // iterate through the pixel and find if the current pixel is inside the triangle
    
    // 找bounding box
    int left=INT32_MAX,right=INT32_MIN,top=INT32_MIN,buttom=INT32_MAX;

    for (int i = 0; i < 3; i++)
    {
        float x = t.v[i][0];
        float y = t.v[i][1];
        
        left = left > floor(x) ? floor(x):left;
        right = right < ceil(x) ? ceil(x):right;

        buttom = buttom > floor(y) ? floor(y):buttom;
        top = top < ceil(y) ? ceil(y):top;
        
    }
    
    for (int x = left; x <= right; x++)
    {
        for (int y = buttom; y <= top; y++)
        {
            bool isInside = insideTriangle(x+0.5,y+0.5,t.v);
            if(isInside){
                auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
                float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
                float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
                z_interpolated *= w_reciprocal;

                bool shouldBePainted = depth_buf[get_index(x,y) ] >  z_interpolated;
                if(shouldBePainted){
                    Vector3f point(x+0.5,y+0.5,z_interpolated);
                    depth_buf[get_index(x,y) ] =  z_interpolated;
                    set_pixel(point,t.getColor());
                }
                
            }
        }
        
    }
    

    // If so, use the following code to get the interpolated z value.
    //auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
    //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
    //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
    //z_interpolated *= w_reciprocal;

    // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
}

结果:

由于使用的远程软件有点问题,看起来上下颠倒了。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值