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

5
一些背景信息:我正在使用C++开发一个项目,旨在根据实时剖面数据绘制物体的三维表示。剖面数据来自外部剖面硬件。系统沿着物体移动,并以每秒300次的速率向我的软件提供剖面切片。每个切片由约8000个X-Y点的列表组成。剖面仪的运动由编码器记录。编码器信息提供了扫描的第三个维度。
另一个重要的事情是,剖面仪可能会在物体上来回移动。随着这种情况的发生,我希望用新的切片替换先前读取/绘制的切片(基于编码器位置)。目前,我通过按编码器计数存储的切片循环缓冲区来实现此目的。这也意味着当缓冲区填满并开始覆盖旧的切片时,我将想要丢弃切片。为了在屏幕上显示适当数量的主题件 - 我需要一次绘制1000个剖面数据切片。现在,我将对象呈现为点云。将来,我们可能会尝试连接相邻的切片并将其呈现为三角形列表。
我对DirectX还不熟悉,但是通过书籍和在线示例,我已经实现了在3D中绘制对象的功能,但是我确信我没有有效/正确地使用顶点缓冲区。我找到的大多数示例都使用非常静态的模型。因此,它们倾向于创建一个带有点列表的单个顶点缓冲区,然后只是通过矩阵变换进行操作。相反,当我从硬件检索剖面数据时,我将非常快速地更新场景。
目前,我为每个读入的切片创建一个新的顶点缓冲区。当我绘制场景时,我循环遍历我的最多1000个缓冲区列表,并为每个缓冲区调用Draw()。我注意到,如果我将一次绘制的顶点缓冲区数量减半,我的FPS会显着增加,而如果将每个缓冲区的顶点数减半,则几乎没有改进 - 因此,我认为这表明多个顶点缓冲区不是适当的方法。
那么,对于我的问题的关键部分......我想知道当顶点频繁更改时是否可以将所有这些顶点放入单个顶点缓冲区中。我能否更新现有顶点缓冲区中的点?还是每次更新场景时都应该重新创建一个全新的缓冲区?最后要记住的一件事是,每个硬件切片的点数将有所不同 - 因此,在覆盖以前的切片时,新切片可能会具有更多或更少的点。
谢谢您的时间。任何建议都将不胜感激!
1个回答

3
只要将缓冲区设为动态(D3D10_USAGE_DYNAMIC),并使用ID3D10Device::CopySubresourceRegion来高效地更新缓冲区的一部分,就可以随时更新顶点缓冲区中的点。这应该比经常重新创建缓冲区更有效。然而,每个切片的大小不同是不好的。你可以实现某种内存管理器来保持顶点缓冲区的总碎片化程度低,或者这是使用多个vb不可避免的点。一种方法是将所有切片大小向上舍入到合理的限制,并为每个大小设置一个vb。

感谢您的回复。您建议使用动态缓冲区听起来非常有前途。至于每个切片具有可变点数,是否有办法在缓冲区内指定间隙 - 空或未使用的顶点?我知道IASetVertexBuffers允许您设置多个缓冲区以及要绘制的每个缓冲区中的哪些顶点。我希望能够有类似的选项来指定要绘制的一个缓冲区内的某些范围,但是到目前为止我没有找到任何类似的选项。 - Tim Coolman
你可以将它们保持原样,不要绘制间隙区域,对吗? - Alexander Gessler
2
经过更多的搜索和阅读,我发现许多人建议使用UpdateSubresource来更新顶点缓冲区的一部分,而且VB甚至不必是动态的。我已经阅读了MSDN上的文档(http://msdn.microsoft.com/en-us/library/bb173621.aspx),但我仍然难以理解传递到该方法中的参数的正确设置方式,特别是_pDstBox_、SrcRowPitch和_SrcDepthPitch_参数。我的顶点缓冲区有100万个顶点长(1000个“切片”,每个切片最多有1000个点)。你用过这个方法吗?谢谢。 - Tim Coolman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接