1.Triangle类

1.1 Triangle.hpp:类的声明

定义了一个名为 Triangle 的类

  • 三角形顶点的齐次坐标:(x,y,z,w)

image-20231203094213284

注:w=0时表示该点在无穷远处

  • ifndef:防止头文件的重复包含,确保在编译时,同一个头文件不会被多次包含,从而避免因重复包含导致的重定义报错。
1
2
3
4
5
6
7
8
#ifndef __TEST_H
#define __TEST_H
"
...... #内容
......
"
头文件结尾写上一行:
#endif

注:__TEST_H为标识符,通常是大写形式

  • void setNormals(const std::array& normals):利用normals设置三角形顶点的法向量normal[3]
    • std::array:标准库中的容器
    • Vector3f(元素类型)、3(数组大小)
    • const:保证normals不会被修改,&:传递引用类型,避免对象的拷贝,提高执行效率
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
32
33
34
35
36
37
38
#ifndef RASTERIZER_TRIANGLE_H
#define RASTERIZER_TRIANGLE_H

#include<eigen3/Eigen/Eigen>
#include"Texture.hpp"//项目内的头文件用""
using namespace Eigen;
class Triangle{
Vector4f v[3];//三角形三个顶点的其次坐标(x,y,z,w)
Vector3f color[3];//顶点的颜色
Vector2f tex_coords[3];//顶点的纹理坐标
Vector3f normal[3];//顶点的法向量

Texture* tex = nullptr;//指向其纹理信息的指针

Triangle();//默认构造函数

//获取三个顶点的坐标
Eigen::Vector4f a() const { return v[0]; }
Eigen::Vector4f b() const { return v[1]; }
Eigen::Vector4f c() const { return v[2]; }

//设置第i个顶点的坐标
void setVertex(int ind,Vector4f ver);//将第i个顶点的坐标设置为ver
//设置法向量
void setNormal(int ind, Vector3f ver);
//设置颜色
void setColor(int ind, float r, float g, float b);
//设置所有顶点的法向量
void setNormals(const std::array<Vector3f, 3>& normals);
//设置所有顶点的颜色
void setColors(const std::array<Vector3f, 3>& colors);
//设置第i个顶点的纹理
void setTexCoord(int ind, Vector2f uv);

std::array<Vector4f, 3> toVector4() const;//定义toVector4()函数,将齐次坐标(x,y,z,w)转换为(x/w,y/w,z/w,1)的形式

};
#endif // !RASTERIZER_TRIANGLE_H

1.2 Triangle.cpp:类的实现

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include"Triangle.hpp"
#include<algorithm>
#include<array>

//构造函数的实现
Triangle::Triangle() {
v[0] << 0, 0, 0, 1;
v[1] << 0, 0, 0, 1;
v[2] << 0, 0, 0, 1;
color[0] << 0.0, 0.0, 0.0;
color[1] << 0.0, 0.0, 0.0;
color[2] << 0.0, 0.0, 0.0;
tex_coords[0] << 0.0, 0.0;
tex_coords[1] << 0.0, 0.0;
tex_coords[2] << 0.0, 0.0;
}

//设置指定索引的纹理
void Triangle::setTexCoord(int ind, Vector2f uv) {
tex_coords[ind] = uv;
}
//设置顶点
void Triangle::setVertex(int ind, Vector4f ver) {
v[ind] = ver;
}
//设置法线
void Triangle::setNormal(int ind, Vector3f n) {
normal[ind] = n;
}
//设置颜色
void Triangle::setColor(int ind, float r, float g, float b) {
if ((r < 0.0) || (r > 255.) ||
(g < 0.0) || (g > 255.) ||
(b < 0.0) || (b > 255.)) {
fprintf(stderr, "ERROR! Invalid color values");
fflush(stderr);
exit(-1);
}

color[ind] = Vector3f((float)r / 255., (float)g / 255., (float)b / 255.);
return;
}
//将顶点坐标转换为标准的四维齐次坐标
std::array<Vector4f, 3> Triangle::toVector4() const
{
std::array<Vector4f, 3> res;
std::transform(std::begin(v), std::end(v), res.begin(), [](auto& vec) { return Vector4f(vec.x(), vec.y(), vec.z(), 1.f); });
return res;
}
void Triangle::setNormals(const std::array<Vector3f, 3>& normals)
{
// 设置法向量
normal[0] = normals[0];
normal[1] = normals[1];
normal[2] = normals[2];
}

void Triangle::setColors(const std::array<Vector3f, 3>& colors)
{
// 设置颜色
auto first_color = colors[0];
setColor(0, colors[0][0], colors[0][1], colors[0][2]);
setColor(1, colors[1][0], colors[1][1], colors[1][2]);
setColor(2, colors[2][0], colors[2][1], colors[2][2]);
}