D3D10始めました -第3回 Texture使用-

今回はテクスチャを読み込んで表示させてみます。

■シェーダーファイル

まずはシェーダーのソースを示します。

従来のシェーダーと変わったところと言えば、ピクセルシェーダー内の
サンプラーおよびテクスチャのアクセス部分です。

対象とするテクスチャからのサンプルを、どのように行うか(サンプラ)、どの位置からとるか(UV)という意味のコードになっているように読み取れます。

struct VS_INPUT {
float3 Pos : POSITION;
float4 Col : COLOR0;
float2 Tex : TEXCOORD0;
};
struct VS_OUTPUT {
float4 Pos : SV_POSITION;
float4 Col : COLOR;
float2 Tex : TEXCOORD0;
};
VS_OUTPUT mainVS( VS_INPUT _In ) {
VS_OUTPUT Out = (VS_OUTPUT)0;
Out.Pos = float4( _In.Pos, 1 );
Out.Col = _In.Col;
Out.Tex = _In.Tex;
return Out;
}
SamplerState gSampler : register(s0);
Texture2D    gTexture : register(t0);
float4 mainPS( VS_OUTPUT _In ) : SV_TARGET {
return gTexture.Sample( gSampler, _In.Tex ) * _In.Col;
}

■入力レイアウトおよびデータの変更

テクスチャアクセス用にUVの設定が入りました。

vbdata[] = {
D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), 0xffffffff, D3DXVECTOR2(0.0f, 0.0f),
D3DXVECTOR3( 1.0f, 0.0f, 0.0f ), 0xffff0000, D3DXVECTOR2(1.0f, 0.0f),
D3DXVECTOR3( 0.0f,-1.0f, 0.0f ), 0xff00ff00, D3DXVECTOR2(0.0f, 1.0f),
};
D3D10_INPUT_ELEMENT_DESC layout[] = {
 "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0,
 "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0,
 "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0,
};
ID3D10InputLayout* pInputLayout = 0;
pDevice->CreateInputLayout(
  layout, 3,
  pBlobVS->GetBufferPointer(), pBlobVS->GetBufferSize(),
  &pInputLayout );

■テクスチャの準備

テクスチャは D3DX10CreateShaderResourceViewFromFile 関数を使い、
ビューを取得します。
このビューの中から対象となるテクスチャを取り出すことが出来ます。

  1. ファイルを元にシェーダーリソースビューを作成&取得
  2. リソース(ID3D10Resource)を取得
  3. リソースがTexture2DのデータならID3D10Texture2Dとしてそのリソースを使用できる。

という手順をたどる必要があります。

コードにすると次のようになります。

ID3D10ShaderResourceView* pTextureRV = 0;
D3DX10CreateShaderResourceViewFromFile( pDevice, L"texture.dds", NULL, NULL, &pTextureRV, &hr );
// テクスチャはリソースビューから取り出さないといけない.
ID3D10Resource* pResource = 0;
ID3D10Texture2D* pTexture = 0;
pTextureRV->GetResource( &pResource );
D3D10_RESOURCE_DIMENSION typeRes;
pResource->GetType( &typeRes );
if( typeRes == D3D10_RESOURCE_DIMENSION_TEXTURE2D ) {
  pTexture = static_cast( pResource );
}

■サンプラーの設定オブジェクト

テクスチャをシェーダーから扱うときにサンプラーを経由するため、
そのサンプラーの設定するためのオブジェクトを準備します。

基本的に設定を構造体に詰めて、生成関数を呼ぶだけなので簡単です。

// サンプラの準備
ID3D10SamplerState* pSamplerState = 0;
D3D10_SAMPLER_DESC descSamp;
descSamp.AddressU =  D3D10_TEXTURE_ADDRESS_CLAMP;
descSamp.AddressV =  D3D10_TEXTURE_ADDRESS_CLAMP;
descSamp.AddressW =  D3D10_TEXTURE_ADDRESS_CLAMP;
descSamp.MipLODBias = 0;
descSamp.MaxAnisotropy = 1;
descSamp.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
descSamp.ComparisonFunc = D3D10_COMPARISON_NEVER;
descSamp.BorderColor[0] = 1.0f;
descSamp.BorderColor[1] = 1.0f;
descSamp.BorderColor[2] = 1.0f;
descSamp.BorderColor[3] = 1.0f;
descSamp.MinLOD = 0;
descSamp.MaxLOD = D3D10_FLOAT32_MAX;

pDevice->CreateSamplerState( &descSamp, &pSamplerState );

■描画処理

シェーダー等をセットした後に、
サンプラーオブジェクトとテクスチャのビューをデバイスに設定します。

// テクスチャのセット
pDevice->PSSetShaderResources( 0, 1, &pTextureRV );
// サンプラーのセット
pDevice->PSSetSamplers( 0, 1, &pSamplerState );

■まとめ

デバイス生成時にデバッグフラグをつけていると
デバイスへの設定情報が怪しいときにいろいろなメッセージを出してくれます。
今回のことでもサンプラー設定デフォルトでいいやと判断して、
設定を怠ったところ、警告メッセージが大量に出てきました。

以前のコードではリソースを解放するコードを書いておらず、
内部的にはリソースリークが発生している状況でした。
使ったデータはきちんと解放しましょう。

次回くらいには、DirectX10でのリソースリーク検知について書いてみようと思います。

■ソースコード

今回作成した分のソースコードです。
HelloDX10_3.cpp のダウンロード

このバージョンからリソースはきちんと解放しています。

DirectX
すらりんをフォローする
すらりん日記

コメント

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