目录
补充作业代码
main.cpp
get_projection_matrix函数
rasterize.cpp
1.insideTriangle函数——判断点(x,y)是否在三角形内
2.rasterizer_triangle
结果展示
正三角-n和f取负值
倒三角-n和f取正值
代码框架详细理解
Triangle.hpp
rasterizer.hpp
rasterizer.cpp
main.cpp
Triangle.cpp
代码涉及到的c++知识回顾
宏定义
无参宏定义
带参宏定义
#ifndef条件编译
#pragma once
using namespace
using
namespace 命名空间
class 类
struct
enum class枚举类型
等价于enum struct
底层数据类型(underlying tyue)
域
头文件
inline
先来说说什么是栈空间
inline具体如何实现目的
类外定义前加上inline关键字
operator
为什么要用这个
在类里实现运算符-成员函数
类外的非类的成员函数-全局函数
逻辑运算符&&和||与&和|的区别
empalce_front/emplace/emplace_back
提供的代码框架里包含了三个头文件和三个源文件
需要补充的部分有:
main.cpp get_projection_matrix函数注意,与作业1情况类似,如果n和f直接取zNear和zFar则两个三角形会是倒三角。
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 f, n, l, r, b, t, fov;
fov = eye_fov / 180 * MY_PI;
n = -zNear; //znear是正值
f = -zFar;
t = tan(fov / 2) * zNear;
b = -t;
r = t * aspect_ratio;
l = -r;
//透视->正交 perspective->orthographic
Eigen::Matrix4f pertoorth;
pertoorth 0) && (p.dot(f2)*f2.dot(v[1])>0))
return true;
return false;
}
2.rasterizer_triangle
这个部分一个取bounding box问题,一个是重心坐标的问题。
void rst::rasterizer::rasterize_triangle(const Triangle& t) { //这里的Triangle是Triangle.hpp里定义的一个class类
auto v = t.toVector4(); //toVector4()是Triangle里定义的一个array
//找到三角形的bounding box
//在Triangle类中定义了三角形顶点为v[0]v[1]v[2] 都是vector4f
int min_x = std::min(std::min(v[0].x(), v[1].x()), v[2].x());
int min_y = std::min(std::min(v[0].y(), v[1].y()), v[2].y());
int max_x = std::max(std::max(v[0].x(), v[1].x()), v[2].x());
int max_y = std::max(std::max(v[0].y(), v[1].y()), v[2].y());
//遍历pixels确定像素是否在三角形内
/*bool MSAA = true;
这里用MSAA 4X 也就是把像素分成4X4,默认像素是1X1的大小,因此有了0.25、0.75
std::vectorpixel
{
{0.25,0.25},{0.25,0.75},{0.75,0.25},{0.75,0.75},
};
*/
//循环判断
for (int x = min_x; x VIEWPORT -> DRAWLINE/DRAWTRI -> FRAGSHADER
private:
Eigen::Matrix4f model;
Eigen::Matrix4f view;
Eigen::Matrix4f projection;
std::map pos_buf;
std::map ind_buf;
std::map col_buf;
std::vector frame_buf;
std::vector depth_buf;
int get_index(int x, int y);
int width, height;
int next_id = 0;
int get_next_id() { return next_id++; }
};
}
rasterizer.cpp
#include //是C++标准算法库,应用在容器上
#include //是c++标准库提供的一个被封装的动态数组
#include "rasterizer.hpp"
#include
#include
/*这里的rst是rasterizer.hpp头文件中定义的一个rst namespace
pos_buf_id 是rst中定义的一个 struct
rasterizer 是rst中定义的一个 class
*/
rst::pos_buf_id rst::rasterizer::load_positions(const std::vector &positions)
{
auto id = get_next_id();//rasterizer类中定义的一个int类型的函数,作用:return下一个id
pos_buf.emplace(id, positions);//在id指向的元素前创建一个值为positions的元素
return {id};
}
rst::ind_buf_id rst::rasterizer::load_indices(const std::vector &indices)
{
auto id = get_next_id();
ind_buf.emplace(id, indices);
return {id};
}
rst::col_buf_id rst::rasterizer::load_colors(const std::vector &cols)
{
auto id = get_next_id();
col_buf.emplace(id, cols);
return {id};
}
auto to_vec4(const Eigen::Vector3f& v3, float w = 1.0f)
{
return Vector4f(v3.x(), v3.y(), v3.z(), w);
}
static bool insideTriangle(int x, int y, const Vector3f* _v)//第三个数是_v指向Vector3f类型的指针,默认传入了三角形的三个顶点
{
//.head(2)用来取出每个顶点的前两个值(x,y)
Eigen::Vector2f AB, BC, CA, AP, BP, CP, p;
float a, b, c;
p 0 && b > 0 && c > 0) return true;
else if (a < 0 && b < 0 && c < 0) return true;
return false;
}
static std::tuple computeBarycentric2D(float x, float y, const Vector3f* v)
{
float c1 = (x*(v[1].y() - v[2].y()) + (v[2].x() - v[1].x())*y + v[1].x()*v[2].y() - v[2].x()*v[1].y()) / (v[0].x()*(v[1].y() - v[2].y()) + (v[2].x() - v[1].x())*v[0].y() + v[1].x()*v[2].y() - v[2].x()*v[1].y());
float c2 = (x*(v[2].y() - v[0].y()) + (v[0].x() - v[2].x())*y + v[2].x()*v[0].y() - v[0].x()*v[2].y()) / (v[1].x()*(v[2].y() - v[0].y()) + (v[0].x() - v[2].x())*v[1].y() + v[2].x()*v[0].y() - v[0].x()*v[2].y());
float c3 = (x*(v[0].y() - v[1].y()) + (v[1].x() - v[0].x())*y + v[0].x()*v[1].y() - v[1].x()*v[0].y()) / (v[2].x()*(v[0].y() - v[1].y()) + (v[1].x() - v[0].x())*v[2].y() + v[0].x()*v[1].y() - v[1].x()*v[0].y());
return {c1,c2,c3};
}
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;
for (auto& i : ind)//用i遍历ind
{
Triangle t;
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)
};
//Homogeneous division
for (auto& vec : v) {
vec /= vec.w();
}
//Viewport transformation
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());
t.setVertex(i, v[i].head());
t.setVertex(i, v[i].head());
}
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);
}
}
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t) { //这里的Triangle是Triangle.hpp里定义的一个class类
auto v = t.toVector4(); //toVector4()是Triangle里定义的一个array
//找到三角形的bounding box
//在Triangle类中定义了三角形顶点为v[0]v[1]v[2] 都是vector4f
int min_x = std::min(std::min(v[0].x(), v[1].x()), v[2].x());
int min_y = std::min(std::min(v[0].y(), v[1].y()), v[2].y());
int max_x = std::max(std::max(v[0].x(), v[1].x()), v[2].x());
int max_y = std::max(std::max(v[0].y(), v[1].y()), v[2].y());
//遍历pixels确定像素是否在三角形内
//循环判断
for (int x = min_x; x
关注
打赏