DXUT源碼分析 ---- 類CDXUTMesh(5)
最后一類是渲染函數,類CDXUTMesh重載了兩個渲染函數Render(),其作用都是用來渲染當前的網格模型。所不同的是,第一個函數用在固定函數流水線中,第二個函數用在可編程流水線技術中,這兩個函數的最后兩個參數用于指定是否渲染網格模型中的不透明和半透明部分。
首先來看第一個Render()函數:
HRESULT CDXUTMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets, bool bDrawAlphaSubsets )
{
if( NULL == m_pMesh )
return E_FAIL;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
}
m_pMesh->DrawSubset( i );
}
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets && m_bUseMaterials )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
// Set the material and texture
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
m_pMesh->DrawSubset( i );
}
}
return S_OK;
}
{
if( NULL == m_pMesh )
return E_FAIL;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
}
m_pMesh->DrawSubset( i );
}
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets && m_bUseMaterials )
{
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
// Set the material and texture
pd3dDevice->SetMaterial( &m_pMaterials[i] );
pd3dDevice->SetTexture( 0, m_pTextures[i] );
m_pMesh->DrawSubset( i );
}
}
return S_OK;
}
代碼簡潔明了,首先繪制不透明的網格(alpha == 1.0f),接著繪制半透明的網格(alpha != 1.0f)。
接著來看第二個Render()函數:
HRESULT CDXUTMesh::Render( ID3DXEffect *pEffect,
D3DXHANDLE hTexture, D3DXHANDLE hDiffuse, D3DXHANDLE hAmbient,
D3DXHANDLE hSpecular, D3DXHANDLE hEmissive, D3DXHANDLE hPower,
bool bDrawOpaqueSubsets, bool bDrawAlphaSubsets )
{
if( NULL == m_pMesh )
return E_FAIL;
UINT cPasses;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
return S_OK;
}
D3DXHANDLE hTexture, D3DXHANDLE hDiffuse, D3DXHANDLE hAmbient,
D3DXHANDLE hSpecular, D3DXHANDLE hEmissive, D3DXHANDLE hPower,
bool bDrawOpaqueSubsets, bool bDrawAlphaSubsets )
{
if( NULL == m_pMesh )
return E_FAIL;
UINT cPasses;
// Frist, draw the subsets without alpha
if( bDrawOpaqueSubsets )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a < 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
// Then, draw the subsets with alpha
if( bDrawAlphaSubsets )
{
pEffect->Begin( &cPasses, 0 );
for( UINT p = 0; p < cPasses; ++p )
{
pEffect->BeginPass( p );
for( DWORD i=0; i<m_dwNumMaterials; i++ )
{
if( m_bUseMaterials )
{
if( m_pMaterials[i].Diffuse.a == 1.0f )
continue;
if( hTexture )
pEffect->SetTexture( hTexture, m_pTextures[i] );
// D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
// No conversion is needed.
if( hDiffuse )
pEffect->SetVector( hDiffuse, (D3DXVECTOR4*)&m_pMaterials[i].Diffuse );
if( hAmbient )
pEffect->SetVector( hAmbient, (D3DXVECTOR4*)&m_pMaterials[i].Ambient );
if( hSpecular )
pEffect->SetVector( hSpecular, (D3DXVECTOR4*)&m_pMaterials[i].Specular );
if( hEmissive )
pEffect->SetVector( hEmissive, (D3DXVECTOR4*)&m_pMaterials[i].Emissive );
if( hPower )
pEffect->SetFloat( hPower, m_pMaterials[i].Power );
pEffect->CommitChanges();
}
m_pMesh->DrawSubset( i );
}
pEffect->EndPass();
}
pEffect->End();
}
return S_OK;
}
代碼也是相當簡潔明了,首先繪制不透明網格,接著繪制半透明網格。在繪制時遍歷所有的通道,并設置紋理,材質的漫反射光、環境光、鏡面反射光、自發光、鏡面反射光指數。