光栅渲染器(七)线框模型绘制和背部剔除实现

我们曾经完成过按多边形顶点输入完成无填充多边形顶点的绘制,所以现在可以按同样的思路绘制线框模型

设置状态

 enum _State {
     normal,
     wireframe
 };
 _State _state = normal;

我们利用这个状态改变模型是之前渲染出的彩色模型还是线框模型

设置状态改变条件

我们选择用space按键改变当前模型的状态

//************************键盘输入*******************
void myKeyBoard(unsigned char theKey, int MouseX, int MouseY)
{
    switch (theKey)
    {
    case 'w':
        CameraPos -= 0.1;
        myDisplay();
        break;
    case 's':
        CameraPos += 0.1;
        myDisplay();
        break;
    case 'a':
        Alpha += 0.1;
        myDisplay();
        break;
    case 'd':
        Alpha -= 0.1;
        myDisplay();
        break;
    case ' ':
        switch (_state)
        {
            case normal:
                _state = wireframe;
                myDisplay();
                break;
            case wireframe:
                _state = normal;
                myDisplay();
                break;
            default:
                break;
        }
        break;
    default:
        break;
    }
}

更改之前的画面函数

void draw_plane( int a, int b, int c, int d) {
    vertex_t p1 = mesh[a], p2 = mesh[b], p3 = mesh[c], p4 = mesh[d];
    vector<vertex_t> vs{ p1,p2,p3,p4 };

    switch (_state)
    {
        case normal:
            DrawTriangle(p1, p2, p3);
            DrawTriangle(p3, p4, p1);
            break;
        case wireframe:
            DrawTriangle_wire(vs);
            break;
        default:
            break;
    }

}

绘制线框模型

//绘制线框多边形
void DrawTriangle_wire(vector<vertex_t> vs)
{
    int size = vs.size();
    vector<vertex_t> ps;
    for (int i = 0; i < size; i++)
    {
        vertex_t vss=vs[i];
        point_t c, v;
        point_t p = vs[i].pos;
        transform_apply(&Transform, &c, &p);
        if (transform_check_cvv(&c) != 0) return;
        transform_homogenize(&Transform, &v, &c);
        vss.pos = v;
        vss.pos.w = c.w;
        vss.color.r = 1;
        vss.color.g = 1;
        vss.color.b = 1;
        vss.color.a = 1;
        ps.push_back(vss);
    }
    for (int i = 0; i < size; i++)
    {
        if(i+1<=size-1)
            DrawLine(ps[i], ps[i+1]);
        else
            DrawLine(ps[i], ps[0]);
    }

}

这里写图片描述
由于没有加入背部剔除,所以我们视野内有多余的线段

背部剔除

只要规定好画正方体时顶点数据的输入顺序,利用方向叉乘和点积判断
这里写图片描述
我们所见的面点的顺序应为顺时针,不能见到的为逆时针
所有修改的顶点顺序为如下

vertex_t mesh[8] = {
    { { 1, -1,  1, 1 },{ 1.0f, 0.2f, 0.2f } },
    { { -1, -1,  1, 1 },{ 0.2f, 1.0f, 0.2f } },
    { { -1,  1,  1, 1 },{ 0.2f, 0.2f, 1.0f }},
    { { 1,  1,  1, 1 },{ 1.0f, 0.2f, 1.0f } },
    { { 1, -1, -1, 1 },{ 1.0f, 1.0f, 0.2f } },
    { { -1, -1, -1, 1 },{ 0.2f, 1.0f, 1.0f } },
    { { -1,  1, -1, 1 },{ 1.0f, 0.3f, 0.3f }},
    { { 1,  1, -1, 1 },{ 0.2f, 1.0f, 0.3f } },
};
//************************画立方体*******************
void DrawBox()
{
    matrix_t m;
    //matrix_set_rotate(&m, -1,1, 1, Alpha);
    matrix_set_rotate(&m, -1, -1, 1, Alpha);
    Transform.world = m;
    transform_update(&Transform);

    draw_plane( 0, 1, 2, 3);
    draw_plane(4, 7, 6, 5);
    draw_plane( 0, 4, 5, 1);
    draw_plane( 1, 5, 6, 2);
    draw_plane(2, 6, 7, 3);
    draw_plane( 3, 7, 4, 0);
}

接下来是背部剔除的代码

// 背部剔除
bool DeleteBack(vertex_t ve1, vertex_t ve2, vertex_t ve3)
{
    vector_t direction = {0,0,-1,1}//视角所见的方向矢量
;
    vector_t normal;//法线
    vector_t v1, v2;
    vector_sub(&v1,&ve2.pos, &ve1.pos);
    vector_sub(&v2, &ve3.pos, &ve2.pos);
    v1.z = 0;
    v2.z = 0;
    vector_crossproduct(&normal, &v1, &v2);
    float dot = vector_dotproduct(&normal, &direction);
    if (dot<0) return true;
    return false;
} 

利用叉乘获得面的方向,通过点积正负判断法线的方向,从而得知面顶点的方向
修改的绘制线框模型的代码如下

//绘制线框多边形
void DrawTriangle_wire(vector<vertex_t> vs)
{

    int size = vs.size();
    vector<vertex_t> ps;
    for (int i = 0; i < size; i++)
    {
        vertex_t vss=vs[i];
        point_t c, v;
        point_t p = vs[i].pos;

        transform_apply(&Transform, &c, &p);
        if (transform_check_cvv(&c) != 0) return;
        transform_homogenize(&Transform, &v, &c);
        vss.pos = v;
        vss.pos.w = c.w;
        vss.color.r = 1;
        vss.color.g = 1;
        vss.color.b = 1;
        vss.color.a = 1;
        ps.push_back(vss);

    }
    if (DeleteBack(ps[0], ps[1], ps[2])) return;

    for (int i = 0; i < size; i++)
    {
        if (i + 1 <= size - 1)
        {

            DrawLine(ps[i], ps[i + 1]);
        }       
        else if(i == size - 1)
        {

            DrawLine(ps[i], ps[0]);
        }

    }


}

这里写图片描述
完成

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据来源:中经数据库 主要指标110多个(全部都是纯粹的 市辖区 指标),大致是: GDP GDP增速 第一产业增加值占GDP比重 第二产业增加值占GDP比重 第三产业增加值占GDP比重 人均GDP 社会消费品零售总额 固定资产投资(不含农户) 新设外商投资企业数_外商直接投资 实际利用外资金额(美元) 一般公共预算收入 一般公共预算支出 一般公共预算支出_教育 一般公共预算支出_科学技术 金融机构人民币各项存款余额_个人储蓄存款 金融机构人民币各项存款余额 金融机构人民币各项贷款余额 规模以上工业企业单位数 规模以上工业企业单位数_内资企业 规模以上工业企业单位数_港澳台商投资企业 规模以上工业企业单位数_外商投资企业 规模以上工业总产值 规模以上工业总产值_内资企业 规模以上工业总产值_港澳台商投资企业 规模以上工业总产值_外商投资企业 规模以上工业企业流动资产合计 规模以上工业企业固定资产合计 规模以上工业企业利润总额 规模以上工业企业应交增值税 规模以上工业企业主营业务税金及附加 户籍人口数 年均户籍人口数 户籍人口自然增长率 第一产业就业人员占全部城镇单位就业人员比重 第二产业就业人员占全部城镇单位就业人员比重 第三产业就业人员占全部城镇单位就业人员比重 城镇非私营单位就业人员数 城镇非私营单位就业人员数_第一产业 城镇非私营单位就业人员数_第二产业 城镇非私营单位就业人员数_第三产业 城镇非私营单位就业人员数_农、林、牧、渔业 城镇非私营单位就业人员数_采矿业 城镇非私营单位就业人员数_制造业 城镇非私营单位就业人员数_电力、热力、燃气及水生产和供应业 城镇非私营单位就业人员数_建筑业 城镇非私营单位就业人员数_批发和零售业 城镇非私营单位就业人员数_交通运输、仓储和邮政业 城镇非私营单位就业人员数_住宿和餐饮业 城镇非私营单位就业人员数_信息传输、软件和信息技术服务业 城镇非私营单位就业人员数_金融业 城镇非私营单位就业人员数_房地产业 城镇非私营单位就业人员数_租赁和商务服务业 城镇非私营单位就业人员数_科学研究和技术服务业 城镇非私营单位就业人员数_水利、环境和公共设施管理业 城镇非私营单位就业人员数_居民服务、修理和其他服务业 城镇非私营单位就业人员数_教育 城镇非私营单位就业人员数_卫生和社会工作 城镇非私营单位就业人员数_文化、体育和娱乐业 城镇非私营单位就业人员数_公共管理、社会保障和社会组织 城镇非私营单位在岗职工平均人数 城镇就业人员数_私营企业和个体 城镇非私营单位在岗职工工资总额 城镇非私营单位在岗职工平均工资 城镇登记失业人员数 建成区面积 建设用地面积 建设用地面积_居住用地 液化石油气供气总量 液化石油气供气总量_居民家庭 人工煤气、天然气供气总量 人工煤气、天然气供气总量_居民家庭 液化石油气用气人口 人工煤气、天然气用气人口 城市公共汽电车运营车辆数 城市出租汽车运营车辆数 城市公共汽电车客运总量 道路面积 排水管道长度 建成区绿化覆盖面积 建成区绿化覆盖率 绿地面积 公园绿地面积 维护建设资金支出 土地面积 生活用水供水量 供水总量 全社会用电量 城乡居民生活用电量 工业生产用电量 房地产开发投资 房地产开发投资_住宅 限额以上批发和零售业法人单位数 限额以上批发和零售业商品销售总额 普通中学学校数 中等职业教育学校数 普通小学学校数 普通高等学校专任教师数 普通中学专任教师数 中等职业教育专任教师数 普通小学专任教师数 普通高等学校在校生数 普通中学在校生数 中等职业教育在校生数 普通小学在校生数 电视节目综合人口覆盖率 公共图书馆总藏量_图书 医疗卫生机构数_医院和卫生院 卫生人员数_执业(助理)医师 医疗卫生机构床位数_医院和卫生院 城镇职工基本养老保险参保人数 职工基本医疗保险参保人数 失业保险参保人数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值