2014年2月7日星期五(7-3,消除了背面的3D线框立方体)

2023-11-18

好久没进行了,看看吧,与DEMO7-2的区别,只看不同的地方,相机类型不同,归一化平面改为2*2/ar,视口为640*480,执行了背面消除,(就是判断面元向量与面元到视点向量的点乘,>0,则可见,否则,消除)

这一步是在物体剔除后和世界坐标到相机坐标变换之前进行背面消除,

先建立4D向量,两点确定一个向量,SO  EASY如下。

void ddraw_math::VECTOR4D_Build( VECTOR4D_PTR init, VECTOR4D_PTR term, VECTOR4D_PTR result )

{

    result->x                      = term->x -init->x;

    result->y                      = term->y - init->y;

    result->z                      = term->z - init->z;

    result->w                      = 1;

}

 

再做个准备工作,4元数之间的叉乘

void ddraw_math::VECTOR4D_CROSS( VECTOR4D_PTR va, VECTOR4D_PTR vb, VECTOR4D_PTR vn )

{

    vn->x                                  = (( va->y * vb->z) - ( va->z * vb->y));

    vn->y                                  = - ( ( va->x * vb->z) - ( va->z * vb->x ));

    vn->z                                  = ( ( va->x * vb->y ) - ( va->y * vb->x));

    vn->w                                  = 1;

 

 

}

 

四元数之间的点乘

float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )

{

    return ( ( va->x * vb->x ) + ( va->y * vb->y ) + ( va->z + vb->z ) );

}

 

背面消除函数如下

 

void ddraw_liushuixian::Remove_Backfaces_OBJECT4DV1(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam, ddraw_math math)

{

    //检查物体是否已经被剔除

    //在执行物体提出之后和世界坐标到相机坐标变换之前进行背面消除

    if ( obj->state & OBJECT4DV1_STATE_CULLED )

    {

         return;

    }

    //处理物体的每个多边形

    for( int poly = 0; poly < obj->num_polys; poly ++ )

    {

         //获取多边形

         POLY4DV1_PTR              curr_poly         = & obj->plist[poly];

         //该多边形是否有效?

         //判断该多边形是否没被裁剪掉,没有被剔除,处于活动状态,可见且不是双面的

         if ( ! ( curr_poly->state & POLY4DV1_STATE_ACTIVE ) ||

             ( curr_poly->state & POLY4DV1_STATE_CLIPPED) ||

             ( curr_poly->state & POLY4DV1_ATTR_2SIDED) ||

             ( curr_poly->state & POLY4DV1_STATE_BACKFACE))

            

         {

             continue;

         }

 

         //获取顶点列表中的顶点索引

         int                            vindex_0     = curr_poly->vert[0];

         int                            vindex_1     = curr_poly->vert[1];

         int                            vindex_2     = curr_poly->vert[2];

 

         //计算多边形的面法线,

         //顶点是按照顺时针方向排列的,u=p0->p1,v=p0->p2,n=UXV;

         VECTOR4D                  u, v, n;

         //计算u和v

         math.VECTOR4D_Build( & obj->vlist_trans[vindex_0], & obj->vlist_trans[vindex_1], & u );

         math.VECTOR4D_Build( & obj->vlist_trans[vindex_0], & obj->vlist_trans[vindex_2], & v );

         //计算叉积

         math.VECTOR4D_CROSS( & u, &v, &n );

 

         //创建指向视点的向量

         VECTOR4D                  view;

         math.VECTOR4D_Build( & obj->vlist_trans[vindex_0], & cam->pos, & view );

 

         //计算点积

         float                          dp                = math.VECTOR4D_DOT( &n, &view );

         if ( dp<= 0)

         {

             SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );

         }

        

        

    }

}

 

现在看看在主函数中怎么改动,首先,在GAME_INIT()中,加载cube2.plg,

             WINDOW_HEIGHT);

//加载模型

liushuixian.Load_OBJECT4DV1_PLG( & obj, "cube2.plg", & vscale, & vpos, & vrot );

在Game_Main()中加上背面消除

。。。。。。

    liushuixian.Build_CAM4DV1_Matrix_Euler( *math, & cam, CAM_ROT_SEQ_ZYX );

    //Build_CAM4DV1_Matrix_Euler( & cam, CAM_ROT_SEQ_ZYX );

    liushuixian.Remove_Backfaces_OBJECT4DV1( & obj, &cam, * math );

    liushuixian.World_To_Camera_OBJECT4DV1(  *math, &obj, & cam );

。。。。。。

如下图所示

 

说明背面消除没有起作用,将

    if ( dp>0 )

         {

             SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );

         }

发现也是整个显示,说明没起作用。

输出到文件的方法

void Remove_Backfaces_OBJECT4DV1(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)

{

         FILE * fp = fopen( "test.txt", "w");

         fprintf( fp, "removebackface函数起效果了\n" );

         ;

    //检查物体是否已经被剔除

    //在执行物体提出之后和世界坐标到相机坐标变换之前进行背面消除

    if ( obj->state & OBJECT4DV1_STATE_CULLED )

    {

         return;

    }

    fprintf(fp, "有不是OBJECT4DV1_STATE_CULLED的点\n");

 

    //处理物体的每个多边形

    for( int poly = 0; poly < obj->num_polys; poly ++ )

    {

         //获取多边形

         POLY4DV1_PTR              curr_poly         = & obj->plist[poly];

         //该多边形是否有效?

         //判断该多边形是否没被裁剪掉,没有被剔除,处于活动状态,可见且不是双面的

         if ( ! ( curr_poly->state & POLY4DV1_STATE_ACTIVE ) ||

             ( curr_poly->state & POLY4DV1_STATE_CLIPPED) ||

             ( curr_poly->state & POLY4DV1_ATTR_2SIDED) ||

             ( curr_poly->state & POLY4DV1_STATE_BACKFACE))

 

         {

             fprintf(fp, "第%d个顶点没经过计算\n",poly);

 

             continue;

         }

         fprintf(fp, "有进行计算的点\n");

 

 

         //获取顶点列表中的顶点索引

         int                            vindex_0     = curr_poly->vert[0];

         int                            vindex_1     = curr_poly->vert[1];

         int                            vindex_2     = curr_poly->vert[2];

 

         //计算多边形的面法线,

         //顶点是按照顺时针方向排列的,u=p0->p1,v=p0->p2,n=UXV;

         VECTOR4D                  u, v, n;

         //计算u和v

         VECTOR4D_Build( & obj->vlist_trans[vindex_0], & obj->vlist_trans[vindex_1], & u );

         VECTOR4D_Build( & obj->vlist_trans[vindex_0], & obj->vlist_trans[vindex_2], & v );

         //计算叉积

         VECTOR4D_Cross( & u, &v, &n );

 

         //创建指向视点的向量

         VECTOR4D                  view;

         VECTOR4D_Build( & obj->vlist_trans[vindex_0], & cam->pos, & view );

 

   

         //计算点积

         float                          dp                =VECTOR4D_Dot( &n, &view );

         if ( dp<0 )

         {

             SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );

 

         }

         ;   fprintf(fp, "第%d个面法线与视线点积为%f", poly, dp );

 

   

 

    }

         fclose( fp);

}

发现test.txt的显示内容是

removebackface函数起效果了

有不是OBJECT4DV1_STATE_CULLED的点

第0个顶点没经过计算,共12个顶点

第1个顶点没经过计算,共12个顶点

第2个顶点没经过计算,共12个顶点

第3个顶点没经过计算,共12个顶点

第4个顶点没经过计算,共12个顶点

第5个顶点没经过计算,共12个顶点

第6个顶点没经过计算,共12个顶点

第7个顶点没经过计算,共12个顶点

第8个顶点没经过计算,共12个顶点

第9个顶点没经过计算,共12个顶点

第10个顶点没经过计算,共12个顶点

第11个顶点没经过计算,共12个顶点

说明全continue了,再往前看状态。

 

结果发现太马虎了,应该是

curr_poly->attr & POLY4DV1_ATTR_2SIDED

而不是

curr_poly->state & POLY4DV1_ATTR_2SIDED

 

另外点乘最后一项应该是×而不是+,即原来是

float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )

{

    return ( ( va->x * vb->x ) + ( va->y * vb->y ) + ( va->z + vb->z ) );

}

应改为

float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )

{

    return ( ( va->x * vb->x ) + ( va->y * vb->y ) + ( va->z * vb->z ) );

}

修正后结果如下所示,OK了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2014年2月7日星期五(7-3,消除了背面的3D线框立方体) 的相关文章

  • Entity Framework Core系列教程-2安装EF Core

    安装Entity Framework Core 这里我们将使用EF Core 3 1 因为它是长期支持版本 开发工具使用Visual Studio 2019 编写 NET Core应用程序 EF Core 3 1 支持 NET Standa
  • 华为机试题-字符串最后一个单词的长度

    计算字符串最后一个单词的长度 单词以空格隔开 字符串长度小于5000 输入描述 输入一行 代表要计算的字符串 非空 长度小于5000 输出描述 输出一个整数 表示输入字符串最后一个单词的长度 示例1 输入 hello nowcoder 复制
  • web前端笔记:html5的标签

    在HTML4 01中 lt b gt lt i gt 是视觉要素 presentationl elements 分别表示无意义的加粗 无意义的斜体 表现样式为 font weight bolder 仅仅表示 这里应该用粗体显示 或者 这里应
  • 人脸重建环境配置时的坑

    ERROR Could not install packages due to an EnvironmentError Errno 28 No space left on device 由于是docker环境 所以把 tmp目录下的文件清理

随机推荐

  • 《Apache MINA 2.0 用户指南》第一章:入门

    最近准备将Apache MINA 2 0 用户指南英文文档翻译给大家 但是我偶然一次百度 发现 Defonds 这位大牛已经翻译大部分文档 原文链接 http mina apache org mina project userguide c
  • [C#] 汉字转拼音,支持多音字

    这份代码大概不是严格意义上正确的 但是一般场景用用应该没问题 而且支持dotnet core public static class Pinyin region 拼音对照表 private static string py 一 yi 丁 d
  • Unity 调用系统键盘

    using System Diagnostics using UnityEngine public class KeyboardEvent MonoBehaviour private Process keyboard
  • 第十章 内部类(下)

    第十章 内部类 下 随着后面所讲的内容越来越深入 所以可能理解得比较慢了 同时这里边的文字描述和示例也越来越多 希望大家能够坚持下去 慢慢看完 相信会有所收获 当然如果像我一样一个字一个字的敲一遍 印象会更深的 不骗你 因为有的东西开始真的
  • SpringCloud Alibaba 框架背后的故事

    前言 Spring Cloud Alibaba是Spring Cloud的一个子项目 它是由阿里巴巴公司推出的 用于构建基于微服务架构的分布式应用程序的开源框架 它与Spring Cloud的其他组件 如Netflix OSS 相结合 为开
  • sqli-labs Less5-6(布尔盲注)

    目录 前言 一 Less 5 1 布尔型的注入相比前四关 思路上最大的不同就是通过对错来获取对你来说有用的信息 1 先找到注入点 2 先判断数据库长度 3 判断数据库名中的每一个字母是什么 4 同样得方法测试表名 5 根据第四步得出表名 推
  • 人性的弱点

    附 本作品来自互联网 本人不做任何负责 内容版权归作者所有 人性的弱点 by Dale Carnegie雷吟译 目录 这本书对你有十二种功用 译者序 前言 原著序 如何从这本书里获得最大效益 第一篇 待人的基本技巧 第一章 如欲采蜜 勿蹴蜂
  • QT槽函数的使用

    QT槽函数的使用 例如 在头文件中设置槽函数 public slots void OnClickedButtonEnsure void OnClickedButtonExit cpp文件 构造函数中写入 connect ui pushBut
  • STM32F103ZET6【标准库函数开发】------配置定时器参数的几个常用函数

    TIM TimeBaseInitTypeDef 基本初始化 TIM OCInitTypeDef 比较输出初始化 TIM ICInitTypeDef 输入捕获初始化 TIM BDTRInitTypeDef 断路和死区初始化 TIM TimeB
  • pycharm创建的虚拟环境为什么用conda env list命令查询不到?

    问题描述 pycharm创建的虚拟环境为什么用conda env list命令查询不到 pycharm开发环境可以创建虚拟环境 目的是为隔绝其他环境种库带来的版本干扰 但是发现一个问题 无论是在windows终端 anaconda终端 Py
  • Java课程设计-学籍信息管理系统

    一 系统分析 学生的学籍信息是记录学生的重要信息档案 如何以电子文档形式记录下学生的学籍信息是每个学校必须做的事情 该学生学籍信息管理系统就是为了方便学校记录下每一个学生的基本信息 生成电子数据库 并且能够做到查询 更改 删除 浏览等功能操
  • Unity 移动端触摸屏操作

    Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时 桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作 但如多点触屏等操作却是无法利用鼠标操作进行的 Unity的Input类中不仅包含桌面系统的各种输入功能 也包含
  • 关于类和对象

    1 面向对象是一种技术的开发模式 但是最早的时候所使用的模式是面向过程 面向对象就是一种组件化的设计思想 面向过程 指的是针对于某一问题单独提出解决方案及代码开发 面向对象 以一种组件化的形势进行代码的设计 这样开发出来的代码有一个最大的好
  • Python Tkinter实现简单文本编辑器

    下面看看如何利用Tkinter实现一个文本编辑器 语言 python 运行效果 在 Python 代码中使用 Tkinter 的简单文本编辑器应用程序 这 使用Tkinter的简单文本编辑器应用程序 是编码在 python 程序设计语言 该
  • [编写高质量代码:改善java程序的151个建议]建议103 反射访问属性或方法时将Accessible设置为true...

    转载于 https www cnblogs com akingseu p 3506576 html
  • canvas小练习之鼠标粒子特效

  • Qt 笔记5--Qt 拉伸窗体

    Qt 笔记5 Qt 拉伸窗体 正常情况下 Qt主窗体拉伸 但内部子窗体大小及位置并未发生该表 导致出现一部分空白区域 因此实际中为了美观需要实现其动态拉伸和调整效果 以下为笔者通过重新resizeEvent方法实现的一个简单拉伸案例 相应学
  • 小程序如何进行分包详细介绍

    微信小程序开发过程中 随着业务不断迭代 程序包的体积越来越大 使用分包加载是开发者必须面对的问题 正常情况下 小程序首次启动时 会将整个代码包下载下来 所以如果代码包过大 会影响小程序首次启动时间 因此微信官方对小程序代码包做了大小限制 官
  • JetBrains Resharper 2019.1.3的安装、破解、使用

    最近在浏览GitHub时 看到好多项目下面会有如下图标 几经折腾之后 发现这个一个非常好用的VS插件 称为神级也不为过 可以进行编写提示 代码重构 文件搜索等许多操作 当然目前最新版的VS中已经具有很多类似的功能 但是这个插件从实用性上来说
  • 2014年2月7日星期五(7-3,消除了背面的3D线框立方体)

    好久没进行了 看看吧 与DEMO7 2的区别 只看不同的地方 相机类型不同 归一化平面改为2 2 ar 视口为640 480 执行了背面消除 就是判断面元向量与面元到视点向量的点乘 gt 0 则可见 否则 消除 这一步是在物体剔除后和世界坐