■今回のプログラムの流れ
*準備段階
第2回のものに加え、以下の準備を行います。
- テクスチャの準備
- サンプラーオブジェクトの準備
また以下の修正を行います。
- 頂点データの修正
- TEXCOORDの追加
- シェーダーの変更
- 頂点入力レイアウトを変更
*メッセージループ
画面クリア処理の後、以下の設定を行います。
- バッファのセット
- 頂点バッファのセット
- 入力頂点の情報オブジェクトをセット
- シェーダーのセット
- テクスチャのセット
- サンプラーオブジェクトのセット
- 描画命令を発行
■テクスチャの準備
今回はD3DXの関数を使って楽にテクスチャを作成します。
[cpp]
ID3D11ShaderResourceView* pTextureSRV = 0;
hr = D3DX11CreateShaderResourceViewFromFile(
pd3dDevice, L”texture.dds”,
NULL, NULL, &pTextureSRV, NULL );
[/cpp]
シェーダーから使うテクスチャは ID3D11ShaderResourceViewとして表現されます。
D3DX11には便利な関数が用意されていて、D3DX11CreateShaderResourceViewFromFile というものを使うと、ファイル名を指定するとこのID3D11ShaderResourceViewを作成してくれます。
■サンプラーオブジェクトの準備
[cpp]
ID3D11SamplerState* pSamplerState = 0;
D3D11_SAMPLER_DESC descSamp;
ZeroMemory( &descSamp, sizeof(descSamp) );
descSamp.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
descSamp.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
descSamp.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
descSamp.MaxAnisotropy = 1;
descSamp.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
descSamp.ComparisonFunc = D3D11_COMPARISON_NEVER;
descSamp.MaxLOD = D3D11_FLOAT32_MAX;
pd3dDevice->CreateSamplerState( &descSamp, &pSamplerState );
[/cpp]
D3D11_SAMPLER_DESCの構造体に値を代入し、CreateSamperStateメソッドにてサンプラーオブジェクトを作成します。
■頂点バッファの修正
[cpp]
struct Vertex {
XMFLOAT3 Pos;
DWORD Color;
XMFLOAT2 Tex; // 追加!
};
// 頂点バッファの準備
D3D11_BUFFER_DESC descVB;
ZeroMemory( &descVB, sizeof(descVB) );
descVB.Usage = D3D11_USAGE_DEFAULT;
descVB.ByteWidth = sizeof(Vertex) * 4;
descVB.BindFlags = D3D11_BIND_VERTEX_BUFFER;
ID3D11Buffer* pVertexBuffer = 0;
/// 頂点”元”データ.
Vertex vbdata[] = {
XMFLOAT3(-0.5f, 0.5f, 0.0f ), 0xFFFFFFFF, XMFLOAT2(0.0f, 0.0f),
XMFLOAT3( 0.5f, 0.5f, 0.0f ), 0xFFFF0000, XMFLOAT2(1.0f, 0.0f),
XMFLOAT3(-0.5f,-0.5f, 0.0f ), 0xFF00FF00, XMFLOAT2(0.0f, 1.0f),
XMFLOAT3( 0.5f,-0.5f, 0.0f ), 0xFF0000FF, XMFLOAT2(1.0f, 1.0f),
};
[/cpp]
このような感じで、頂点データおよび頂点バッファの作成部分を修正します。
■シェーダーの修正
テクスチャを使うようにシェーダーファイルを修正します。
*頂点シェーダー
[cpp]
struct VS_INPUT {
float3 Pos : POSITION;
float4 Col : COLOR0;
float2 Tex0: TEXCOORD0;
};
struct VS_OUTPUT {
float4 Pos : SV_POSITION;
float4 Col : COLOR;
float2 Tex0: TEXCOORD0;
};
VS_OUTPUT mainVS( VS_INPUT _In ) {
VS_OUTPUT Out = (VS_OUTPUT)0;
Out.Pos = float4( _In.Pos, 1 );
Out.Col = _In.Col;
Out.Tex0 = _In.Tex0;
return Out;
}
[/cpp]
*ピクセルシェーダー
[cpp]
struct VS_OUTPUT {
float4 Pos : SV_POSITION;
float4 Col : COLOR;
float2 Tex0 : TEXCOORD0;
};
SamplerState gSampler : register(s0);
Texture2D gTexture : register(t0);
float4 mainPS( VS_OUTPUT _In ) : SV_TARGET
{
float4 diffuse = gTexture.Sample( gSampler, _In.Tex0 );
return _In.Col * diffuse;
}
[/cpp]
■頂点入力レイアウトの修正
TEXCOORDのセマンティクスが追加されているので、それにあうように修正します。
[cpp]
D3D11_INPUT_ELEMENT_DESC layout[] = {
“POSITION”, 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
“COLOR”, 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0,
“TEXCOORD”, 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0,
};
[/cpp]
■描画処理
シェーダーのセットしたあたりで、テクスチャとサンプラーオブジェクトをセットします。
[cpp]
// テクスチャとサンプラ設定.
pImmediateContext->PSSetShaderResources( 0, 1, &pTextureSRV );
pImmediateContext->PSSetSamplers( 0, 1, &pSamplerState );
// 描画
pImmediateContext->Draw( 4, 0 );
[/cpp]
■感想
DirectX10のサンプルを書いていたときには、テクスチャの作成がもう少し手間でした。
一旦ID3D10Texture2D作って、そこからシェーダーリソースビューを作っていました。
今回は、D3DXのAPIの中に便利なものがあったのでそれを使ってみました。1行でシェーダーリソースビューが取得できてしまうので便利です。
とはいえ、DirectX9のときには、D3DXCreateTextureFromFileが使えたので、それと同じことだったりします。