按照lockattribute来划分MESH

2023-11-02

网格模型基础

网格模型

  一:定义

  二:子集和属性缓存

    2.0:子集

    2.1:属性

    2.2:操作

       三:邻接信息

       四:属性表

       五:优化

       六:网格的创建与绘制

             6.1:创建

             6.2:绘制

一:定义

网格模型是一种将物体的顶点数据,纹理,材质等信息存储在一个外部文件中的3D物体模型。网格模型由一个或多个子集subset组成,其中每个子集都具有一组相同材质、纹理和绘制状态等属性的三角形集合。

二:子集和属性缓存 2.0:子集

一个mesh由一个或数个子集组成,一个子集是在mesh中的使用相同属性渲染的一组三角形,这里的属性是指材质,纹理和渲染状态。如下图组成.

 

2.1:属性

(1)网格属性是指物体面具有相同材质,纹理和渲染状态的性质。

属性的级别的是面,比喻A面和B面的属性相同。

(2)Direct3D属性缓存:属性缓存是一个DWORD类型的数组。用于保存每个三角形面的的属性ID。所以属性缓存中的元数个数与网格中的三角形个数相同。如下图,

Attribute Buffer:

Attribute--------- Begin

Triangle lives in subset 0: 0

Triangle lives in subset 1: 0

Triangle lives in subset 2: 0

Triangle lives in subset 3: 0

Triangle lives in subset 4: 1

Triangle lives in subset 5: 1

Triangle lives in subset 6: 1

Triangle lives in subset 7: 1

Triangle lives in subset 8: 2

Triangle lives in subset 9: 2

Triangle lives in subset 10: 2

Triangle lives in subset 11: 2

Attribute--------- End

写出了12个面,每个面的属性ID

2.2:操作

(1)设置属性缓存中的属性

设置属性缓存中的属性,每个面具有自己的属性之后,就等于进行了子集分类。

当需要访问网格模型中的属性缓存时,通过调用LockAttributeBuffer锁定属性缓存,该方法保存一个缓存的首地址在参数二中。通过该地址读取或设置属性缓存中的数据。当该问结束之后,就需要UnlockAttributeBuffer解锁。

设置12个面的属性。

DWORD* pAttrib = NULL;

MpCubeMesh->LockAttributeBuffer(0, &pAttrib);

for(int a = 0; a < 4;  a++) pAttrib[a] = 0;

for(int b = 4; b < 8;  b++) pAttrib[b] = 1;

for(int c = 8; c < 12; c++) pAttrib[c] = 2;

mpCubeMesh->UnlockAttributeBuffer();

(2)读取属性缓存

输出所有面的属性。

DWORD *pAtrribuf = NULL;

mpCubeMesh->LockAttributeBuffer(D3DLOCK_READONLY, & pAtrribuf);

for (int i = 0; i < mFaceNums; i++)

{

outfile << "Triangle lives in subset " << i << ": ";

outfile << pAtrribuf[i] << std::endl;

}

mpCubeMesh->UnlockAttributeBuffer();

三:邻接信息

网格的邻接信息用于指定网格中任意一个三角形与其它三角形的邻接情况,由于每个三角形只有3条边,所以每个三角形也最多和3个三角形相邻。

ID3DXMesh接口提供了一个GenerateAdjacency方法用于生存网格的邻接信息。并将网格的邻接信息保存到一个DWORD数组中,

邻接数组是一个DWORD数组,其中的每一项对应了Mesh中的一个三角形。

mFaceNums*3:由于每个三角形最多和3个三角形相邻,所以该邻接数组必须为网格中的三角形面数的3倍。

邻接信息将会被用到网格优化,且作为里面的参数.

生存网格的邻接信息,并输出

DWORD *AdjacencyInfo = new DWORD[mFaceNums*3];

mpCubeMesh->GenerateAdjacency(0.001f, AdjacencyInfo);

for(int i = 0; i < mFaceNums; i++)

{

outfile << "Triangle's adjacent to triangle " << i << ": ";

outfile << AdjacencyInfo[i * 3    ] << " ";

outfile << AdjacencyInfo[i * 3 + 1] << " ";

outfile << AdjacencyInfo[i * 3 + 2] << std::endl;

}

输出:

Adjacency Buffer:

AdjacencyBuffer--------- Begin

Triangle's adjacent to triangle 0: 1 4 9

Triangle's adjacent to triangle 1: 7 10 0

Triangle's adjacent to triangle 2: 3 5 11

Triangle's adjacent to triangle 3: 6 8 2

Triangle's adjacent to triangle 4: 5 0 10

Triangle's adjacent to triangle 5: 2 8 4

Triangle's adjacent to triangle 6: 7 3 11

Triangle's adjacent to triangle 7: 1 9 6

Triangle's adjacent to triangle 8: 9 5 3

Triangle's adjacent to triangle 9: 7 0 8

Triangle's adjacent to triangle 10: 11 4 1

Triangle's adjacent to triangle 11: 6 2 10

AdjacencyBuffer--------- End

每个面的邻接面索引。第0个面相邻接面的索引是第149号面。

四:属性表

属性表是一个D3DXATTRIBUTERANGE结构的一个数组。属性表对应的是网格子集。

D3DXATTRIBUTERANGE

{

DWORD AttribId; // 网格子集ID

    DWORD FaceStart; //子集面的面的起始值。

DWORD FaceCount; //在子集中的面(三角形)数

DWORD VertexStart; //该子集的起始顶点在顶点缓存中的序号

DWORD VertexCount; //在子集中的顶点数

}

GetAttributeTable(D3DXATTRIBUTERANGE tab, DWORD TableSize);

这个函数可以生成 tablesize属性表的属性数。 属性表结构数组tab。

//获取属性表的属性数

DWORD numSubsets = 0;

mpCubeMesh->GetAttributeTable(0, &numSubsets);

//利用属性数创新Talbe

D3DXATTRIBUTERANGE *table = new D3DXATTRIBUTERANGE[numSubsets];

mpCubeMesh->GetAttributeTable(table, &numSubsets);

输出数组成员

Cout  << Table[0]  << endl;

Subset ID:    0

Face Start:   0

Face Count:   4

Vertex Start: 0

Vertex Count: 8

五:优化

不论是使用手工还是使用3D建模软件所创建的网格模型,其中都可能包含一些无效的顶点和索引,并且网格中属性缓存中的子集顺序也并不一定是有序的,因为,通常在创建或加载网格模型后,需要对网格进行优化以便重组网格中的顶点和索引。

ID3DXMesh接口提供了OptimizeInplace Optimze方对网格进行优化。

他们的不同之处在于,前者是在原网格对象上进行优化,而后者则返回一个优化后的新网格对象。但原网格对象不会发生改变。

优化需要前面所创建的属性表,

pOldAdjacency 优化前的网格邻接信息表

pNewAdjacency 优化后的网格邻接信息表

//优化网格数据

std::vector<DWORD> pOldAdjacency(mpCubeMesh->GetNumFaces() * 3);

std::vector<DWORD> pNewAdjacency(mpCubeMesh->GetNumFaces() * 3);

mpCubeMesh->GenerateAdjacency(0.0001f, &pOldAdjacency[0]);

mpCubeMesh->OptimizeInplace(

D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_COMPACT|D3DXMESHOPT_VERTEXCACHE,

&pOldAdjacency[0], 

&pNewAdjacency[0],

0,0);

六:网格的创建与绘制
 
6.1:创建

通过D3DXCreateMeshFVF 函数来创建一个空的mesh,所谓空mesh是指我们己经指定了顶点数,面数。而只需要向顶点缓存,索引缓存,属性缓存,提供顶点,索引,属性数据就可以了。

HRESULT hr = D3DXCreateMeshFVF(mFaceNums, mVertexNums, D3DXMESH_MANAGED, MeshVertex::FVF, apD9Device, &mpCubeMesh ); 注:即这里的mpCubeMesh还是个空的mesh

D3DXCreateMeshFV(创建空的mesh)-LockVertexBuffer(填充顶点数据)-LockIndexBuffer(设置索引数据)-LockAttributeBuffer(设置属性数据,用作子集分类)-OptimizeInplace(优化)-最后绘制

6.2:绘制

通过调用DrawSubset(i)来进行绘制子集图形

for(vector<LPDIRECT3DTEXTURE9*>::size_type i = 0; i != mpTextures.size(); i++)

{

apD9Device->SetTexture(0, mpTextures[i]);

mpCubeMesh->DrawSubset(i);

}

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

按照lockattribute来划分MESH 的相关文章

  • 【转】物联网常见通信协议

    转载地址 https www jianshu com p f3f1a35f64cc 1 通信 与 通讯 傻傻分得清 传统意义上的 通讯 主要指电话 电报 电传 通讯的 讯 指消息 Message 媒体讯息通过通讯网络从一端传递到另外一端 媒
  • LaTex中把下标置于文本正下方的方法 (转载)

    转载一篇文章 因为我想打出 H z H 0 J m
  • sql注入之万能密码总结

    万能密码 万能密码原理 原验证登陆语句 SELECT FROM admin WHERE Username username AND Password md5 password 输入 1 or 1 1 or 1 1万能密码语句变为 SELEC
  • 网络面试题及答案

    1 标准网络线的颜色排列顺序 568B 橙白 橙 绿白 蓝 蓝白 绿 棕白 棕 568A 绿白 绿 橙白 蓝 蓝白 橙 棕白 棕 直通线一般都用 A线序或 B线序 交叉线一端是 568A 一端 是 568B 2 按照数据访问速度排序 硬盘
  • 【转载】关于在keil5的time environment没有StdPeriph Drivers(标准库)但是又想使用库函数的解决办法

    关于在keil5的time environment没有StdPeriph Drivers 标准库 但是又想使用库函数的解决办法 本人刚刚接触keil5 遇到了一些问题 希望我的方法能帮到大家 作者本人使用的是芯片是stm32f407VET6
  • “你已被移出穷人群”

    壹心理创作者 触角 本文转载自壹心理旗下最有料公众号 心理公开课 ID yixinligongkaike 01 关于 贫穷 我们受到的恐吓不下10000次 中国的年轻人 光是今年 受到贫穷的恐吓就可能不下10000次 一篇细致描绘北漂生活的
  • iOS 自动构建命令——xcodebuild

    想想当初天天来到公司 每天需要做一件事就是打开Xcode打包ipa 上传到fir 日复一日月复一月年复一年的做着同样的事情 作为有志成为优秀工程师的我来说 这是必须要解决的问题 所以决定自动化解决问题 简介 xcodebuild 是苹果发布
  • BAJT 中高级 Java 面试题答案

    1 请问你做过哪些JVM优化 使用什么方法达到什么效果 vm调优主要也就是内存空间的分配 最终策略 提高系统性能 主要策略有 1 增加eden空间 让更多的对象留在年轻代 2 大对象直接放到老年代 以免扰乱年轻代高频率的gc XX Pete
  • [转载]QT框架的一个截图工具

    原文标题 Snipaste 开发了三年的截图工具 但不只是截图 原文作者 levie 一直以来都想要入门QT 但是却一直没有付诸行动 昨天在无意间发现了 这个开发者的截图工具 虽然我还没有使用 但是看上去却很能吸引目光 便重新激发了我开始学
  • qt退出定位

    https blog csdn net u011430225 article details 52812854
  • 什么是to B 业务

    引言 To B or Not to B there is not a question 对于企业而言 数据分析的作用主要体现在三大领域 1 是对业务的改进优化 2 是帮助业务发现机会 3 是创造新的商业价值 数据分析最重要的是基于对业务的理
  • jumpserver堡垒机 (资源)

    23 5 jumpserver介绍 官网www jumpserver org 跳板机概述 跳板机就是一台服务器 开发戒运维人员在维护过程中首先要统一登录到这台服务器 然后再登录到目标 设备迚行维护和操作 堡垒机概述 堡垒机 即在一个特定的网
  • SpringCloud与SpringBoot的版本对应关系

    在SpringCloud官网 https spring io projects spring cloud 可以看到 当前 2021年11月 SpringCloud的最新GA版本是2020 0 4这一版 除了2020 0 X版本外 Sprin
  • 解密蓝牙mesh系列

    转载自 蓝牙技术联盟 蓝牙mesh网络基本概念 本周跟大家分享解密蓝牙mesh系列第四篇 点这里查看第一篇 第二篇和第三篇文章 同时也是蓝牙mesh网络基本概念的第二部分 借助蓝牙mesh 您将能够创建大型网络并支持成千上万的设备之间进行安
  • Java/JDK 21正式发布!15个特性一览

    订阅专栏 JDK 21已经于2023年9月19日正式发布 本文总结了JDK 21发布的新特性 发布版本说明 根据发布的规划 这次发布的 JDK 21 将是一个长期支持版 LTS 版 LTS 版每 2 年发布一个 上一次长期支持版是 21 年
  • kaggle冠军代码汇总

    https www cnblogs com rw rongwei p 6509146 html
  • 硬盘故障时如何强制关机:Input/output error

    如果硬盘可能会出现锁死或坏道的故障 会造成SHELL命令的失效 包括 reboot powoff shutdown 用正常的命令是没法完成重启的 执行这些命令 会出现如下IO报错 reboot bash sbin reboot Input
  • Shell 脚本中 '$' 符号的多种用法

    来源 JackTian 杰哥的IT之旅 https mp weixin qq com s XBu7G UxPs2dv6fsPXGq4w 通常情况下 在工作中用的最多的有如下几项 0 Shell 的命令本身 1 到 9 表示 Shell 的第
  • char码值对应列表大全

    char码值对应列表大全 Char 0 为0的字符 Char 1 Char 2 Char 3 Char 4 Char 5 Char 6 Char 7 响铃 Char 8 回格 Char 9 tab 水平制表符 Char 10 换行 Char
  • 探索第三方 API 服务的身份验证方法:优点和缺点

    探索第三方 API 服务的身份验证方法 优点和缺点 赛斯 法特的相片 赛斯法特 2023 年 3 月 18 日 4分钟阅读 嗨 大家好 我们中的大多数人已经使用多个第三方 API 服务来实现您的业务逻辑 是的 他们中的大多数都有不同的身份验

随机推荐