ここぷろ!

私がプログラミングで学んだこと、行き詰った事などを書いていきます。たまに個人的なことも載せるかも

【DirectX12】DirectX開発にComPtrのススメ

 こんにちは、ここあです。

 今日DirectXの勉強をしていて思ったことがありました。

 日本語でDirectX12に関して初期化の先まで解説しているサイトがほぼ無い気がする! そうだ、どうせ自分で開発していくんだから記事を書いていけばいいじゃないか!
※もし説明してくださっているサイトさんがあった場合はごめんなさい

 

 というわけで、私は初期化して三角形を描画するだけではなく、さらに色々実装していく予定ですので書いていくことにしました。

 C++のコーディングなどに関しては、機会を見て別で書いていこうかなとも思っているので、主にDirectX12に関係する部分を書いていきたいと思います。

 別に特別な実装が出来たとか進捗があったとかの場合は、そっち優先で書いていく予定です。

※過去バージョンのDirectXをよく知らないので、被る説明をする可能性もあります。

 東京から返ってくる間も、スマホ機内モードでDirectX12の資料を読んだりしてたのですが、絶対に忘れると思ったので、備忘録的にも扱っていきたいと思います。

 

DirtectXにはComPtrを

ComPtrとは

 ComPtrスマートポインタというもので、ポインタをラップして、ポインタ型に応じて適切な処理を行う機能を追加したクラスの総称です。
 一般的にポインタに関連付けられたオブジェクトの管理をする為にを使うようです。
 私は今回の開発でこれを使って、初期化処理などを実装しました。なので、なぜ使ったのかに関して解説していきたいと思います。

 DirectXはその大部分をCOMオブジェクトで実装しているようです。
 COMオブジェクトについてはこちらを参照。

COM オブジェクトとは


COMオブジェクトの作成と削除

 そして、これが今回の記事を書いた一番の理由なのですが、COMオブジェクトの場合、Microsoftが便利な物が用意されていて、それがMicrosoft::WRL::ComPtrです。
 ComPtrは、いちいちプログラマがRelase関数を呼ばなくても、必要なときに自動的に呼んでくれます

 DirectX12の初期化には多くのCOMオブジェクトを作成しなくてはなりません。なので、個別でいちいちRelease関数を呼び出すのはコードを書く上でとても面倒くさい大変なので、これを使うというわけです。


 DirectXでCOMオブジェクトを作成するためには、一般的なC++のオブジェクト生成の様に変数を宣言したり、newするのではコンパイルエラーになります。

 どうすれば作成できるのかというと、用意された専用の関数を呼び出すことで作成できます。例えば、ID3D12Deviceの場合、ID3D12CreateDevice関数を呼び出すことで作成できます。

 また、COMオブジェクトを削除する場合も、生成と同じく専用のRelease関数を呼び出します。


COMオブジェクトの成功・失敗判定

 COMオブジェクトの多くの関数がHRESULT型の32bit整数を返すので、DirectXではこの型を使った、成功か失敗かの判定に使用することが多いみたいです。

関数名 TRUE FALSE
SUCCEEDED 成功 失敗
FAILED 失敗 成功
ComPtr<ID3D12Device> device;

if(FAILED(D3D12CreateDevice(/*引数*/)){
    // 処理
}

device->Release();

DirectXの関数は引数が多いので、ここでは割愛させていただきます。


 こうすることで処理を一文で書くことが出来るので、私はこの方法で記述しています。
 これは、人の好みだとは思うのですが、以下の様な書き方をする方もいるようです。

HRESULT hr =FAILED(D3D12CreateDevice(/*引数*/)

if(hr){
    // 処理
}

 私個人の意見としては、デバッグするときに結果が明確にわかりやすい変数に入っているので、そういった場合に良いのかなと思っています。

終わりに

 今回はDirectXを使う上でとても楽になるであろうCOMオブジェクトの作成について、解説しました。
 明日以降はDirectX12で使っていく各インタフェースのCreate関数について解説していきたいと思います。
 それでは、今回はこのあたりで。