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