I have a terrain mesh where just the Z value for each vertex needs to be updated every frame. My current method looks like this:
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
Here, TerrainHeight is a float array created with Marshal.AllocHGlobal representing terrain height. Basically it scans across the entire TerrainHeight array and copies each value to the Z value of the respective PositionNormalTextured in the mesh. I used LockFlags.NoOverwrite to avoid creating a new copy of the array, although that doesn't seem any faster than LockFlags.Discard.
It takes as long or longer to update the mesh than it does to compute the new terrain in the CPU, which leads me to believe there should be a faster way. I've been having trouble finding info on Google about this. Is there a better way to update the vertexbuffer? In case it matters, the size of the mesh is user set and may include over a million vertices (this is accomplished with multiple meshes), but the default settings is 32k verts which is the max for a single D3D mesh.