Direct3D c ++ api如何更新顶点缓冲区?

时间:2014-10-19 18:11:14

标签: c++ windows graphics direct3d directx-11

那么如何使用IASetVertexBuffers方法更新绑定到设备对象的顶点缓冲区中的值?在调用Draw()Present()之前,还会更改此缓冲区中的值吗?还会根据缓冲区中的这些新值来更新图像吗?

1 个答案:

答案 0 :(得分:7)

要通过CPU更新顶点缓冲区,必须首先创建一个允许CPU写入的动态顶点缓冲区。要执行此操作,请将ID3D11Device::CreateBuffer设置为Usage并将D3D11_USAGE_DYNAMIC设置为CPUAccessFlags,然后致电D3D11_CPU_ACCESS_WRITE。例如:

D3D11_BUFFER_DESC desc;
ZeroMemory( &desc, sizeof( desc ) );
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = size;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
d3dDevice->CreateBuffer( &desc, initialVertexData, &vertexBuffer );

现在你有了一个动态顶点缓冲区,你可以使用ID3D11DeviceContext::MapID3D11DeviceContext::Unmap来更新它。例如:

D3D11_MAPPED_SUBRESOURCE resource;
d3dDeviceContext->Map( vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource );
memcpy( resource.pData, sourceData, vertexDataSize );
d3dDeviceContext->Unmap( vertexBuffer, 0 );

其中sourceData是您要放入缓冲区的新顶点数据。

这是一种更新顶点缓冲区的方法,您可以在其中上传一组全新的顶点数据并丢弃以前的内容。还有其他方法可以更新顶点缓冲区。例如,您可以保留当前内容并仅修改某些值,或者您只能更新顶点缓冲区的某些区域而不是整个内容。

每种方法都有自己的用法和性能特征。这完全取决于您的数据是什么以及您打算如何使用它。 This NVIDIA presentation就更新缓冲区以获取不同用途的最佳方法提供了一些建议。

是的,您需要在IASetVertexBuffersDraw()之前调用此Present()以查看当前帧的更新结果。在调用IASetVertexBuffers之前,您不一定需要更新顶点缓冲区内容。这些可以按任何顺序排列。