効果の状態の設定 (Direct3D 10)

一部の効果定数は初期化する必要があります。 初期化されると、効果の状態は、レンダー ループ全体のデバイスに設定されます。 他の変数は、レンダー ループが呼び出されるたびに更新する必要があります。 各種類の変数について、効果変数を設定するための基本的なコードを次に示します。

効果は、レンダリング パスを実行するために必要なすべてのレンダリング状態をカプセル化します。 API の観点からは、3 種類の状態が効果にカプセル化されています。

定数の状態

まず、HLSL データ型を使用して、効果で変数を宣言します。

//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_MaterialAmbientColor;      // Material's ambient color
float4 g_MaterialDiffuseColor;      // Material's diffuse color
int g_nNumLights;

float3 g_LightDir[3];               // Light's direction in world space
float4 g_LightDiffuse[3];           // Light's diffuse color
float4 g_LightAmbient;              // Light's ambient color

Texture2D g_MeshTexture;            // Color texture for mesh

float    g_fTime;                   // App's time in seconds
float4x4 g_mWorld;                  // World matrix for object
float4x4 g_mWorldViewProjection;    // World * View * Projection matrix

次に、アプリケーションで設定できる変数をアプリケーションで宣言し、効果変数を更新します。

           
    D3DXMATRIX  mWorldViewProjection;
    D3DXVECTOR3 vLightDir[MAX_LIGHTS];
    D3DXVECTOR4 vLightDiffuse[MAX_LIGHTS];
    D3DXMATRIX  mWorld;
    D3DXMATRIX  mView;
    D3DXMATRIX  mProj;

    // Get the projection and view matrix from the camera class
    mWorld = g_mCenterMesh * *g_Camera.GetWorldMatrix();
    mProj = *g_Camera.GetProjMatrix();
    mView = *g_Camera.GetViewMatrix();

    
OnD3D10CreateDevice()
{
  ...
    g_pLightDir = g_pEffect10->GetVariableByName( "g_LightDir" )->AsVector();
    g_pLightDiffuse = g_pEffect10->GetVariableByName( "g_LightDiffuse" )->AsVector();
    g_pmWorldViewProjection = g_pEffect10->GetVariableByName( 
        "g_mWorldViewProjection" )->AsMatrix();
    g_pmWorld = g_pEffect10->GetVariableByName( "g_mWorld" )->AsMatrix();
    g_pfTime = g_pEffect10->GetVariableByName( "g_fTime" )->AsScalar();
    g_pMaterialAmbientColor = g_pEffect10->GetVariableByName("g_MaterialAmbientColor")->AsVector();
    g_pMaterialDiffuseColor = g_pEffect10->GetVariableByName( 
        "g_MaterialDiffuseColor" )->AsVector();
    g_pnNumLights = g_pEffect10->GetVariableByName( "g_nNumLights" )->AsScalar();
}

3 つ目は、update メソッドを使用して、エフェクト変数内のアプリケーション内の変数の値を設定します。

           
OnD3D10FrameRender()
{
    ...
    g_pLightDir->SetRawValue( vLightDir, 0, sizeof(D3DXVECTOR3)*MAX_LIGHTS );
    g_pLightDiffuse->SetFloatVectorArray( (float*)vLightDiffuse, 0, MAX_LIGHTS );
    g_pmWorldViewProjection->SetMatrix( (float*)&mWorldViewProjection );
    g_pmWorld->SetMatrix( (float*)&mWorld );
    g_pfTime->SetFloat( (float)fTime );
    g_pnNumLights->SetInt( g_nNumActiveLights );
}

効果変数の状態を取得する 2 つの方法

効果変数に含まれる状態を取得するには、2 つの方法があります。 メモリに読み込まれた効果が与えられました。

1 つの方法は、サンプラー インターフェイスとしてキャストされた ID3D10EffectVariable インターフェイス からサンプラーの状態を取得することです。

D3D10_SAMPLER_DESC sampler_desc;
ID3D10EffectVariable* l_pD3D10EffectVariable = NULL;
if( g_pEffect10 )
{
    l_pD3D10EffectVariable = g_pEffect10->GetVariableByName( "MeshTextureSampler" );
    if( l_pD3D10EffectVariable )
        hr = (l_pD3D10EffectVariable->AsSampler())->GetBackingStore( 0, 
            &sampler_desc );
}

もう 1 つの方法は、 ID3D10SamplerState インターフェイスからサンプラーの状態を取得することです。

ID3D10SamplerState* l_ppSamplerState = NULL;
D3D10_SAMPLER_DESC sampler_desc;
ID3D10EffectVariable* l_pD3D10EffectVariable = NULL;
if( g_pEffect10 )
{
    l_pD3D10EffectVariable = g_pEffect10->GetVariableByName( "MeshTextureSampler" );
    if( l_pD3D10EffectVariable )
    {
        hr = (l_pD3D10EffectVariable->AsSampler())->GetSampler( 0, 
            &l_ppSamplerState );
        if( l_ppSamplerState )
            l_ppSamplerState->GetDesc( &sampler_desc );
    }
}

シェーダーの状態

シェーダーの状態は、パス内でエフェクト手法で宣言され、割り当てられます。

technique10 RenderSceneWithTexture1Light
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
    }
}

これは、効果を使用していない場合と同じように機能します。 シェーダーの種類 (頂点、ジオメトリ、ピクセル) ごとに 1 つずつ、3 つの呼び出しがあります。 最初の SetVertexShader は ID3D10Device::VSSetShader を呼び出します。 CompileShader は、シェーダー プロファイル (vs_4_0) と頂点シェーダー関数 (RenderVS) の名前を受け取る特殊効果関数です。 つまり、これらの各 SetXXXShader 呼び出しは、関連付けられたシェーダー関数をコンパイルし、コンパイルされたシェーダーへのポインターを返します。

テクスチャの状態

テクスチャの状態は変数を設定するよりも少し複雑です。テクスチャ データは単に変数のように読み取られないため、テクスチャからサンプリングされます。 したがって、テクスチャ変数 (テクスチャ型を使用する以外は通常の変数と同様) を定義し、サンプリング条件を定義する必要があります。 テクスチャ変数宣言と対応するサンプリング状態宣言の例を次に示します。

Texture2D g_MeshTexture;            // Color texture for mesh

SamplerState MeshTextureSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

アプリケーションからテクスチャを設定する例を次に示します。 この例では、テクスチャは、効果の作成時に読み込まれたメッシュ データに格納されます。

最初の手順では、(メッシュから) 効果からテクスチャへのポインターを取得します。

ID3D10EffectShaderResourceVariable* g_ptxDiffuse = NULL;

    // Obtain variables
    g_ptxDiffuse = g_pEffect10->GetVariableByName( "g_MeshTexture" )->AsShaderResource();

2 番目の手順では、テクスチャにアクセスするためのビューを指定します。 ビューは、テクスチャ リソースからデータにアクセスするための一般的な方法を定義します。

   
OnD3D10FrameRender()
{
  ID3D10ShaderResourceView* pDiffuseRV = NULL;

   ...
   pDiffuseRV = g_Mesh10.GetMaterial(pSubset->MaterialID)->pDiffuseRV10;
   g_ptxDiffuse->SetResource( pDiffuseRV );
   ...
}   

リソースの表示の詳細については、「 テクスチャ ビュー (Direct3D 10)」を参照してください。

効果のレンダリング (Direct3D 10)