如何从Direct3d11中的顶点缓冲区读取顶点 [英] How to read vertices from vertex buffer in Direct3d11

查看:92
本文介绍了如何从Direct3d11中的顶点缓冲区读取顶点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对顶点缓冲区有疑问。如何从D3D11的顶点缓冲区中读取顶点?我想获得特定顶点的位置来进行计算,如果这种方法不正确,那该怎么办?以下代码(显然)无效。

I have a question regarding vertex buffers. How does one read the vertices from the vertex buffer in D3D11? I want to get a particular vertex's position for calculations, if this approach is wrong, how would one do it? The following code does not (obviously) work.

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

谢谢。

推荐答案

您的代码错误的地方:


  • 您要求GPU给您地址内存( Map()),

  • 存储此地址( operator =()),

  • 然后说:谢谢,我不再需要它了( Unmap())。

  • You asking GPU to give you an address to its memory(Map()),
  • Storing this adress (operator=()),
  • Then saying: "Thanks, I don't need it anymore" (Unmap()).

取消映射后,您无法真正说出指针现在指向的位置。它可以指向已经分配了其他东西的内存位置,或者指向女友的笔记本电脑的内存(只是在开玩笑=)。
您必须复制数据(全部或部分),而不要复制 Map() Unmap():使用内存复制,用于循环,任何方法。将其放在数组中, std :: vector ,BST,所有内容。

After unmap, you can't really say where your pointer now points. It can point to memory location where already allocated another stuff or at memory of your girlfriend's laptop (just kidding =) ). You must copy data (all or it's part), not pointer in between Map() Unmap(): use memcopy, for loop, anything. Put it in array, std::vector, BST, everything.

新手可以犯的典型错误在此处进行


  1. 不检查 HRESULT 从< a href = http://msdn.microsoft.com/zh-cn/library/windows/desktop/ff476457%28v=vs.85%29.aspx rel = noreferrer> ID3D11DeviceContext: :Map 方法。如果map失败,它可以返回它喜欢的任何指针。取消引用此类指针会导致未定义的行为。因此,最好检查任何DirectX函数的返回值。

  2. 不要检查D3D11调试输出。它可以用通俗易懂的英语(显然比我的英语=)要好得多,可以清楚地说出问题和处理方法。因此,您几乎可以立即修复错误。

  3. 您只能从 ID3D11Buffer (如果它是已创建,其中 D3D11_CPU_ACCESS_READ CPU访问标志,这意味着您还必须设置 D3D11_USAGE_STAGING 使用率错误。

  1. Not to check HRESULT return value from ID3D11DeviceContext::Map method. If map fails it can return whatever pointer it likes. Dereferencing such pointer leads to undefined behavior. So, better check any DirectX function return value.
  2. Not to check D3D11 debug output. It can clearly say what's wrong and what to do in plain good English language (clearly better than my English =) ). So, you can fix bug almost instantly.
  3. You can only read from ID3D11Buffer if it was created with D3D11_CPU_ACCESS_READ CPU access flag which means that you must also set D3D11_USAGE_STAGING usage fag.

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


  • 我们不使用暂存缓冲区进行渲染/计算:这很慢。

  • 相反,我们从主缓冲区(非暂存和CPU无法读取)复制到暂存一个( ID3D11DeviceContext :: CopyResource() 或< a href = http://msdn.microsoft.com/zh-cn/library/windows/desktop/ff476394%28v=vs.85%29.aspx rel = noreferrer> ID3D11DeviceContext: :CopySubresourceRegion() ),然后将数据复制到系统内存( memcopy())。

  • 我们在发行版本中不要做太多,这会损害性能。

  • 临时缓冲区有两种主要的实际用法:调试(查看缓冲区是否包含错误的数据并修复算法中的某些错误)并读取最终的非像素数据(例如,如果您在Compute shader中计算科学数据)。

  • 在大多数情况下通过精心设计代码,您可以完全避免登台缓冲区。认为好像CPU<-> GPU仅以一种方式连接:CPU-> GPU。

  • We don't use staging buffers for rendering/calculations: it's slow.
  • Instead we copy from main buffer (non-staging and non-readable by CPU) to staging one (ID3D11DeviceContext::CopyResource() or ID3D11DeviceContext::CopySubresourceRegion()), and then copying data to system memory (memcopy()).
  • We don't do this too much in release builds, it will harm performance.
  • There are two main real-life usages of staging buffers: debugging (see if buffer contains wrong data and fix some bug in algorithm) and reading final non-pixel data (for example if you calculating scientific data in Compute shader).
  • In most cases you can avoid staging buffers at all by well-designing your code. Think as if CPU<->GPU was connected only one way: CPU->GPU.

这篇关于如何从Direct3d11中的顶点缓冲区读取顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆