Directx 如何在Direct3d11中从顶点缓冲区读取顶点
我有一个关于顶点缓冲区的问题。如何从D3D11中的顶点缓冲区读取顶点?我想得到一个特定顶点的位置来进行计算,如果这个方法是错误的,人们会怎么做呢?以下代码(显然)不起作用Directx 如何在Direct3d11中从顶点缓冲区读取顶点,directx,buffer,direct3d,vertex,Directx,Buffer,Direct3d,Vertex,我有一个关于顶点缓冲区的问题。如何从D3D11中的顶点缓冲区读取顶点?我想得到一个特定顶点的位置来进行计算,如果这个方法是错误的,人们会怎么做呢?以下代码(显然)不起作用 谢谢。以下代码仅获取映射资源的地址,在取消映射之前您没有阅读任何内容 vert = (VERTEX*) ms.pData; 如果要从映射的资源中读取数据,请首先分配足够的内存,然后使用memcpy复制数据,我不知道您的顶点结构,因此我假设vert为void*,您可以自己转换它 vert = new BYTE[ms.Depth
谢谢。以下代码仅获取映射资源的地址,在取消映射之前您没有阅读任何内容
vert = (VERTEX*) ms.pData;
如果要从映射的资源中读取数据,请首先分配足够的内存,然后使用memcpy复制数据,我不知道您的顶点结构,因此我假设vert为void*,您可以自己转换它
vert = new BYTE[ms.DepthPitch];
memcpy(vert, ms.pData, ms.DepthPitch];
代码错误的地方:
- 您要求GPU为您提供其内存地址(
)Map()
- 存储此地址(
)运算符=()
- 然后说:“谢谢,我不再需要它了”(
)李>Unmap()
Map()
Unmap()
之间的指针:使用memcopy、进行循环或任何操作。把它放在数组中,std::vector
,BST,所有东西
新来者在这里可能犯的典型错误:
不检查HRESULT
方法的返回值。如果map失败,它可以返回它喜欢的任何指针。取消引用这样的指针会导致未定义的行为。因此,最好检查任何DirectX函数的返回值
不检查D3D11调试输出。它可以用通俗易懂的英语(显然比我的英语好=)清楚地说出哪里错了,该做什么。所以,您几乎可以立即修复该错误
您只能在具有CPU访问标志的情况下读取,这意味着您还必须设置使用率fag
我们通常如何读取缓冲区:
- 我们不使用暂存缓冲区进行渲染/计算:它很慢李>
- 相反,我们从主缓冲区(非暂存且CPU不可读)复制到暂存缓冲区(or),然后将数据复制到系统内存(
memcopy()
)李>
- 我们在发布版本中不会做太多,这会影响性能
- 暂存缓冲区在现实生活中有两种主要用途:调试(查看缓冲区是否包含错误数据并修复算法中的某些错误)和读取最终的非像素数据(例如,如果您在计算着色器中计算科学数据)
- 在大多数情况下,通过良好地设计代码,可以完全避免暂存缓冲区。假设CPUGPU只有一种连接方式:CPU->GPU
Drop的回答很有帮助。我想我不能读取缓冲区的原因是因为我之前没有将CPU访问标志设置为D3D11。这里
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;
我同意这是性能下降,我想这样做,只是为了能够调试这些值
谢谢你 谢谢你的解释。作为DirectX中的新手,我没有意识到,我可以把最终的变换矩阵与顶点相乘,以获得其在C++代码中的位置,即在着色器之外。这就是我想要的,所以使用管道中的输出流是一种严重的过度使用。谢谢你的解释!复制内存后,如何实际访问顶点?
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;