Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Niektóre stałe efektu muszą być inicjowane tylko. Po zainicjowaniu stan efektu jest ustawiony na urządzenie dla całej pętli renderowania. Inne zmienne muszą być aktualizowane za każdym razem, gdy jest wywoływana pętla renderowania. Poniżej przedstawiono podstawowy kod ustawiania zmiennych efektów dla każdego z typów zmiennych.
Efekt hermetyzuje cały stan renderowania wymagany do wykonania przekazywania renderowania. Jeśli chodzi o interfejs API, istnieją trzy typy hermetyzowanego stanu w efekcie.
Stan stałej
Najpierw zadeklaruj zmienne w efekcie przy użyciu typów danych 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
Po drugie, zadeklaruj zmienne w aplikacji, które można ustawić przez aplikację, a następnie zaktualizuje zmienne efektu.
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();
}
Po trzecie, użyj metod aktualizacji, aby ustawić wartość zmiennych w aplikacji w zmiennych efektowych.
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 );
}
Dwa sposoby uzyskiwania stanu w zmiennej efektu
Istnieją dwa sposoby uzyskania stanu zawartego w zmiennej efektu. Biorąc pod uwagę efekt, który został załadowany do pamięci.
Jednym ze sposobów jest pobranie stanu próbkatora z ID3D10EffectVariable Interface, który został rzutowany jako interfejs próbkatora.
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 );
}
Innym sposobem jest pobranie stanu próbkatora z interfejsu 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 );
}
}
Stan cieniowania
Stan cieniowania jest deklarowany i przypisywany w technice efektu w ramach przebiegu.
technique10 RenderSceneWithTexture1Light
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
}
}
To działa tak, jakby nie używało efektu. Istnieją trzy wywołania, po jednym dla każdego typu cieniowania (wierzchołka, geometria i piksel). Pierwszy z nich, SetVertexShader, wywołuje ID3D10Device::VSSetShader. CompileShader to funkcja specjalna, która przyjmuje profil cieniowania (vs_4_0) i nazwę funkcji cieniowania wierzchołków (RenderVS). Innymi słowy, każdy z tych wywołań SetXXXShader kompiluje powiązaną funkcję cieniowania i zwraca wskaźnik do skompilowanego cieniowania.
Stan tekstury
Stan tekstury jest nieco bardziej złożony niż ustawienie zmiennej, ponieważ dane tekstury nie są po prostu odczytywane jak zmienna, są próbkowane z tekstury. W związku z tym należy zdefiniować zmienną tekstury (podobnie jak zmienna normalna, z wyjątkiem typu tekstury) i zdefiniować warunki próbkowania. Oto przykład deklaracji zmiennej tekstury i odpowiadającej deklaracji stanu próbkowania.
Texture2D g_MeshTexture; // Color texture for mesh
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Oto przykład ustawiania tekstury z aplikacji. W tym przykładzie tekstura jest przechowywana w danych siatki, które zostały załadowane podczas tworzenia efektu.
Pierwszym krokiem jest uzyskanie wskaźnika do tekstury z efektu (z siatki).
ID3D10EffectShaderResourceVariable* g_ptxDiffuse = NULL;
// Obtain variables
g_ptxDiffuse = g_pEffect10->GetVariableByName( "g_MeshTexture" )->AsShaderResource();
Drugi krok określa widok umożliwiający uzyskanie dostępu do tekstury. Widok definiuje ogólny sposób uzyskiwania dostępu do danych z zasobu tekstury.
OnD3D10FrameRender()
{
ID3D10ShaderResourceView* pDiffuseRV = NULL;
...
pDiffuseRV = g_Mesh10.GetMaterial(pSubset->MaterialID)->pDiffuseRV10;
g_ptxDiffuse->SetResource( pDiffuseRV );
...
}
Aby uzyskać więcej informacji na temat wyświetlania zasobów, zobacz Widoki tekstur (Direct3D 10).
Tematy pokrewne