games101 作业2

应该是最菜的一批了,每个作业都做的磕磕绊绊,已经有点感觉了,基本上都是自己写的。最后才来参考下别人的答案,希望能有所进步。

配置

依然是这次作业用到的东西。怎么在新建项目时,不用重复配置:http://t.csdn.cn/XRtCd

写作业时的问题

浏览完作业,有几个问题,挨着排出来,挨着把这些问题解决,发现自己基本上也把这道题给做出来了。果然梳理一下还是很有用。

1.因为画面内每个像素都需要对比是否在三角形内,画面的尺寸怎么找
解决: 找到三角形的边界,将给出的三角形三个点求x,y的最小最大值(直接用t.v[][]来比较)。作业这里其实也提示了…但是第一次完全没有读懂他的意思,还是要自己从头捋一次。

// TODO : Find out the bounding box of current triangle.
//需要做的:找到当前三角形的边界

2.不改变原函数定义的话, static bool insideTriangle()应该怎么使用。是输入画面内像素的x,y还有三角形其中一条边长?
解决: Vector3f* 的意思就是数组,直接把三角形的三个点全部传过去了。所以直接传入t.v。太菜了,居然没有一眼明白。
3.depth buffer怎么使用。
解决: 确实是自己c++基础太差了,自己看了好久都没看懂到底怎么使用depth_buf。最后还是看了下其他人的答案才明白过来,但是整体框架自己也都写好了,就差了这一个函数。

作业的思路

1.找到三角形x轴和y轴的最大最小值。
2.两个嵌套for循环,依次遍历所有的点,对其进行判断是否在三角形内。分别用点和3条边进行叉乘。
点乘和叉乘:https://www.csdn.net/tags/NtjaUg4sNDYwMjQtYmxvZwO0O0OO0O0O.html
3.如果在三角形内,直接用老师给出的几行代码,得到z的坐标。如果z的坐标小于缓冲区的值,则更新缓冲区的值,并设置颜色set_pixel()

代码

static bool insideTriangle(int x, int y, const Vector3f* _v)
{
    Vector3f pixel(x, y, 0);
    Vector3f dot[4];//三角形三个点
    float equ[3];
    for (int i = 0; i < 3; i++) {
        dot[i] = _v[i];
        dot[i][2] = 0;//不知道把z轴加进去计算有没有影响,干脆把z给变成0
    }
    dot[3] = _v[0];
    dot[3][2] = 0;
    for (int i = 0; i < 3; i++) {//进行三次叉乘,并且把y的坐标保存。
        Vector3f ve=(dot[i + 1] - dot[i]).cross(pixel - dot[i]);//叉乘运算
        equ[i] = ve[2];
    }
    if ((equ[0] > 0 && equ[1] > 0 && equ[2] > 0) || (equ[0] < 0 && equ[1] < 0 && equ[2] < 0)) {//如果三个y的符号相同,则返回true
        return true;
    }
    return false;
    // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
    //需要做的:执行此函数以检查点(x,y)是否位于由_v[0]、_v[1]、_v[2]表示的三角形内
}
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    float xmin, xmax, ymin, ymax;
    float alpha, beta, gamma;
//    std::tuple<float, float, float> angle(alpha, beta, gamma);
    xmin = t.v[0][0] < (t.v[1][0] < t.v[2][0] ? t.v[1][0] : t.v[2][0]) ? t.v[0][0] : (t.v[1][0] < t.v[2][0] ? t.v[1][0] : t.v[2][0]);//最左边边界,最小值
    xmax = t.v[0][0] > (t.v[1][0] > t.v[2][0] ? t.v[1][0] : t.v[2][0]) ? t.v[0][0] : (t.v[1][0] > t.v[2][0] ? t.v[1][0] : t.v[2][0]);//最右边边界,最大值
    ymin= t.v[0][1] < (t.v[1][1] < t.v[2][1] ? t.v[1][1] : t.v[2][1]) ? t.v[0][1] : (t.v[1][1] < t.v[2][1] ? t.v[1][1] : t.v[2][1]);//最矮,最小值
    ymax = t.v[0][1] > (t.v[1][1] > t.v[2][1] ? t.v[1][1] : t.v[2][1]) ? t.v[0][1] : (t.v[1][1] > t.v[2][1] ? t.v[1][1] : t.v[2][1]);//最高,最大值
    int x_min = xmin, x_max = xmax, y_min = ymin, y_max = ymax;
    //遍历所有坐标
    for (int x = x_min; x <= x_max; x++) {
        for (int y = y_min; y <= y_max; y++) {
        //这里加不加0.5目前看来都好像没有影响,只是看好多人都是加上的,我也加上了
            if (insideTriangle(x+0.5, y+0.5, t.v)) {//如果在三角形内
//                auto angle = computeBarycentric2D(x+0.5, y+0.5, t.v);
                auto [alpha, beta, gamma] = computeBarycentric2D(x+0.5, y+0.5, 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;
                Vector3f nowpixel(x, y, z_interpolated);
                if (z_interpolated < depth_buf[get_index(x, y)]) {//如果z的坐标小于缓冲区,则更新并且获取颜色
                    depth_buf[get_index(x, y)] = z_interpolated;
                    set_pixel(nowpixel, t.getColor());
                }
            }
        }
    }

    // TODO : Find out the bounding box of current triangle.
    //需要做的:找到当前三角形的边界
    // iterate through the pixel and find if the current pixel is inside the triangle
    //遍历像素,并确定当前像素是否在三角形内

    // If so, use the following code to get the interpolated z value.
    //如果在三角形内,根据下面的代码得到z轴的值
    //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.
    //如果需要绘制三角形,则将当前像素(使用set_pixel函数)设置为三角形的颜色(使用getColor函数)。
}

运行结果

在这里插入图片描述

存在问题

1.代码看着有点冗余,但是不太会简化。有机会再简化。
2.auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);这句代码用不了,只能自己试着改改了。
解决:还是只能用老师的代码,之前报错可能是因为x,y的值代入了整数。否则按照自己写的

std::tuple<float, float, float> angle(alpha, beta, gamma);
auto angle = computeBarycentric2D(x, y, t.v);

会在作业3中出现问题,还是不知道为什么会有问题。。。

3.main函数中每次循环都很慢,不知道是当前作业限制还是自己的代码问题。
4.提高版完全看不懂。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值