今回はテクスチャを読み込んで表示させてみます。
■シェーダーファイル
まずはシェーダーのソースを示します。
従来のシェーダーと変わったところと言えば、ピクセルシェーダー内の
サンプラーおよびテクスチャのアクセス部分です。
対象とするテクスチャからのサンプルを、どのように行うか(サンプラ)、どの位置からとるか(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 関数を使い、
ビューを取得します。
このビューの中から対象となるテクスチャを取り出すことが出来ます。
- ファイルを元にシェーダーリソースビューを作成&取得
- リソース(ID3D10Resource)を取得
- リソースが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でのリソースリーク検知について書いてみようと思います。
