Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Vissa effektkonstanter behöver bara initieras. När initieringen har initierats anges effekttillståndet till enheten för hela återgivningsloopen. Andra variabler måste uppdateras varje gång återgivningsloopen anropas. Den grundläggande koden för att ange effektvariabler visas nedan för var och en av typerna av variabler.
En effekt kapslar in allt återgivningstillstånd som krävs för att göra ett återgivningspass. När det gäller API:et finns det tre typer av tillstånd inkapslade i en effekt.
Konstant tillstånd
Deklarera först variabler i en effekt med hjälp av HLSL-datatyper.
//--------------------------------------------------------------------------------------
// 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
För det andra deklarerar du variabler i programmet som kan anges av programmet och uppdaterar sedan effektvariablerna.
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();
}
För det tredje använder du uppdateringsmetoderna för att ange värdet för variablerna i programmet i effektvariablerna.
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 );
}
Två sätt att hämta tillståndet i en effektvariabel
Det finns två sätt att hämta tillståndet i en effektvariabel. Med tanke på en effekt som har lästs in i minnet.
Ett sätt är att hämta sampler-tillståndet från ett ID3D10EffectVariable Interface som har castats som ett sampler-gränssnitt.
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 );
}
Det andra sättet är att hämta sampler-tillståndet från ett ID3D10SamplerState Interface.
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 );
}
}
Skuggningstillstånd
Skuggningstillstånd deklareras och tilldelas i en effektteknik inom ett pass.
technique10 RenderSceneWithTexture1Light
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
}
}
Detta fungerar precis som om du inte använder en effekt. Det finns tre anrop, ett för varje typ av skuggning (hörn, geometri och pixel). Den första, SetVertexShader, anropar ID3D10Enhet::VSSetShader. CompileShader är en specialeffektfunktion som tar skuggningsprofilen (vs_4_0) och namnet på funktionen hörnskuggning (RenderVS). Med andra ord kompilerar var och en av dessa SetXXXShader-anrop sin associerade skuggningsfunktion och returnerar en pekare till den kompilerade skuggningen.
Strukturtillstånd
Strukturtillståndet är lite mer komplext än att ange en variabel, eftersom texturdata inte bara läss som en variabel, utan samplas från en struktur. Därför måste du definiera texturvariabeln (precis som en normal variabel förutom att den använder en texturtyp) och du måste definiera samplingsvillkoren. Här är ett exempel på en strukturvariabeldeklaration och motsvarande samplingstillståndsdeklaration.
Texture2D g_MeshTexture; // Color texture for mesh
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
Här är ett exempel på hur du ställer in en struktur från ett program. I det här exemplet lagras strukturen i nätdata som lästes in när effekten skapades.
Det första steget är att få en pekare till strukturen från effekten (från nätet).
ID3D10EffectShaderResourceVariable* g_ptxDiffuse = NULL;
// Obtain variables
g_ptxDiffuse = g_pEffect10->GetVariableByName( "g_MeshTexture" )->AsShaderResource();
Det andra steget är att ange en vy för åtkomst till strukturen. Vyn definierar ett allmänt sätt att komma åt data från strukturresursen.
OnD3D10FrameRender()
{
ID3D10ShaderResourceView* pDiffuseRV = NULL;
...
pDiffuseRV = g_Mesh10.GetMaterial(pSubset->MaterialID)->pDiffuseRV10;
g_ptxDiffuse->SetResource( pDiffuseRV );
...
}
Mer information om hur du visar resurser finns i Texturvyer (Direct3D 10).
Relaterade ämnen