​点の描画

 一つの点を描画したいと思います。画像からはほとんど見えませんが、サンプルを実行してみると中心付近に一つの白い点があり、ぐるぐると画面中央のZ軸を中心に回っています。たったそれだけのシンプルなものですが、プログラムの内容や流れは、この後に続く線や面、立体を描画する場合とほぼ一緒です。そのため、コードの記述量が倍に増えます。前回からの内容で増えたものを大まかに言うと、

  ・パイプラインの構築と描画データ
  ・シェーダ
  ・DirectXMathによる計算

の3つになるかと思います。今回は、「パイプラインの構築と描画データ」に関しての説明をしたいと思います。その他のものについては、次回以降に分けて解説していきたいと思います。

 パイプラインとは、「DirectX側での一連の処理、各工程の作業を繋げたもの」を表す言葉です。DirectXを使うためには、このパイプラインを事前にプログラマが設計・構築して用意しなくてはいけません。そして、出来上がったパイプラインに描画で使うデータ(頂点や色、画像等)を流し込んで、出てきた結果を画面上に表示することで完成です。パイプライン上の各工程(ステージ)内で行われる処理内容は、プログラマによって定義・制御が可能で(次回説明のシェーダ)、次の5つがあります。

  ・頂点シェーダステージ
  ・ハルシェーダステージ
  ・ドメインシェーダステージ
  ・ジオメトリシェーダステージ
  ・ピクセルシェーダステージ

この内サンプルで使っているのは一番上と下にある、頂点シェーダとピクセルシェーダのみです(他は省略可)。頂点シェーダでは、最初に入ってきた頂点データを加工する所で、基本的に座標変換を行います。ピクセルシェーダでは、最終的に表示される色をピクセル毎に処理することが可能です。
 

それでは実際にパイプラインの構築、データの取り扱いに関する部分をコードと共に見ていきたいと思います。

​コード解説

① 頂点レイアウトと描画データの定義
 まずは描画に使う頂点データに関して、その情報を格納する構造体の定義、定義した構造体を使って点のデータを作成、そして利用する頂点がどのような情報であるかをDirectXに伝えるための頂点レイアウトを作成します。

2行目から4行目にかけて、頂点データのための構造体を定義しています。ここでは、頂点データの内の座標を格納する変数を一つ定義しています。座標のみを格納するのであれば、わざわざ構造体で定義する必要がないのではと思われたかもしれませんが、今後座標以外のデータを持つ頂点も扱う予定なので構造体で定義しています。

7行目から9行目で数値を入力して描画する頂点データの作成を行っています。

​11行目以降で頂点レイアウトの定義を行っています。頂点レイアウトは、2行目から4行目で定義した構造体VERTEXの内部構成、ここでは3行目のメンバ「V」の正体が何なのかをDirectXに知らせるためのものです。"POSITION"は頂点の位置情報であることを示します。位置情報がどんなデータなのかを、DXGI_FORMAT_R32G32B32_FLOATで指定しています。意味は32BitのFloat型が3つから成ることを表しています。

② データバッファの作成
 DirectXとデータのやり取りを行うためのバッファの定義と作成を行います。D3D11_BUFFER_DESC構造体でバッファの定義を行い、D3D11_MAPPED_SUBRESOURCE構造体を使ってデータ情報の受け渡しを行います。

本プログラムで使われるデータバッファは以下の通り2つあります。

・定数バッファ … 点が回転するための行列を送るためのバッファ

・頂点バッファ … 頂点データを送るためのバッファ

​使用するデータ内容、バッファ内のリソースへのアクセス方法によってD3D11_BUFFER_DESC構造体の中身の設定値は異なります。以下にD3D11_BUFFER_DESC構造体の各メンバの種類の内容と、そこで使われる定数の意味の一覧を表にしました。中にはメンバ同士である特定の組み合わせでないといけないものがありますが、本ソースコードで使われている内容、値の意味については、以下を参照していただくと分かるかと思います。

○ UINT ByteWidth        バッファの大きさ(バイト単位)

○ D3D11_USAGE Usage       CPU、GPUからリソースへのアクセス方法を決める

  D3D11_USAGE_DEFAULT            : GPUによる読み書きが可能
  D3D11_USAGE_IMMUTABLE           : GPUによる読み込みのみ可能、CPUからはアクセス不可能
  D3D11_USAGE_DYNAMIC            : GPUからは読み取り専用。CPUからは書き込み専用。
  D3D11_USAGE_STAGING            : GPUからCPUへのデータ転送用リソース

○ UINT BindFlags        どのステージで利用されるのかバッファの種類を指定する
  D3D11_BIND_VERTEX_BUFFER          : 入力アセンブラで利用される頂点バッファ
  D3D11_BIND_INDEX_BUFFER          : 入力アセンブラで利用されるインデックスバッファ
  D3D11_BIND_CONSTANT_BUFFER         : シェーダで利用される定数バッファ
  D3D11_BIND_SHADER_RESOURCE         : シェーダで利用される汎用バッファまたはテクスチャバッファ
  D3D11_BIND_STREAM_OUTPUT          : ストリート出力からの出力バッファ
  D3D11_BIND_RENDER_TARGET          : 出力結合ステージのレンダーターゲットになるバッファ(テクスチャ)
  D3D11_BIND_DEPTH_STENCIL          : 出力結合ステージの深度ステンシルターゲットとなる

                         バッファ(テクスチャ)
  D3D11_BIND_UNORDERED_ACCESS        : アンオーダードアクセスリソース

○ UINT CPUAccessFlags      リソースで許可されるCPUからのアクセス種類。必要がない場合は0。
  D3D11_CPU_ACCESS_WRITE           : 書き込み可。但しD3D11_USAGEが動的使用または

                         ステージング使用であること
  D3D11_CPU_ACCESS_READ           : 読み込み可。

○ UINT MiscFlags        リソースに対するその他のオプション。必要がない場合は0。
  D3D11_RESOURCE_MISC_GENERATE_MIPS     : ミップマップ生成を有効にしたい場合
  D3D11_RESOURCE_MISC_SHARED         : 複数のDirect3Dデバイス間でのリソースデータ共有の有効化
  D3D11_RESOURCE_MISC_TEXTURECUBE      : キューブテクスチャをリソースにしたい場合
  D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS   : GPUで生成したコンテンツをインスタンス化
  D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS : バイト アドレス バッファーとしてリソースを有効
  D3D11_RESOURCE_MISC_BUFFER_STRUCTURED    : 構造化バッファーとしてリソースを有効
  D3D11_RESOURCE_MISC_RESOURCE_CLAMP     : クランプした深度バイアスを持つリソースを有効
  D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX    : 同期するように作成したリソースを有効
  D3D11_RESOURCE_MISC_GDI_COMPATIBLE     : GDI と互換性のあるリソースを有効</td>

○ UINT StructureByteStride   構造体が構造化バッファーを表す場合のその構造体のサイズ (バイト単位)

③ パイプラインの構築
 実際に描画を行う直前、最後の設定であるパイプラインの構築を行っていきます。といっても何か難しい特別な処理があるというわけではなく、ID3D11DeviceContextを使って必要なパラメータを指定してあげます。

これまの所で作成した頂点レイアウトやデータバッファ、流し込むデータを指定して、パイプラインを構築しています。特に5行目では、使用するデータの表現タイプによって異なるので注意が必要です。代表的なものは以下に書きました。その他の行での内容の説明も含めて大きな流れは次のようになります。


 3行目:頂点データをセット
 4行目:頂点レイアウトをセット

 5行目:入力される頂点データの種類を指定

      < 代表的なもの >

        ・D3D11_PRIMITIVE_TOPOLOGY_POINTLIST     … 入力される頂点データを点のリストとして解釈

        ・D3D11_PRIMITIVE_TOPOLOGY_LINELIST     … 入力される頂点データを線のリストとして解釈

        ・D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP     … 入力される頂点データを線ストリップとして解釈
        ・D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST   … 入力される頂点データを三角形のリストとして解釈
        ・D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP   … 入力される頂点データを三角ストリップとして解釈

 6行目:レンダーターゲットビューのセット
 7行目:ビューポートのセット
 8行目:頂点シェーダをセット

 9行目:ピクセルシェーダをセット

10行目:定数バッファをセット

​以上で、今回のパイプラインの構築が完了します。

サンプル​コード

< 動作確認環境 >
 ・Windows10 Pro
 ・Visual Studio Community 2017


基本的には空のプロジェクトを作ってもらい、以下のソースコードをコピペするだけでうまく実行できるかと思います。もしうまくいかない場合がありましたら、サンプルコードの実行に関する注意事項を一度参照してみてください。

​ソースコード

シェーダのソースコード (shader.hlsl ※必ずこの名前で保存してください)