DirectX11始めました -第3回-

今回はプログラムを修正して4角形にしたうえで、テクスチャを貼ってみます。

■今回のプログラムの流れ

*準備段階

第2回のものに加え、以下の準備を行います。

  1. テクスチャの準備
  2. サンプラーオブジェクトの準備

また以下の修正を行います。

  1. 頂点データの修正
    1. TEXCOORDの追加
  2. シェーダーの変更
  3. 頂点入力レイアウトを変更

*メッセージループ

画面クリア処理の後、以下の設定を行います。

  1. バッファのセット
    1. 頂点バッファのセット
    2. 入力頂点の情報オブジェクトをセット
  2. シェーダーのセット
  3. テクスチャのセット
  4. サンプラーオブジェクトのセット
  5. 描画命令を発行

■テクスチャの準備

今回は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が使えたので、それと同じことだったりします。

HelloDX11_3 ソースコード

DirectX プログラミング
すらりんをフォローする
すらりん日記

コメント

タイトルとURLをコピーしました