我有一个地形网格,每个顶点的Z值需要更新每一帧。我现在的方法是这样的:更新Direct3D网格的顶点缓冲区的最快方法?
int stepping = CustomVertex.PositionNormalTextured.StrideSize/4;
//ZPtr points to the Z value of the first PositionNormalTextured in the mesh.
//This way we don't have to dereference ->Z for each vertex.
float* ZPtr = &(((CustomVertex.PositionNormalTextured*)
TerrainMesh.LockVertexBuffer(LockFlags.NoOverwrite).InternalDataPointer)->Z);
float* DPtr = TerrainHeight; //point to begin scanning result
float* EndPtr = DPtr + TerrainMesh.NumberVertices; //point to stop scanning result
do { *ZPtr = *DPtr; ZPtr += stepping; } while (++DPtr < EndPtr); //copy data
TerrainMesh.UnlockVertexBuffer(); //unlock
这里,TerrainHeight是Marshal.AllocHGlobal代表地形高度创造了一个float数组。基本上,它扫描整个TerrainHeight数组,并将每个值复制到网格中相应的PositionNormalTextured的Z值。我使用LockFlags.NoOverwrite来避免创建数组的新副本,尽管这看起来没有LockFlags.Discard更快。
它需要长或更长的时间比它计算的CPU,这使我相信应该有一个更快的方式,在新的领域进行更新的网格。我一直无法在Google上找到关于此的信息。有更好的方法来更新顶点缓冲区吗?万一它很重要,网格的大小是用户设置,可能包括超过一百万个顶点(这是用多个网格完成的),但默认设置是32k个顶点,这是单个D3D网格的最大值。
你应该避免每帧更新大的顶点缓冲区。特别是当它包含复制数据时。您的szenario是否允许在例如顶点着色器的高度图? –