2012-02-15 59 views
0

我正在开发一个个人项目,与许多XNA项目一样,它的起始地形位移贴图用于生成一个在Device.DrawIndexedPrimitives()调用中呈现的顶点集合。用于地形编辑器的XNA VertexBuffer

我已经更新到自定义VertexDeclaration,但我现在无法访问该代码,所以我会发布稍微老一点的,但范例相同的(?)代码。

我定义VertexBuffer为:

VertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); 
VertexBuffer.SetData(vertices); 

其中“顶点”的定义是:

VertexPositionNormalTexture[] vertices

我也得到了在每个更新换两只指数缓冲区()迭代。在Draw()电话,我设置GraphicsDevice缓冲区:

Device.SetVertexBuffer(_buffers.VertexBuffer); 
Device.Indices = _buffers.IndexBuffer; 

忽略我希望是什么的代码无关的线条,我有一个边界形状内进行检查,以确定是否顶点是在一定半径范围内的方法鼠标光标的位置,并根据按下哪个键来升高或降低顶点位置。我的问题是VertexBuffer.SetData()只在容器类的初始化时被调用一次。

修改VertexPositionNormalTexture[]阵列的顶点位置不会反映到屏幕上,尽管顶点位置的值会发生变化。我相信这与VertexBuffer.SetData()调用相关,但在修改顶点数组后,您不能简单地使用顶点数组调用SetData()

后重新检查IndexBuffer如何(在Update()时间2个缓冲区,交换和传递到SetData())处理,我想这应该是处理VertexBuffer操作的方式,但工作的呢?有更合适的方法吗?我在这里看到另一个类似问题的参考,但链接到源代码是在MegaUpload,所以...

我会尝试我的VertexBuffer.Swap()想法了,但我也看到引用DynamicVertexBuffer,想知道增益有?性能据说会受到影响,但对于地形编辑器来说,如果我可以动态地操作顶点数据,我并不认为这是一个过大的折衷。

我可以发布更多的代码,但我认为这可能是缺乏对如何设置设备缓冲区或数据流式传输给他们的理解。

编辑:下面提出的解决方案是正确的。我会很快发布我的代码。

回答

1

第一:我假设你没有增加或减少地形的顶点。如果你不是,你根本不需要改变索引缓冲区。

第二:在识别简单地编辑您的顶点数组不会改变屏幕上显示的内容时您是正确的。 VertexBuffer与它所创建的顶点完全分离,并且不保留对它们原始数组的引用。这是设置数据时顶点的“快照”。

我不确定你所做的一些假设。您可以在,据我所知,随时调用VertexBuffer.SetData()。如果你没有改变你的地形中的顶点数量,只有它们的位置,这是很好的。每次更改顶点位置时,只需重新设置缓冲区中的数据即可。 [注意:如果我错了,只能将缓冲区中的数据设置一次,那么只需用新缓冲区替换缓冲区的旧实例并在其上设置数据即可。不过,我认为你不需要,除非你已经改变了顶点的数量]

虽然,调用SetData对于大型缓冲区来说相当昂贵。您可以考虑将您的地形“分块”成许多较小的缓冲区,以避免在更改地形时设置数据所需的开销。

我对DynamicVertexBuffer类了解不多,但我不认为这是最佳的(即使听起来像这样)。我认为它更多地用于粒子顶点。虽然我可能是错的。绝对研究它。

出于好奇,为什么你需要两个索引缓冲区?如果你的顶点是相同的,为什么你会使用每帧不同的索引?

编辑:您创建VertexBuffer的代码使用BufferUsage.WriteOnly。好的做法是使BufferUsage与GraphicsDevice相匹配。如果你没有设置设备的BufferUsage,你可能只想使用BufferUsage.None。如果你喜欢,试试并检查性能差异。

+0

我使用两个索引缓冲区,以适应LOD顶点激活/停用。这也很好地说明了你所说的关于SetData是一个相当昂贵的操作。我把我的地形看作象限,有很多层次的子四边形,所以这对我的顶点缓冲区来说可能是一个很好的范例。无论如何,我正在尝试您提出的一些建议,并会在明天报告。 – 2012-02-17 04:35:09

+1

将顶点/索引缓冲区划分为小节还允许您选择性渲染地形的某些部分,并更改特定节的LOD。通过计算摄像机的分段距离和(sectionPosition - cameraPosition)的点积与摄像机的前向矢量的距离,可以在摄像机后面剔除缓冲区,并在远处设置较低的LOD。 – 2012-02-17 17:44:52