(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();
}
第三,使用 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 );
}
获取效果变量中的状态的两种方法
有两种方法可以获取效果变量中包含的状态。 给定已加载到内存中的效果。
一种方法是从已强制转换为采样器 接口的 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) 。
相关主题