渐进网格
我们今天看一下网格的应用当然也是看一下D3DX库提供的与网格相关的接口结构和函数。例如我们从磁盘上面加载一个复杂的3D模型并将该模型绘制出来或者利用渐进网格接口来控制网格的细节层次。ID3DXBuffer接口是一种泛型数据结构该接口为D3DX可所使用并将数据存储在一个连续的内存块中。该接口有两个方法LPVOID GetBufferPointer():返回指向缓存中数据起始位置的指针。DWORD GetBufferSize():返回缓存的大小单位为字节。为了保持该接口的通用性该接口使用了void类型的指针。这就意味着必须由我们来实现被存储的数据类型。例如D3DXLoadMeshFromX函数用ID3DXBuffer类型的返回一个网格对象的邻接信息。由于邻接信息保存在一个DWORD类型的数组中所以当我们想要使用该接口的邻接信息时我们必须对该缓存进行强制类型转换。DWORD * info (DWORD *)adjacencyInfo - GetBufferPointer(); D3DXMATERIAL * mtrls (D3DXMATRIAL *)mtrlBuffer-GetBufferPointer();由于ID3DXBuffer是一个COM对象该接口使用完毕之后必须将其释放以防内存泄露。adjacencyInfo - Release(); mtrlBuffer - Release();我们可用如下函数创建一个空的ID3DXBuffer对象HRESULT D3DXCreateBuffer( DWORD NumBytes,LPD3DXBUFFER * ppBuffer )下面的例子中创建一个能容纳4个整数的缓存。ID3DXBuffer * buffer 0; D3DXCreateBuffer(4*sizeof(int),buffer);XFile:下面我们看一下关于DIRECT3D如何导入建模工具中的文件这里我们说的建模工具主要是3DX MAX和Maya,这些建模工具能够将网格数据(几何信息材质动画以及其他可能的有用数据)导出到文件中。这样我们可以编写一个文件读取程序来提取网格数据并在我们的3D应用程序中使用。这当然是一种方案。但是还有一种更简单的方案。有一种特殊的网格文件称为XFile格式(扩展名为.X).许多建模工具可以将模型数据导成这种格式而且也有许多转换程序可以将其他较流行的网格文件格式转换为.X格式。XFile是DirectX定义的格式。我们可以使用如下函数加载网格数据并将其存储在XFile文件中注意该方法创建了一个ID3DXMesh对象并将XFile中的几何数据加载到该对象中。HRESULT D3DXLoadMeshFromX( LPCSTR pFilename, DWORD Options, LPDIRECT3DDEVICE9 pDevice, LPD3DXBUFFER *ppAdjacency, LPD3DXBUFFER *ppMaterials, LPD3DXBUFFER *ppEffectInstances, PDWORD pNumMaterials, LPD3DXMESH *ppMesh )下面就其参数进行说明pFileName所要加载的XFile文件名。Options 创建某网格副本时的创建标记或标记组合。标记选项的完整列表需要参阅SDK文档。下面是常用的标记D3DXMESH_32BIT 网格将使用32位索引。D3DXMESH_MANAGED 网格数据将存储与托管的内存池中D3DXMESH_WRITEONLY 指定网格数据为只读。D3DXMESH_DYNAMIC 网格缓存将使用动态缓存。pDevic 与该网格对象相关的设备指针。ppAdjacency 返回一个ID3DXBuffer对象该对象包含了一个描述了该网格对象的邻接信息的DWORD类型的数组。ppMaterials 返回一个ID3DXBuffer对象该对象包含了一个描述了该网格对象的材质数据的D3DXMATERIAL类型的结构数组ppEffectInstances 返回一个ID3DXBuffer对象该对象包含了一个D3DXEFFECTINSTANCE结构.现在我们可以将其设为0.pNumMaterials 返回网格中的材质数据即由ppMaterials输出的D3DXMATERIAL数组中元素的个数).ppMesh 返回所创建的并已填充了XFile几何数据的ID3DXMesh对象。XFile材质D3DXLoadMeshFromX函数中的第7个参数返回了该网格对象所含的材质数目第5个参数返回了一个存储了材质数据的D3DXMATRIAL类型的结构数组。D3DXMATERIAL结构的定义如下typedef struct D3DXMATERIAL{ D3DMATERIAL9 MatD3D; LPSTR pTextureFilename; }D3DXMATERIAL;该结构较为简单它包含了D3DMATERIAL9结构和一个指向以NULL结尾的字符串指针该字符串指定了与网格相关的纹理文件名。XFile文件中并未存储纹理数据它只包含了纹理图像文件名该文件名是对实际纹理数据的纹理图像的引用。这样当用D3DXLoadMeshFromX函数加载一个XFile文件后我们必须根据指定的纹理文件名加载纹理数据。值得一提的是D3DXLoadMeshFromX函数载入XFile数据后返回的D3DXMATERIAL结构数组中的第i项就与第i个子集相对应。所以我们将各子集按照012到n-1的顺序进行标记其中n是子集和材质的总数。这样我们就可用一个简单的循环对全部子集进行遍历和绘制从而完成整个网格的绘制。生成顶点法向量XFile文件中有可能没有存放顶点的法向量。如果出现这种情况为了使用光照我们可能需要手工计算每个顶点的法向量。前面我们简要介绍了顶点法向量的计算。但现在既然我们已经了解了ID3DXMesh接口及其父接口ID3DXBaseMesh我们可用如下方法来产生任意网格的顶点法向量。HRESULT D3DXComputeNormals( LPD3DXBASEMESH pMesh, CONST DWORD * pAdjacency);该函数通过发向量平均的方法生成顶点的法向量。如果提供了邻接信息重叠的顶点会被剔除。如果没有提供邻接信息则重叠顶点的法向量由该顶点所依附的各面在该点的局部法向量取平均而得到。很重要的一点是我们传入的参数pMesh的顶点格式中必须包含标记D3DFVF_NORMAL.注意如果一个XFile文件不含顶点法线数据则由函数D3DXLoadMeshFromX所创建的ID3DXMesh网格对象在其顶点格式中将不含D3DFVF_NORMAL标记。所以在使用函数D3DComputeNormal之前我们必须克隆该网格并为其指定一个包含了D3DFVF_NORMAL标记的顶点格式。下面的例子演示整个过程。if( !(pMesh - GetFVF() D3DFVF_NORMAL) ) { ID3DXMesh* pTempMesh 0; pMesh - CloneMeshFVF( D3DXMESH_MANAGED, pMesh - GetFVF() | D3DFVF_NORMAL, Device, pTempMesh); D3DXComputeNormals(pTempMesh,0); pMesh - Release(); pMesh - pTempMesh(); }渐进网格渐进网格用ID3DXPMesh接口表示它允许我们运用一系列的边折叠变换(ECT)对网格进行简化每次ECT都移除一个顶点以及一个或两个面。由于每次ECT都是可逆的(其逆运算称为顶点分裂)我们可对过程进行逆转从而将网格精确回复到初始状态。当然这也就意味着我们无法获得比原始网格更丰富的细节。我们只能对网格进行简化以及逆运算。渐进网格的思路与纹理中的多级渐进纹理类似。进行纹理映射时我们会注意到如果对一个小而远的图元应用高分辨率的纹理实在是一种浪费因为观察者根本不可能注意到这些细节。对于网格也是同样的道理一个小而远的网格完全不必像大而近的网格一样使用大量的面片。所以在满足要求的条件下我们总是尽量使用少的面片来表达一个网格以节省宝贵的绘制时间。生成渐进网格我们可用如下函数创建ID3DXPMesh对象HRESULT D3DXGeneratePMesh( LPD3DXMESH pMesh, CONST DWORD * pAdjacency, CONST D3DXATTRIBUTEWEIGHTS * pVertexAttributeWeights, CONST FLOAT * pVertexWeight, DWORD MinValue, DWORD Options, LPD3DXMESH * ppPMesh }下面就其参数进行说明pMesh 该输入变量包含了网格数据渐进网格将根据此网格产生。pAdjacency 指向包含了pMesh的邻接信息的DWORD类型的数据指针pVertexAttributeWeights 指向D3DXATRIBUTEWEIGHTS类型的结构数组的指针该数组的维数为pMesh-GetNumVertices()该数组的第i项对应于pMesh中的第i个顶点并指定了相应顶点的属性权值。顶点属性权值用于决定在简化过程中顶点被移除的概率。可为该参数传入NULL则每个顶点将被赋予默认的属性权值。pVertexWeight 指向一个float类型数组的指针该数组的维数为pMesh - GetNumVertices()该数组的第i项对应于pMesh中的第i个顶点并指定了相应顶点的权值。一个顶点的权值越高在简化过程中被移除的概率就越小。可将其设置为NULL,这样每个顶点就会被赋予默认的顶点权值1.0.MinValue 网格中的顶点数或面片数(由下一个Options决定)可被简化到的下限。请注意该值只是一种期望值实际还要依赖于顶点的权值或属性权值所以简化结果可能与该值不一致。Options 该参数实际上是D3DXMESHSIMP枚举类型的一个成员。D3DXMESHSIMP_VERTEX 指定了前面的参数MinValue是指顶点树D3DXMESHSIMP_FACE 指定了前面的参数MinValue是指面片数ppPMesh 返回所生成的渐进网格。顶点属性权值typedef struct D3DXATTRIBUTEWEIGHTS { FLOAT Position; FLOAT Boundary; FLOAT Normal; FLOAT Diffuse; FLOAT Specular; FLOAT Texcoord[8]; FLOAT Tangent; FLOAT Binormal; } D3DXATTRIBUTEWEIGHTS,*LPD3DXATTRIBUTEWEIGHTS;该顶点权值结构允许我们为顶点的每一个可能的分量指定一个权值。如果某个分量的权值被赋为0.0则表明该分量无权值。顶点分量的权值越高在简化过程中该顶点被移除的概率越小各分量的默认权值为D3DXATTRIBUTEWEIGHTS AttributeWeights; AttributeWeights.Position 1.0; AttributeWeights.Boundary 1.0; AttributeWeights.Normal 1.0; AttributeWeights.Diffuse 0.0; AttributeWeights.Specular 0.0; AttributeWeights.Tex[8] {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};除非你的应用程序有充分的理由一般情况下我们都建议使用这些默认值。ID3DXPMesh 接口方法ID3DXPMesh 接口继承自ID3DXBaseMesh接口。所以前者具有前面所提到的ID3CXMesh接口的全部功能。此外ID3DXPMesh接口还具有以下方法.DWORD GetMaxFaces(VOID);返回渐进网格面片数可被指定的上限。DWORD GetMaxVertices(VOID);返回渐进网格顶点数可被指定的上限。DWORD GetMinFaces(VOID);返回渐进网格面片数可被指定的下限。DWORD GetMinVertices(VOID);返回渐进网格顶点数可被指定的下限。HRESULT SetNumFaces(DWORD Faces);该方法允许我们设置网格的面片数可被简化或细化到的个数。例如假定网格目前有50个面片我们想将其简化到30个可以这样做pMesh - SetNumFaces(30);注意调整后的网格面片数可能与期望的不一致如果Faces小于GetMinFaces(),它将取GetMinFaces()类似如果Faces大于GetMaxFaces(),它将取GetMaxFaces();HRESULT SetNumVertices(DWORD Vertices); 该方法允许我们设置网格的顶点数为可被简化或细化到的个数。例如假定网格目前有20个面片我们想将其简化到40个可以这样做pMesh - SetNumVertices(40);注意调整后的网格面片数可能与期望的不一致如果Vertices小于GetMinVertices(),它将取GetMinVertices()类似如果Vertices大于GetMaxVertices(),它将取GetMaxVertices();HRESULT TrimByFaces( DWORD NewFacesMin, DWORD NewFacesMax, DWORD * rgiFaceRemap, DWORD * rgiVertRemap );该方法允许我们重新设定面片数的最小值(NewFacesMin)和最大值(NewFacesMax).注意NewFacesMin和NewFacesMax必须位于区间[GetMinFaces(),GetMaxFaces()].该函数同时也返回了面片和顶点的重绘信息。HRESULT TrimVertices( DWORD NewVerticesMin, DWORD NewVerticesMax, DWORD * rgiFaceRemap, DWORD * rgiVertRemap );该方法允许我们重新设定顶点数的最小值(NewVerticesMin)和最大值(NewVerticesMax).注意NewVerticesMin和NewVerticesMax必须位于区间[GetMinVertices(),GetMaxVertices()].该函数同时也返回了面片和顶点的重绘信息。原文链接https://blog.csdn.net/z18_28_19/article/details/8790842

相关新闻

前端动画方案大全:CSS、JS、Lottie、Rive、GSAP 的年度选型指南

前端动画方案大全:CSS、JS、Lottie、Rive、GSAP 的年度选型指南

前端动画方案大全:CSS、JS、Lottie、Rive、GSAP 的年度选型指南 一、引子:为什么同时存在五种动画方案? 一个新项目启动时,技术选型讨论中总有一个灵魂拷问:"动画用 CSS 还是 JS?"然后有人提 Lot…

2026/10/18 9:52:56 阅读更多 →
搜索引擎流量变化与SERP优化策略

搜索引擎流量变化与SERP优化策略

1. 搜索引擎流量格局的显著变化 过去十年里,谷歌搜索结果首页首位的点击率一直稳定在30%左右,但今年第三季度出现了明显下滑。根据我跟踪的多个行业数据,榜首点击率平均下降了5-8个百分点,这是自移动搜索兴起以来最显著的一次变动…

2026/10/18 9:53:15 阅读更多 →
VLC媒体播放器终极视频转码指南:5分钟掌握专业级格式转换

VLC媒体播放器终极视频转码指南:5分钟掌握专业级格式转换

VLC媒体播放器终极视频转码指南:5分钟掌握专业级格式转换 【免费下载链接】vlc VLC media player - plays everything, runs anywhere. Code here: https://code.videolan.org/videolan/vlc 项目地址: https://gitcode.com/gh_mirrors/vl/vlc 你是否曾因视频…

2026/10/18 9:00:47 阅读更多 →

最新新闻

AI漫剧全流程制作:从剧本到成片的零基础技术路径

AI漫剧全流程制作:从剧本到成片的零基础技术路径

B站有一套 AI 漫剧教程,标题很夸张:全 666 集,198 小时,零基础入门,还允许白嫖。很多人第一反应是标题党,但仔细看它列出的内容板块——剧本、分镜、静帧、视频、配音、剪辑、保持人物一致——这正是目前 A…

2026/10/19 2:22:37 阅读更多 →
小鹏MONA零接管跑山背后:智驾感知、规划与控制全链路解析

小鹏MONA零接管跑山背后:智驾感知、规划与控制全链路解析

零接管跑山登顶背后:小鹏MONA智驾的技术看点、验证方法与安全边界“完全是老司机水平”“零接管登顶”……最近小鹏 MONA 辅助驾驶跑山的讨论,标题一个比一个猛。作为长期关注智驾技术栈的程序员,我第一反应不是情绪,而是三个问题…

2026/10/19 2:22:37 阅读更多 →
豆包+即梦5.0+LibTV:AI短剧多主体一致性的全流程生产链路

豆包+即梦5.0+LibTV:AI短剧多主体一致性的全流程生产链路

做 AI 短剧,最让人头疼的不是画面不够精致,而是角色前后不一致。第一镜里还是长发白衣的女主,第三镜就变成了短发黑裙,观众一眼就能看出是“拼接货”。这次分享的“豆包 即梦5.0 LibTV”组合,核心就是解决多主体一致…

2026/10/19 2:22:37 阅读更多 →
电力系统多源异构数据融合框架:面向网络入侵检测的Python实现

电力系统多源异构数据融合框架:面向网络入侵检测的Python实现

简介:本资源聚焦电力系统网络安全防护,面向具备Python基础与机器学习知识的科研人员、电力系统安全方向研究生及工业控制系统安全从业者,提供一套针对网络入侵检测的多传感器异构数据融合完整方案。资源以1个77KB的docx文档形式交付&#xff…

2026/10/19 2:22:37 阅读更多 →
AI漫剧零基础全流程:从剧本到剪辑的人物一致性实战

AI漫剧零基础全流程:从剧本到剪辑的人物一致性实战

如果你在B站刷到过类似标题,大概第一反应是:又是标题党,点进去之后发现确实是一套几百集的视频,但里面全是凑数的水课。但“AI漫剧”这个方向,最近变化实在太快,快到大多数人都还没意识到,制作一…

2026/10/19 2:22:37 阅读更多 →
Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

简介:面向Android开发者的SeekBar定制方案资源包,以图片替换系统原生样式,解决默认SeekBar外观单一、难以匹配界面整体设计的问题。压缩包内是一个完整的Eclipse工程示例,演示如何继承SeekBar并编写MySeekBar类,在attr…

2026/10/19 2:21:37 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →