我对顶点缓冲区有疑问。如何从D3D11中的顶点缓冲区读取顶点?我想得到一个特定的顶点位置进行计算,如果这种方法错了,怎么会这样做呢?以下代码(显然)不起作用。
VERTEX* vert;
D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(pVBufferSphere, NULL, D3D11_MAP_READ, NULL, &ms);
vert = (VERTEX*) ms.pData;
devcon->Unmap(pVBufferSphere, NULL);
感谢。
答案 0 :(得分:6)
代码错误的地方:
Map()
),operator=()
),Unmap()
)。 取消映射后,您无法真正说出指针指向的位置。它可以指向已经分配了另一个东西的内存位置或者在你女朋友的笔记本电脑的记忆中(只是开玩笑=))。
您必须复制数据(全部或部分),而不是Map()
Unmap()
之间的指针:使用memcopy,for
循环,任何东西。把它放在数组,std::vector
,BST,一切。
新手可以在这里犯下的典型错误:
ID3D11DeviceContext::Map
方法检查HRESULT
返回值。如果map失败,它可以返回它喜欢的任何指针。取消引用此类指针会导致未定义的行为。因此,最好检查任何DirectX函数的返回值。D3D11_CPU_ACCESS_READ
CPU访问标记,则只能从D3D11_USAGE_STAGING
开始阅读,这意味着您还必须设置ID3D11DeviceContext::CopyResource()
使用时间。我们如何通常从缓冲区读取
ID3D11DeviceContext::CopySubresourceRegion()
或{{3}}),然后将数据复制到系统内存(memcopy()
)。 答案 1 :(得分:2)
以下代码仅获取映射资源的地址,在Unmap之前没有读取任何内容。
vert = (VERTEX*) ms.pData;
如果你想从映射资源中读取数据,首先分配足够的内存,然后使用memcpy复制数据,我不知道你的VERTEX结构,所以我认为vert是void *,你可以自己转换< / p>
vert = new BYTE[ms.DepthPitch];
memcpy(vert, ms.pData, ms.DepthPitch];
答案 2 :(得分:1)
Drop的回答很有帮助。我认为我之所以无法读取缓冲区的原因是因为我之前没有将CPU_ACCESS_FLAG设置为D3D11_CPU_ACCESS_READ。这里
D3D11_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.ByteWidth = iNumElements * sizeof(T);
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
bufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE ;
bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
bufferDesc.StructureByteStride = sizeof(T);
然后读取我做的数据
const ID3D11Device& device = *DXUTGetD3D11Device();
ID3D11DeviceContext& deviceContext = *DXUTGetD3D11DeviceContext();
D3D11_MAPPED_SUBRESOURCE ms;
HRESULT hr = deviceContext.Map(g_pParticles, 0, D3D11_MAP_READ, 0, &ms);
Particle* p = (Particle*)malloc(sizeof(Particle*) * g_iNumParticles);
ZeroMemory(p, sizeof(Particle*) * g_iNumParticles);
memccpy(p, ms.pData, 0, sizeof(ms.pData));
deviceContext.Unmap(g_pParticles, 0);
delete[] p;
我同意它的性能下降,我想这样做,只是为了能够调试价值!
非常感谢! =)