你需要频繁更新顶点数据,如果使用VertexBuffer的SetData方法会拖慢程序。
如果你计划频繁更新顶点数据,应该使用DynamicVertexBuffer而不是VertexBuffer。
这会让数据不是存储在最快的显存中,而是更容易处理的某些内存中。所以,这样做会让性能有一点降低,但在VertexBuffer中频繁地改变数据会让性能得到极大地提高。
对于VertexBuffer,只要显卡被要求切换任务(例如,使用Alt+Tab切换程序),DynamicVertexBuffer中的内容必须被重载,你可以通过订阅到DynamicVertexBuffer的ContentLost事件上实现这个功能。
DynamicVertexBuffer的工作原理与VertexBuffer很像。首先需要一个顶点数组,如下所示:
private void InitVertices() { myVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements); vertices = new VertexPositionTexture[6]; int i = 0; vertices[i++] = new VertexPositionTexture(new Vector3(-5.0f, -3, -1), new Vector2(-0.5f, 1.5f)); vertices[i++] = new VertexPositionTexture(new Vector3(-2.5f, 5, -1), new Vector2(0.5f, -1.5f)); vertices[i++] = new VertexPositionTexture(new Vector3(0, -3, -1), new Vector2(1.5f, 1.5f)); vertices[i++] = new VertexPositionTexture(new Vector3(0, -3, -1), new Vector2(-0.5f, 1.5f)); vertices[i++] = new VertexPositionTexture(new Vector3(2.5f, 5, -1), new Vector2(0.5f, -1.5f)); vertices[i++] = new VertexPositionTexture(new Vector3(5.0f, -3, -1), new Vector2(1.5f, 1.5f)); dynVertBuffer = new DynamicVertexBuffer(device, VertexPositionTexture.SizeInBytes * vertices.Length, BufferUsage.WriteOnly); dynVertBuffer.SetData(vertices, 0, vertices.Length, SetDataOptions.NoOverwrite); dynVertBuffer.ContentLost +=new EventHandler(dynVertBuffer_ContentLost); }
创建DynamicVertexBuffer接受和创建VertexBuffer一样的参数,但SetData方法接受一个新的加强的参数,我会在下面讲到。最后一行代码是新的,如果显卡被要求处理另一个程序,设备会丢失,DynamicVertexBuffer的内容也会丢失。所以你要在DynamicVertexBuffer 的ContentLost事件上订阅一个方法。只要DynamicVertexBuffer丢失了内容就会引发ContentLost 事件,对应的方法就会被调用,这个方法会重载DynamicVertexBuffer中的内容。本例中,你将dynVertBuffer_ContentLost方法订阅到事件。
当然你还要定义这个方法,在这个方法中重载缓冲的内容:
private void dynVertBuffer_ContentLost(object sender, EventArgs e) { dynVertBuffer.SetData(vertices, 0, vertices.Length, SetDataOptions.NoOverwrite); }
注意:这需要本地处理顶点数据。因为只有当顶点数据变化地很频繁时才使用DynamixVertexBuffer,所以首先要保证数据没有问题,记住你永远不会从(Dynamic)VertexBuffer中读取数据。
当进行到绘制这步时,DynamicVertexBuffer的工作方式与VertexBuffer是相同的。
因为当你想频繁更新数据时才会使用DynamicVertexBuffer,所以你会经常使用SetData 方法。因此DynamicVertexBuffer的SetData方法还接受一个额外的参数SetDataOptions。
这个参数让你可以指定一些选项可以提高程序的速度。默认情况下,当你想覆盖显存中的内容时,因为不支持同时读写,显卡无法从显存中读取数据。当你把大量数据写至内存时会导致显卡的绘制过程中止,这是因为显卡要等待你的复制过程结束。但是,有两个方法可以让你确保显卡不会等待复制操作结束。你可以使用SetDataOptions 参数,下面是可选项: