共用方式為


設定效果狀態 (Direct3D 10)

某些效果常數只需要初始化。 初始化之後,效果狀態會設定為整個轉譯迴圈的裝置。 每次呼叫轉譯迴圈時,都必須更新其他變數。 設定效果變數的基本程式碼如下所示,適用于每個變數類型。

效果會封裝執行轉譯階段所需的所有轉譯狀態。 就 API 而言,效果中封裝了三種類型的狀態。

常數狀態

首先,使用 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();
}

第三,使用更新方法,在效果變數中設定應用程式中變數的值。

           
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 );
}

取得效果變數中狀態的兩種方式

有兩種方式可取得效果變數中包含的狀態。 假設已載入記憶體的效果。

其中一種方式是從已轉換成取樣器 介面的 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 );
}

另一種方式是從 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 ) ) );
    }
}

這就像您未使用效果一樣。 每個著色器類型都有三個呼叫, (頂點、幾何和圖元) 。 第一個是 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();

第二個步驟是指定用來存取紋理的檢視。 檢視會定義從紋理資源存取資料的一般方式。

   
OnD3D10FrameRender()
{
  ID3D10ShaderResourceView* pDiffuseRV = NULL;

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

如需檢視資源的詳細資訊,請參閱 紋理檢視 (Direct3D 10)

轉譯效果 (Direct3D 10)