在 DirectX 11 中从 GPU 读回顶点缓冲区(并获取顶点)
Read Back Vertex Buffers from GPU in DirectX 11 (and get vertices)
我正在尝试使用以下方法访问我的应用程序顶点缓冲区(以及那里的顶点):
//access vertex buffers
UINT* Stride = new UINT[32];
UINT* veBufferOffset = new UINT[32];
ID3D11Buffer** veBuffer = new ID3D11Buffer * [32];
pContext->IAGetVertexBuffers(0, 32, veBuffer, Stride, veBufferOffset);
std::ostream& operator<<(std::ostream & out, const ID3D11Buffer& buff); // my attempt at overloading...
for (int i = 0; i < 32; i++)
{
ID3D11Buffer* buff = veBuffer[i];
for (int e = 0; e < 50; e++) {
out << buff[e] << std::endl;
return out;
}
}
我可以毫无问题地循环遍历 veBuffer,但是我没有成功访问顶点 (buff[e])。
我已经阅读了很多这方面的资料,但我仍然不完全确定从这里到哪里去。
我也知道使用流输出阶段可以做什么:https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-stream-stage?redirectedfrom=MSDN
它指出您可以从几何着色器获取顶点缓冲区。据我了解,几何着色器一次输入一个图元(三角形或直线)。我正在寻找每个模型的缓冲区。
我找到这篇关于从 GPU 回读数据的文章:https://docs.microsoft.com/en-us/windows/win32/direct3d12/readback-data-using-heaps
不幸的是,它适用于 DirectX 12。是否有等效的 DirectX 11 方法?
这是一种方法。
像您一样获取 ID3D11Buffer
指针。理想情况下使用 std::vector<CComPtr<ID3D11Buffer>>
之类的东西而不是 new/delete 但这不是太重要,至少对于小项目来说不是。
调用 ID3D11Buffer::GetDesc
获取您要读取的缓冲区的大小和其他参数。
调整buffer的描述,设置usage为D3D11_USAGE_STAGING
,bind flags为0,CPU access flags为D3D11_CPU_ACCESS_READ
.
通过调用 ID3D11Device::CreateBuffer
,使用修改后的描述创建另一个临时缓冲区。不要指定初始数据,在那里传递 nullptr
。
通过调用 ID3D11DeviceContext::CopyResource
将源缓冲区复制到新创建的临时缓冲区中
现在您可以使用 ID3D11DeviceContext::Map/Unmap 从您在步骤 4 中创建的临时缓冲区中读取顶点数据。
P.S。如果您想回读索引缓冲区或任何其他资源类型,工作流程是相同的:创建一个临时暂存资源,复制并从暂存资源中读取。
我正在尝试使用以下方法访问我的应用程序顶点缓冲区(以及那里的顶点):
//access vertex buffers
UINT* Stride = new UINT[32];
UINT* veBufferOffset = new UINT[32];
ID3D11Buffer** veBuffer = new ID3D11Buffer * [32];
pContext->IAGetVertexBuffers(0, 32, veBuffer, Stride, veBufferOffset);
std::ostream& operator<<(std::ostream & out, const ID3D11Buffer& buff); // my attempt at overloading...
for (int i = 0; i < 32; i++)
{
ID3D11Buffer* buff = veBuffer[i];
for (int e = 0; e < 50; e++) {
out << buff[e] << std::endl;
return out;
}
}
我可以毫无问题地循环遍历 veBuffer,但是我没有成功访问顶点 (buff[e])。 我已经阅读了很多这方面的资料,但我仍然不完全确定从这里到哪里去。
我也知道使用流输出阶段可以做什么:https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-stream-stage?redirectedfrom=MSDN
它指出您可以从几何着色器获取顶点缓冲区。据我了解,几何着色器一次输入一个图元(三角形或直线)。我正在寻找每个模型的缓冲区。
我找到这篇关于从 GPU 回读数据的文章:https://docs.microsoft.com/en-us/windows/win32/direct3d12/readback-data-using-heaps
不幸的是,它适用于 DirectX 12。是否有等效的 DirectX 11 方法?
这是一种方法。
像您一样获取
ID3D11Buffer
指针。理想情况下使用std::vector<CComPtr<ID3D11Buffer>>
之类的东西而不是 new/delete 但这不是太重要,至少对于小项目来说不是。调用
ID3D11Buffer::GetDesc
获取您要读取的缓冲区的大小和其他参数。调整buffer的描述,设置usage为
D3D11_USAGE_STAGING
,bind flags为0,CPU access flags为D3D11_CPU_ACCESS_READ
.通过调用
ID3D11Device::CreateBuffer
,使用修改后的描述创建另一个临时缓冲区。不要指定初始数据,在那里传递nullptr
。通过调用
将源缓冲区复制到新创建的临时缓冲区中ID3D11DeviceContext::CopyResource
现在您可以使用 ID3D11DeviceContext::Map/Unmap 从您在步骤 4 中创建的临时缓冲区中读取顶点数据。
P.S。如果您想回读索引缓冲区或任何其他资源类型,工作流程是相同的:创建一个临时暂存资源,复制并从暂存资源中读取。