こんにちは、エンジニアのオオバです。

WebGLでもやりましたが、DirectXで三角形を描画してみます。

生のWebGLで三角形を描画するショートコード - 渋谷ほととぎす通信

描画するウィンドウの生成や、GPUを使用するまでの手順は、こちらにまとめました。

上記の内容を踏まえて三角形1個を描画してみます。

WebGLの時にもありましたが、三角形を描画するために頂点バッファシェーダーシェーダーに渡すデータの紐づけ的なものがDirectXでも必要になってきます。

頂点バッファ

頂点バッファの作成にはSlimDX.Direct3D11.Bufferクラスを使います。
頂点バッファはその名の通り、各頂点データのことで、座標やカラー法線ベクトルなどを保持します。今回は頂点のみ使用します。

Bufferを生成するためにはDeviceDataStreamBufferDescriptionを渡します。
この中で新たに登場したDataStreamBufferDescription

DataStream

コンストラクタの引数で頂点の配列を渡していることから、頂点バッファをを生成するためのデータ本体が格納されいているようです。また、読み取り書き込みの設定もできるクラスです。

BufferDescription

~~Descriptionというのがちょいちょい出てきますが、これは頂点バッファの情報をセットしたデータです。
バッファのサイズ、バッファの種類をセットします。

バインドするバッファの種類はWebGLと近しいにおいがして懐かしいです。

頂点バッファ生成部分コード · GitHub

シェーダー

次にシェーダーです。
WebGlだとGLSLを直接HTMLに書いたりしますが、DirectXではHLSLで書いていきます。
.fxという拡張子を使うようです。

先にシェーダーのコードから。
myEffect.fx · GitHub

GLSL民から見ると見慣れないコードtechique10を調べてみます。

Effect Technique Syntax (Direct3D 10) - Win32 apps | Microsoft Docs

公式リファレンスをのぞいてみると、シェーダー内の設定を行うシンタックスだということがわかります。
頂点シェーダー、ピクセルシェーダー、ブレンド、ステンシルのステートを定義するものだという風に理解しました。

上記のコードでは、MyVertexShaderMyPixelShaderという関数がシェーダーの関数だということを定義しています。

また、シェーダーファイルはあくまでテキストデータなので、コンパイルする必要があります。

シェーダーを外部ファイルとして定義しているので、ShaderBytecode.CompileFromFileメソッドでコンパイルします。

該当コードはこちら
シェーダーのコンパイル部分コード · GitHub

シェーダーに渡すデータの紐づけ的なもの

頂点バッファに含めるデータは、位置、色、UV座標など様々ですが、これらはただの数値の塊で、GPUがどう解釈してよいかはわかりません。
それを解決するのがInputLayoutです。

渡されたデータの中のxx~yyバイトまでは位置情報‘という感じになっているようです。

inputlayout.cs · GitHub

InputLayoutを作成するにあたって、Device、ShaderSignature、InputElement配列が必要です。
この中で初登場かつ、よくわからないものはShaderSignatureなのですが、これはコードから察するにシェーダー内のパス情報ということになります。

InputElementは各頂点の定義情報ということになります。

これらの情報をもとに、GPUが解釈する方法を決めているということなのでしょう。

ビューポートの設定

前回は背景を塗りつぶすだけだったので不要でしたが、今回は描画する範囲ビューポートの設定が別途必要になってきます。

ビューポート設定部分コード · GitHub

次にループ時に行う描画処理について実装していきます。

三角形描画部分コード · GitHub

C#でDirectX11 SlimDXで三角形を描画する_0

実行するとこのように三角形が1つ佇みます。

全体コードはコチラ
SimpleTriangle.cs · GitHub

→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら

まとめ

だいぶコードが長くなってきましたが、WebGLを生で書いて三角形を描画した時と、やってることはそう変わらない感じで親近感が持てました。

リスペクト

オススメ記事
検証環境