图形管线
Vertex Processing
对顶点进行加工,使其变换到屏幕空间坐标。
Triangle Processing
将加工后的顶点组装成三角形,用于下一步的光栅化。
void rst::rasterizer::draw(pos_buf_id pos_buffer, ind_buf_id ind_buffer, col_buf_id col_buffer, Primitive type)
{
//从缓冲区中读取顶点坐标,索引,颜色信息
auto& buf = pos_buf[pos_buffer.pos_id];
auto& ind = ind_buf[ind_buffer.ind_id];
auto& col = col_buf[col_buffer.col_id];
float f1 = (50 - 0.1) / 2.0;
float f2 = (50 + 0.1) / 2.0;
Eigen::Matrix4f mvp = projection * view * model; //计算得到mvp矩阵
for (auto& i : ind) //遍历索引数组,对顶点进行加工
{
Triangle t;
//这里对顶点进行mvp变换,并将结果存入v
Eigen::Vector4f v[] = {
mvp * to_vec4(buf[i[0]], 1.0f),
mvp * to_vec4(buf[i[1]], 1.0f),
mvp * to_vec4(buf[i[2]], 1.0f)
};
//因为得到的结果w值是原本的z值,所以除以w才是变换后在[-1,1]^3的空间中的坐标
for (auto& vec : v) {
vec /= vec.w();
}
//将归一化设备坐标的点转换到屏幕空间坐标
for (auto & vert : v)
{
vert.x() = 0.5*width*(vert.x()+1.0);
vert.y() = 0.5*height*(vert.y()+1.0);
vert.z() = vert.z() * f1 + f2;
}
//将屏幕空间的点组装成三角形
for (int i = 0; i < 3; ++i)
{
t.setVertex(i, v[i].head<3>());
t.setVertex(i, v[i].head<3>());
t.setVertex(i, v[i].head<3>());
}
//从颜色缓冲区中读取颜色
auto col_x = col[i[0]];
auto col_y = col[i[1]];
auto col_z = col[i[2]];
//为三角形的每个顶点附上颜色数据
t.setColor(0, col_x[0], col_x[1], col_x[2]);
t.setColor(1, col_y[0], col_y[1], col_y[2]);
t.setColor(2, col_z[0], col_z[1], col_z[2]);
//光栅化三角形
rasterize_triangle(t);
}
}
Rasterization
将三角形光栅化得到片元,这些片元最终会被渲染成屏幕上的像素。
FargmentProcessing
紧随光栅化(Rasterization)之后。在Fragment Processing阶段,主要对光栅化生成的每个片元(Fragment)进行进一步的处理,以确定其最终的颜色、深度和其他属性。而这里的各种属性可以根据线性插值和透视矫正插值得出。作业里要实现的是透视矫正插值。透视矫正插值需要用到重心坐标。重心坐标的计算作业框架中已经直接给出函数,直接调用即可。
Framebuffer Opeations
main.cpp这里通过框架的cv库,将frame_buffer的内容写入图片,从而得到最终的图片。
代码:
games101 实验hw2(作业2)_games101作业2-CSDN博客
https://zhuanlan.zhihu.com/p/425153734