天行健 君子当自强而不息

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

 

代码简洁明了,首先绘制不透明的网格(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;
}

 

代码也是相当简洁明了,首先绘制不透明网格,接着绘制半透明网格。在绘制时遍历所有的通道,并设置纹理,材质的漫反射光、环境光、镜面反射光、自发光、镜面反射光指数。

posted on 2008-05-31 11:36 lovedday 阅读(495) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论