如何在 DirectX 10 中正确更新顶点缓冲区

Tim*_*man 5 c++ directx vertex-buffer directx-10 vertex

对于一点背景:我正在使用 C++ 开发一个项目,在该项目中我试图根据实时配置文件数据绘制对象的 3D 表示。分析数据是从外部分析硬件收集的。该系统沿着一个物体以每秒 300 次的速度为我的软件提供一个剖面切片。每个切片由约 8000 个 XY 点的列表组成。轮廓仪的运动由编码器记录。编码器信息提供扫描的第三维。

另一个需要注意的重要事项是探查器可能会在对象上来回移动。发生这种情况时,我想用新的切片替换以前读取/绘制的切片(基于编码器位置)。到目前为止,我正在使用我按编码器计数存储的切片的循环缓冲区来实现这一点。这也意味着当缓冲区填满并开始覆盖旧切片时,我会想要丢弃切片。为了在屏幕上显示适当数量的主题片断 - 我需要一次绘制 1000 个切片数据。现在我将对象渲染为点云。将来我们可能会尝试附加相邻的切片并渲染为三角形列表。

我是 DirectX 的新手,但使用书籍和在线示例,我已经达到了在 3D 中绘制对象的程度,但我确信我没有有效/正确地使用顶点缓冲区。我发现的大多数示例都适用于非常静态的模型。因此,他们倾向于用他们的点列表创建一个单一的顶点缓冲区,然后只是通过矩阵变换来操作。另一方面,当我从硬件中检索配置文件数据时,我将非常快速地更新场景。

目前,我正在为我读入的每个切片创建一个新的顶点缓冲区。当我绘制场景时,我会遍历最多 1000 个缓冲区的列表,并为每个缓冲区调用 Draw()。我注意到,如果我将一次绘制的顶点缓冲区数量减少一半,我的 FPS 会显着增加,而将每个缓冲区的顶点点数量减半时几乎没有改进 - 所以我认为这表明多个顶点缓冲区不是解决这个问题的正确方法。

所以对于我的问题的胆量......我想知道当顶点变化如此频繁时我是否可以将所有这些顶点放在一个顶点缓冲区中。我可以更新现有顶点缓冲区中的点吗?或者我应该在每次更新场景时重新创建一个全新的缓冲区?要记住的最后一件事是,硬件中每个切片的点数会有所不同 - 因此,在覆盖之前的切片时,新切片可能比被替换的切片具有更多或更少的点。

谢谢你的时间。任何建议将不胜感激!

Ale*_*ler 3

只要使缓冲区动态化(指定D3D10_USAGE_DYNAMIC并用于ID3D10Device::CopySubresourceRegion仅有效更新缓冲区的一部分),您始终可以更新顶点缓冲区内的点。这应该比过于频繁地重新创建缓冲区更有效。

然而,每个切片的大小不同是不好的。您可以实现某种内存管理器来保持顶点缓冲区的整体碎片较低,否则使用多个 vb 是不可避免的。一种方法是将所有切片大小四舍五入到合理的限制,并为每个大小分配一个 vb。

  • 经过更多的搜索和阅读,我发现很多人建议使用 UpdateSubresource 来更新顶点缓冲区的一部分,并且 VB 甚至不必是动态的。我已经阅读了 MSDN 上的文档(http://msdn.microsoft.com/en-us/library/bb173621.aspx),但我仍然在努力理解设置传递到的参数的正确方法此方法 - 特别是 _pDstBox_、_SrcRowPitch_ 和 _SrcDepthPitch_ 参数。我的顶点缓冲区有 100 万个顶点长(1000 个“切片”,每个切片有 1000 个最大点)。你用过这个方法吗?谢谢。 (2认同)