如何从Direct3d11中的顶点缓冲区读取顶点

Ma *_* Sa 3 directx buffer direct3d vertex

我有一个关于顶点缓冲区的问题.如何从D3D11中的顶点缓冲区读取顶点?我想获得一个特定顶点的计算位置,如果这种方法错了,怎么会这样做呢?以下代码(显然)不起作用.

VERTEX* vert;
D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(pVBufferSphere, NULL, D3D11_MAP_READ, NULL, &ms);
vert = (VERTEX*) ms.pData;
devcon->Unmap(pVBufferSphere, NULL);  
Run Code Online (Sandbox Code Playgroud)

谢谢.

Iva*_*rop 6

您的代码错误的地方:

  • 你要求GPU给你一个内存地址(Map()),
  • 存储此地址(operator=()),
  • 然后说:"谢谢,我不再需要了它"(Unmap()).

取消映射后,您无法真正说出指针指向的位置.它可以指向已经分配了另一个东西的内存位置或者在你女朋友的笔记本电脑的内存中(只是开玩笑=)).您必须复制数据(全部或部分),而不是指针之间Map() Unmap():使用memcopy,for循环,任何东西.把它放在数组std::vector,BST,一切.

新人可以在这里犯的典型错误:

  1. 不要检查方法的HRESULT返回值ID3D11DeviceContext::Map.如果map失败,它可以返回它喜欢的任何指针.取消引用此类指针会导致未定义的行为.因此,最好检查任何DirectX函数的返回值.
  2. 不检查D3D11调试输出.它可以清楚地说出什么是错的,用简单的英语做什么(显然比我的英语好)=).所以,你几乎可以立即修复bug.
  3. 如果ID3D11Buffer是使用CPU访问标志创建的,则只能读取ID3D11Buffer,D3D11_CPU_ACCESS_READ这意味着您还必须设置D3D11_USAGE_STAGING使用fag.

我们如何通常从缓冲区读取:

  • 我们不使用临时缓冲区进行渲染/计算:它很慢.
  • 相反,我们从主缓冲区(非暂存和CPU不可读)复制到暂存一个(ID3D11DeviceContext::CopyResource()ID3D11DeviceContext::CopySubresourceRegion()),然后将数据复制到系统内存(memcopy()).
  • 我们在发布版本中不会做太多这样做,它会损害性能.
  • 暂存缓冲区有两个主要的实际用法:调试(查看缓冲区是否包含错误的数据并修复算法中的一些错误)和读取最终的非像素数据(例如,如果您在Compute着色器中计算科学数据).
  • 在大多数情况下,您可以通过精心设计代码来避免暂存缓冲区.认为好像CPU < - > GPU仅以一种方式连接:CPU-> GPU.