您当前的位置: 首页 >  flashinggg c++

GAMES101作业2-代码框架逐行理解(c++基础巩固)

flashinggg 发布时间:2022-05-06 18:16:24 ,浏览量:2

目录

补充作业代码

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             
关注
打赏
1688896170
查看更多评论
0.0896s