Nanashi-softプログラマ専用DirectX11開発


◇DirectX11プログラミング -三角形を表示するプログラム-

ビューポート設定の直後,メインループの直前に記述する
	//ポリゴン頂点構造体
struct Vertex3D {
float pos[3]; //x-y-z
float col[4]; //r-g-b-a
};

const int TYOUTEN = 3; //ポリゴンの頂点数

//頂点データ(三角ポリゴン1枚)
Vertex3D hVectorData[TYOUTEN] = {
{ { +0.0f, +0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { +0.5f, -0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -0.5f, -0.5f, +0.5f }, { 1.0f, 1.0f, 1.0f, 1.0f } }
};

//頂点レイアウト
//5番目のパラメータは先頭からのバイト数なので,COLORにはPOSITIONのfloat型4バイト×3を記述
D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};

//頂点バッファ作成
D3D11_BUFFER_DESC hBufferDesc;
hBufferDesc.ByteWidth = sizeof(Vertex3D) * TYOUTEN;
hBufferDesc.Usage = D3D11_USAGE_DEFAULT;
hBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
hBufferDesc.CPUAccessFlags = 0;
hBufferDesc.MiscFlags = 0;
hBufferDesc.StructureByteStride = sizeof(float);

D3D11_SUBRESOURCE_DATA hSubResourceData;
hSubResourceData.pSysMem = hVectorData;
hSubResourceData.SysMemPitch = 0;
hSubResourceData.SysMemSlicePitch = 0;

ID3D11Buffer* hpBuffer;
if(FAILED(hpDevice->CreateBuffer(&hBufferDesc, &hSubResourceData, &hpBuffer))){
MessageBox(hWnd, _T("CreateBuffer"), _T("Err"), MB_ICONSTOP);
goto End;
}

//その頂点バッファをコンテキストに設定
UINT hStrides = sizeof(Vertex3D);
UINT hOffsets = 0;
hpDeviceContext->IASetVertexBuffers(0, 1, &hpBuffer, &hStrides, &hOffsets);

//プリミティブ(ポリゴンの形状)をコンテキストに設定
hpDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

//頂点レイアウト作成
ID3D11InputLayout* hpInputLayout = NULL;
if(FAILED(hpDevice->CreateInputLayout(hInElementDesc, ARRAYSIZE(hInElementDesc), &g_vs_main, sizeof(g_vs_main), &hpInputLayout))){
MessageBox(hWnd, _T("CreateInputLayout"), _T("Err"), MB_ICONSTOP);
goto End;
}

//頂点レイアウトをコンテキストに設定
hpDeviceContext->IASetInputLayout(hpInputLayout);

//頂点シェーダー生成
ID3D11VertexShader* hpVertexShader;
if(FAILED(hpDevice->CreateVertexShader(&g_vs_main, sizeof(g_vs_main), NULL, &hpVertexShader))){
MessageBox(hWnd, _T("CreateVertexShader"), _T("Err"), MB_ICONSTOP);
goto End;
}

//頂点シェーダーをコンテキストに設定
hpDeviceContext->VSSetShader(hpVertexShader, NULL, 0);

//ピクセルシェーダー生成
ID3D11PixelShader* hpPixelShader;
if(FAILED(hpDevice->CreatePixelShader(&g_ps_main, sizeof(g_ps_main), NULL, &hpPixelShader))){
MessageBox(hWnd, _T("CreateVertexShader"), _T("Err"), MB_ICONSTOP);
goto End;
}

//ピクセルシェーダーをコンテキストに設定
hpDeviceContext->PSSetShader(hpPixelShader, NULL, 0);

//メインループ
MSG hMsg;
while(true){
while(PeekMessageW(&hMsg, NULL, 0, 0, PM_REMOVE)){
if(hMsg.message == WM_QUIT){
goto End;
}
TranslateMessage(&hMsg);
DispatchMessage(&hMsg);
}

//描画
hpDeviceContext->Draw(TYOUTEN, 0);

//バックバッファをスワップ
hpDXGISwpChain->Present(0, 0);
}
このプログラムは動きません(ぉ
頂点シェーダとピクセルシェーダは『別にプログラムを書く必要がある』為です

DirectX11では,シェーダープログラムを書かなければならなくなりました
シェーダーとは何か? ウィキってください(ぉ
いや,そこが一番よくわかるからです。DirectXでのバージョン遷移も解説されています
http://ja.wikipedia.org/wiki/シェーダ

シェーダーは HLSL言語で記述します。C言語ではありません
DirectX SDK付属の,fxc.exeでコンパイルします
前に書いたサンプルを動かす為の,何もしないシェーダーを書いてみます

・頂点シェーダー(HLSL)
//入力用
struct vertexIn
{
float4 pos : POSITION0;
float4 col : COLOR0;
};

//出力用
struct vertexOut
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};

vertexOut vs_main(vertexIn IN)
{
vertexOut OUT;

OUT.pos = IN.pos;
OUT.col = IN.col;

return OUT;
}
これを,vs.fxとして保存してください
ちなみに,VSは Vertex Shader(バーテックスシェーダー)の略です
なぜかこれだけ,頂点シェーダーと日本語化して呼ばれています(^^;

fxc.exeは,SDKフォルダを検索して下さい(ぉ
いやね。えらい下に隠されているのですよ。パスも普通通さないような場所に……

fxc.exe /?
でオプションのヘルプが出るので,MSDN見て下さい↓
http://msdn.microsoft.com/ja-jp/library/ee418538(v=vs.85).aspx
はい,専門用語しか無いので閉じて下さい(ぉ ←

コンパイルオプションを人間にわかるように書くと,↓こうなります
fxc.exe 「入力ファイル名」 /T 「シェーダーの種類」 /E 「関数名」 /Fh 「出力ファイル名」

シェーダーの種類は,定数で決まっています
上のMSDNマニュアルページのプロファイルに一覧があります
主なオプションを抜粋すると,

・頂点シェーダー
vs_4_0 (DirectX10)
vs_4_1 (DirectX10.1)
vs_5_0 (DirectX11)

・ピクセルシェーダー
ps_4_0 (DirectX10)
ps_4_1 (DirectX10.1)
ps_5_0 (DirectX11)

バージョンまで含んだ定数なので困るのですが(ビデオカードの対応バージョンの話なので),ここでは 4.0を使用します

サンプルの vs.fx(頂点シェーダー)をコンパイルするオプションは,
fxc.exe vs.fx /T vs_4_0 /E vs_main /Fh vs.h
になります


同様に何もしないピクセルシェーダーも作成します
struct pixcelIn
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};

float4 ps_main(pixcelIn IN) : SV_Target
{
pixcelIn OUT;

//カラーをそのまま返す
OUT.col = IN.col;

return OUT.col;
}
ps.fxで保存して,fxc.exeでコンパイルします
fxc.exe ps.fx /T ps_4_0 /E ps_main /Fh ps.h


そうすると,vs.hと ps.hの2つのヘッダーファイルが出来ます
これを,前回作成したサンプルにインクルードします
#include "vs.fx"
#include "ps.fx"

プロジェクトをビルドすると,三角形が表示される(はず)です



TOPプログラマ専用DirectX11開発