DX11 将顶点缓冲区映射为 WRL::ComPtr

Posted

技术标签:

【中文标题】DX11 将顶点缓冲区映射为 WRL::ComPtr【英文标题】:DX11 Mapping vertex buffer as WRL::ComPtr 【发布时间】:2016-02-05 14:04:11 【问题描述】:

我在映射顶点缓冲区时遇到问题。当我这样做时:

ID3D11Buffer* pD3DSingleVertexBuffer;
...
pD3DImmediateContext->Map(pD3DSingleVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mappedSubresource);

一切正常,所有框架都正常工作。但是,当我这样做时:

Microsoft::WRL::ComPtr<ID3D11Buffer> pD3DSingleVertexBuffer;
...
pD3DImmediateContext->Map(pD3DSingleVertexBuffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mappedSubresource);

没有渲染,但应用程序没有崩溃,也没有任何错误。

你知道我做错了什么吗?

【问题讨论】:

好的,我已经解决了这个问题,长话短说,后来在代码中我使用了这个:pD3DImmediateContext-&gt;IASetVertexBuffers(0, 1, &amp;pD3DSingleVertexBuffer, &amp;stride, &amp;offset);insted of this pD3DImmediateContext-&gt;IASetVertexBuffers(0, 1, pD3DSingleVertexBuffer.GetAddressOf(), &amp;stride, &amp;offset); 【参考方案1】:

正如您所发现的,虽然 D3D 中经常使用的创建单元素数组的经典方法是仅对单个元素使用 address-of 运算符,但它也常用于将输出参数传递给创建方法(例如 @987654321 @)。由于这是更常见的用法,尤其是在整个 Win32 API 表面的上下文中,ComPtr 旨在安全地提供输出参数语义,Release()在返回其地址之前将包含的对象。

有两种方法可以解决这个问题。第一个是实际创建一个对象数组,例如ID3D11Buffer** ppBuffers[] = pBuffer.Get() ;。第二种是使用ComPtr::GetAddressOf,它返回包含对象的地址而不更改其引用计数。在后一种情况下,请注意不要在您确实将容器用作输出参数的情况下使用它,否则您会泄漏先前保存的对象。

【讨论】:

以上是关于DX11 将顶点缓冲区映射为 WRL::ComPtr的主要内容,如果未能解决你的问题,请参考以下文章

DX11 中的顶点缠绕顺序

DX:粒子系统

顶点和纹理坐标的缓冲区大小不同?

如何在 C++ 中急切提交分配的内存?

DX11 恒定缓冲区持久性

C++ DirectX 11 从第二个顶点缓冲区渲染问题