hw2

在屏幕上画出一个实心三角形.
相较于hw1,多了一些内容,需要好好看下框架.

判断$(x,y)$对应的pixel否在三角形内部.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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]
Vector2f vertex2p[3], vertex2vertex[3];
int i;
//储存顶点到测试点的向量
for (i = 0;i < 3;i++) {
vertex2p[i] << x - _v[i].x(), y - _v[i].y();
}
//储存顶点到顶点之间的向量
for (i = 0;i < 3;i++) {
vertex2vertex[i] << _v[(i + 1) % 3].x() - _v[i].x(), _v[(i + 1) % 3].y() - _v[i].y();
}
//计算叉乘法.
int result[3];
for (i = 0;i < 3;i++) {
result[i] = vertex2vertex[i].x()*vertex2p[i].y()
-vertex2vertex[i].y()*vertex2p[i].x();
}
if(result[0]>0 && result[1]>0 && result[2]>0){
return true;
}
else if(result[0]<0 && result[1]<0 && result[2]<0){
return true;
}
else{
return false;
}

}

先限定下founding box范围,提高效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();

// TODO : Find out the bounding box of current triangle.
// iterate through the pixel and find if the current pixel is inside the triangle
float xmin,ymin,xmax,ymax;
xmin=std::min(std::min(v[0].x(),v[1].x()),v[2].x());
ymin=std::min(std::min(v[0].y(),v[1].y()),v[2].y());
xmax=std::max(std::max(v[0].x(),v[1].x()),v[2].x());
ymax=std::max(std::max(v[0].y(),v[1].y()),v[2].y());
xmin=std::floor(xmin);
xmax=std::ceil(xmax);
ymin=std::floor(ymin);
ymax=std::ceil(ymax);

for(int x=xmin;x<=xmax;x++){
for(int y=ymin;y<=ymax;y++){
if(insideTriangle(x+0.5,y+0.5,t.v)){
// 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.
if (z_interpolated<depth_buf[get_index(x,y)]){
set_pixel(Vector3f(x,y,z_interpolated),t.getColor());
depth_buf[get_index(x,y)]=z_interpolated;
}
}
}
}

阅读更多

hw1

总的来说,hw1是比较简单的.
本次作业的任务是填写一个旋转矩阵和一个透视投影矩阵,只要记得上课时候给的公式,写进去就行.

  • 旋转矩阵
    注意,cos,sin等,需要的参数为弧度制(rad),而不是角度制
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Eigen::Matrix4f get_model_matrix(float rotation_angle) {
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();

    // TODO: Implement this function
    // Create the model matrix for rotating the triangle around the Z axis.
    // Then return it.
    rotation_angle = rotation_angle / 180 * MY_PI;
    Eigen::Matrix4f rotate;
    rotate << cos(rotation_angle), -sin(rotation_angle), 0, 0,
    sin(rotation_angle), cos(rotation_angle), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
    model = rotate * model;
    return model;
    }

先进行挤压,再进行正交投影得到结果

  • persp2ortho

    • 透视投影到正交投影的变化矩阵
  • ortho

    • 正交矩阵
      projection = ortho * persp2ortho * projection;
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      Eigen::Matrix4f get_projection_matrix(float eye_fov,
      float aspect_ratio,
      float zNear,
      float zFar) {
      // Students will implement this function

      Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

      // TODO: Implement this function
      // Create the projection matrix for the given parameters.
      // Then return it.
      Eigen::Matrix4f persp2ortho = Eigen::Matrix4f::Identity();
      Eigen::Matrix4f ortho = Eigen::Matrix4f::Identity();

      float top = abs(zNear) * tan(eye_fov / 2 / 180 * MY_PI);
      float bottom = -top;
      float right = top * aspect_ratio;
      float left = -right;

      persp2ortho << zNear, 0, 0, 0, 0, zNear, 0, 0, 0, 0, zNear + zFar,
      -zNear * zFar, 0, 0, 1, 0;

      ortho << 2 / (right - left), 0, 0, -(right + left) / (right - left), 0,
      2 / (top - bottom), 0, -(top + bottom) / (top - bottom), 0, 0,
      2 / (zNear - zFar), -(zNear + zFar) / (zNear - zFar), 0, 0, 0, 1;

      projection = ortho * persp2ortho * projection;
      return projection;
      }

最后得到的结果与官方答案不同,图形倒转了.这是zNear值导致的.
根据课上的内容,看向的是Z轴负半轴,Z<0; 而代码中,看向Z正半轴,Z>0;

小问题懒得修改了.

顺便学习了一下cmake的相关知识
[[07archive/tech/cmake|cmake]]

阅读更多

配置环境

环境配置

难绷,论坛上给的虚拟机是ubuntu18 并且是virtual box的版本.
想用vmware虚拟机跑.将vdi格式转化为vmdk,并创建对应的虚拟机.
问题在于VMware tools安装失败.每次安装完成之后,再reboot,就会变成没有VMware tools…搞不懂.
还是在windows上配置环境算了…

看了下windows配置eigen和opencv有点麻烦,选择换成虚拟机ubuntu20.04LTS自己配置


更新
breaking news!
官方给的虚拟机,转换为vmware之后,vmwaretools安装成功了…
直接用就行了.配置环境结束.

ubuntu具体设置

参考

遇上vscode编译时候报错

1
/usr/bin/gcc -fdiagnostics-color=always -g /home/l4rk/games101/pa0.c -o /home/l4rk/games101/pa0 /usr/bin/ld: /tmp/ccjPHxdQ.o: in function `main': /home/l4rk/games101/pa0.c:6: undefined reference to `sin' collect2: error: ld returned 1 exit status

阅读更多