C++言語でDirectX 11を使ったアプリケーションを開発してみよう。
DirectX 11ではシェーダーの利用が必須です。
簡単な図形を出すにもシェーダーを使わなければなりません。
シェーダーはHLSLという言語で記述する必要があり、さらにそれをコンパイルして使います。アプリ実行時に毎回コンパイルして使うという方法もありますが、事前にコンパイルしたものを使うのが一般的だと思います。
ここでは、HLSL言語で簡単なシェーダーを記述して、コンパイルする方法をまとめてみます。
頂点シェーダーを作る
すごく単純な頂点シェーダーを作ってみます。
入力された座標と色データをそのまま出力するだけのシェーダーです。
(本来ならここでワールド・ビュー・プロジェクションといった座標変換などを行なったりしますが、
ここではシンプルに何もしません)
以下はHLSL言語で記述した頂点シェーダーです。
(ファイル名は「vs_test.vsh」としてみました)
vs_test.vsh
struct VS_IN { float4 pos : POSITION0; float4 col : COLOR0; }; struct VS_OUT { float4 pos : SV_POSITION; float4 col : COLOR0; }; VS_OUT vs_main( VS_IN input ) { VS_OUT output; output.pos = input.pos; output.col = input.col; return output; }
「VS_IN」と「VS_OUT」という2つの構造体を定義しています。
それぞれ入力用のものと出力用のものです。
「vs_main」というのがシェーダーの実態となる関数です。
座標と色というデータを受け取り、それをそのまま吐き出しています。
ピクセルシェーダーを作る
すごく単純なピクセルシェーダーも作ってみます。
入力された座標と色データから色をそのまま出力するだけのシェーダーです。
(本来ならここでライトの当たり方によって色を変えたりなどの計算をしたりしますが、
ここではシンプルに何もしません)
以下はHLSL言語で記述したピクセルシェーダーです。
(ファイル名は「ps_test.psh」としてみました)
ps_test.psh
struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR0; }; float4 ps_main( PS_IN input ) : SV_Target { return input.col; }
「PS_IN」という入力用の構造体を定義しています。
頂点シェーダーの出力と同じ構造です。
「ps_main」というのがシェーダーの実態となる関数です。
座標と色というデータを受け取り、その色データをそのまま吐き出しています。
fxc.exeでコンパイルする
まずはコンパイラの実行ファイル「fxc.exe」を見つけましょう。
Visual Studioを使っている人は [C:\Program Files (x86)\Windows Kits\8.1\bin\x86] 辺りにあると思います。
コマンドプロンプトなどから実行します。
使い方は [fxc.exe <options> <files>] のようになっています。
fxc.exeの代表的なオプション
/?
各オプションの説明など使い方を表示してくれます。
/T <profile>
ターゲットプロファイルを指定します。
指定できるプロファイルは「/?」オプションで確認できますが、シェーダーの種類とバージョンの組み合わせになっています。
例)vs_5_0 vs_4_1 vs_4_0 ps_5_0 ps_4_1 ps_4_0 など
/E <name>
シェーダーの関数名を指定します
/Fh <file>
出力ファイル名を指定します
コンパイル後のオブジェクトコードを含むヘッダーファイルが作成されます。
fxc.exeでコンパイルする
上記で作ったシェーダーのファイルを下記のような感じでコンパイルします。
>fxc.exe /T vs_5_0 /E vs_main /Fh vs_test.h vs_test.vsh
>fxc.exe /T ps_5_0 /E ps_main /Fh ps_test.h ps_test.psh
コンパイルが成功すると「vs_test.h」と「ps_test.h」ファイルが出来上がります。
コンパイル後のファイルをソースに組み込む
上記のように「/Fh」オプションを使うとヘッダーファイルが出来上がります。
中身を見てみると関数名の先頭に[g_]がついた変数が確認できます。
コンパイル後のオブジェクトコードがバイト配列で定義されています。
const BYTE g_vs_main[] = { 68, 88, 66, 67, 71, 193, 40, 109, 81, 69, 118, 230, 196, 192, 21, 90, 167, 179, 135, 40, 1, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0, 0, 0, 252, 0, 0, 0, 80, 1, 0, 0, 196, 1, 0, 0, 82, 68, : :
出来上がったヘッダーファイルはインクルードして使います。
#include "vs_test.h" #include "ps_test.h"
- ~プログラミング~ DirectX 11を始めよう
- ~プログラミング~ DirectX 11はDirectX 9と何が違うか その1
- ~プログラミング~ DirectX 11はDirectX 9と何が違うか その2
- ~プログラミング~ DirectX 11の初期化をしよう その1
- ~プログラミング~ DirectX 11の初期化をしよう その2
- ~プログラミング~ DirectX 11で深度/ステンシルバッファを準備しよう
- ~プログラミング~ DirectX 11でシェーダーをコンパイルしよう
- ~プログラミング~ DirectX 11で三角形を表示しよう
- ~プログラミング~ DirectX 11の頂点バッファとインデックスバッファ
- ~プログラミング~ DirectX 11で立体を表示しよう その1
- ~プログラミング~ DirectX 11で立体を表示しよう その2
- ~プログラミング~ DirectX 11で平行光源ライティング
- ~プログラミング~ DirectX 11で点光源ライティング
- ~プログラミング~ DirectX 11で拡散反射 (Diffuse reflection)
- ~プログラミング~ DirectX 11で鏡面反射 (Specular reflection)
- ~プログラミング~ DirectX 11でフォン反射モデル
- ~プログラミング~ DirectXTexライブラリを導入しよう
- ~プログラミング~ DirectX 11でテクスチャマッピング
コメントをお書きください