组件对象模型(Component Object Model,COM)是一种令DirectX不受编程语言束缚,并且使之向后兼容的技术。我们通常将COM对象视为一种接口,但考虑当前编程的目的,遂将它当做一个C++类来使用。用C++语言编写DirectX时,COM帮我们隐藏大量的细节。我们只需知道:要获取指向某COM接口的指针,需借助特定函数或另一个COM接口的方法--而不是用C++语言中的关键字new去创建一个COM接口。另外,COM对象会统计其引用次数;因此,在使用完某接口时,我们便应调用它的Release方法(COM接口的所有功能提供是从IUnknow这个COM接口继承而来,包括Release方法在内),而不是用delete来删除---当COM对象的引用计数为0时,它将自行释放做自己所占用的内存。
为了辅助用户管理COM对象的生命周期,Windows运行时库(Windows Runtime Library, WRL)专门为此提供了Microsoft::WRL::ComPtr类(#include<wrl.h>),我们可以帮它当作是COM对象的智能指针。当一个ComPtr实例超出作用域范围时,它便会自动调用COM对象的Release方法,继而省掉了我们手动调用的麻烦。常用的3个ComPtr方法如下:
1.Get:返回一个指向此底层COM接口的指针。此方法常用于把原始的COM接口指针作为参数传给函数。例如:
#include <wrl.h>
ComPtr<ID3D12RootSignature>mRootSignature;
...
//SetGraphicsRootSignature需要获取ID3D12RootSignature*类型参数
mCommandList->SetGraphicsRootSignature(mRootSignature.Get());
2.GetAddressof:返回指向此底层COM接口指针地址。凭此方法即可利用函数返回COM接口指针。例如:
#include <wrl.h>
ComPtr<ID3D12RootSignature>mDirectCmdListAlloc;
...
ThrowIfFailed(md3dDevice->CreateCommandAllocator(
D3D12_COMMAND_LIST_TYPE_DIRECT,
mDirectCmdListAlloc.GetAddressof()));
3.Reset:将此ComPtr实例设置为nullptr释放与之相关的所有引用(同时减少其底层COM接口的引用计数)。此方法的功能与将ComPtr目标实例赋值为nullptr的效果相同。
当然,与COM有关的知识不止于此,但是对有效地使用DirectX来说足矣。
注意:
COM的接口都以“I”作为开头。例如,表示命令列表的COM接口为ID3D12GraphicsCommandList。