CDXUTMesh.docx

上传人:b****4 文档编号:4652020 上传时间:2023-05-07 格式:DOCX 页数:45 大小:33.07KB
下载 相关 举报
CDXUTMesh.docx_第1页
第1页 / 共45页
CDXUTMesh.docx_第2页
第2页 / 共45页
CDXUTMesh.docx_第3页
第3页 / 共45页
CDXUTMesh.docx_第4页
第4页 / 共45页
CDXUTMesh.docx_第5页
第5页 / 共45页
CDXUTMesh.docx_第6页
第6页 / 共45页
CDXUTMesh.docx_第7页
第7页 / 共45页
CDXUTMesh.docx_第8页
第8页 / 共45页
CDXUTMesh.docx_第9页
第9页 / 共45页
CDXUTMesh.docx_第10页
第10页 / 共45页
CDXUTMesh.docx_第11页
第11页 / 共45页
CDXUTMesh.docx_第12页
第12页 / 共45页
CDXUTMesh.docx_第13页
第13页 / 共45页
CDXUTMesh.docx_第14页
第14页 / 共45页
CDXUTMesh.docx_第15页
第15页 / 共45页
CDXUTMesh.docx_第16页
第16页 / 共45页
CDXUTMesh.docx_第17页
第17页 / 共45页
CDXUTMesh.docx_第18页
第18页 / 共45页
CDXUTMesh.docx_第19页
第19页 / 共45页
CDXUTMesh.docx_第20页
第20页 / 共45页
亲,该文档总共45页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

CDXUTMesh.docx

《CDXUTMesh.docx》由会员分享,可在线阅读,更多相关《CDXUTMesh.docx(45页珍藏版)》请在冰点文库上搜索。

CDXUTMesh.docx

CDXUTMesh

DXUT源码分析----类CDXUTMesh

(1)

类CDXUTMesh主要用于从一个指定的网格模型中加载数据、渲染模型以及销毁网格模型,它将整个网格模型作为一个整体进行操作,没有考虑网格模型内部的框架层次,对于不包含动画信息的网格模型,使用该类是一个比较好的选择。

这个类的定义和实现分别位于DXUTMesh.h和DXUTMesh.cpp中,其定义如下:

//-----------------------------------------------------------------------------

// Name:

 class CDXUTMesh

// Desc:

 Class for loading and rendering file-based meshes

//-----------------------------------------------------------------------------

class CDXUTMesh

{

public:

    WCHAR                            m_strName[512];

    LPD3DXMESH                        m_pMesh;   // Managed mesh

    

    // Cache of data in m_pMesh for easy access

    IDirect3DVertexBuffer9*            m_pVB;

    IDirect3DIndexBuffer9*            m_pIB;

    IDirect3DVertexDeclaration9*    m_pDecl;

    DWORD                           m_dwNumVertices;

    DWORD                           m_dwNumFaces;

    DWORD                           m_dwBytesPerVertex;

    DWORD                           m_dwNumMaterials; // Materials for the mesh

    D3DMATERIAL9*                   m_pMaterials;

    CHAR                            (*m_strMaterials)[MAX_PATH];

    IDirect3DBaseTexture9**         m_pTextures;

    bool                            m_bUseMaterials;

public:

    // Rendering

    HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice, 

                    bool bDrawOpaqueSubsets = true,

                    bool bDrawAlphaSubsets = true );

    HRESULT Render( ID3DXEffect *pEffect,

                    D3DXHANDLE hTexture = NULL,

                    D3DXHANDLE hDiffuse = NULL,

                    D3DXHANDLE hAmbient = NULL,

                    D3DXHANDLE hSpecular = NULL,

                    D3DXHANDLE hEmissive = NULL,

                    D3DXHANDLE hPower = NULL,

                    bool bDrawOpaqueSubsets = true,

                    bool bDrawAlphaSubsets = true );

    // Mesh access

    LPD3DXMESH GetMesh() { return m_pMesh; }

    // Rendering options

    void    UseMeshMaterials( bool bFlag ) { m_bUseMaterials = bFlag; }

    HRESULT SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF );

    HRESULT SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl, 

                           bool bAutoComputeNormals = true, bool bAutoComputeTangents = true, 

                           bool bSplitVertexForOptimalTangents = false );

    // Initializing

    HRESULT RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice );

    HRESULT InvalidateDeviceObjects();

    // Creation/destruction

    HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename );

    HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXFILEDATA pFileData );

    HRESULT Create(LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh, D3DXMATERIAL* pd3dxMaterials, DWORD dwMaterials);

    HRESULT CreateMaterials(LPCWSTR strPath, IDirect3DDevice9 *pd3dDevice, 

                            D3DXMATERIAL* d3dxMtrls, DWORD dwNumMaterials);

    HRESULT Destroy();

    CDXUTMesh( LPCWSTR strName = L"CDXUTMeshFile_Mesh" );

    virtual ~CDXUTMesh();

};

 

该类中包含的成员函数按其作用可分为6类。

第一类是构造和析构函数,函数CDXUTMesh()和~CDXUTMesh()分别是该类的构造函数和析构函数,其作用分别是进行一些初始化工作以及在类CDXUTMesh的对象被销毁时完成最后的销毁工作。

CDXUTMesh:

:

CDXUTMesh(LPCWSTRstrName)

{

StringCchCopy(m_strName,512,strName);

m_pMesh=NULL;

m_pMaterials=NULL;

m_pTextures=NULL;

m_bUseMaterials=TRUE;

m_pVB=NULL;

m_pIB=NULL;

m_pDecl=NULL;

m_strMaterials=NULL;

m_dwNumMaterials=0;

m_dwNumVertices=0;

m_dwNumFaces=0;

m_dwBytesPerVertex=0;

}

CDXUTMesh:

:

~CDXUTMesh()

{

Destroy();

}

第二类是获取网格函数,它仅包含一个函数GetMesh(),实现也非常简单,即返回类CDXUTMesh的成员变量m_pMesh。

LPD3DXMESHGetMesh(){returnm_pMesh;}

第三类是设备恢复和丢失时所采取的操作函数,这里所包含的两个成员函数RestoreDeviceObjects()和InvalidateDeviceObjects()分别是在设备恢复和丢失时调用,用于恢复和释放相应的资源。

HRESULTCDXUTMesh:

:

RestoreDeviceObjects(LPDIRECT3DDEVICE9pd3dDevice)

{

returnS_OK;

}

HRESULTCDXUTMesh:

:

InvalidateDeviceObjects()

{

SAFE_RELEASE(m_pIB);

SAFE_RELEASE(m_pVB);

SAFE_RELEASE(m_pDecl);

returnS_OK;

}

第四类是创建和销毁函数,这里首先重载了3个创建网格模型函数Create(),它们依次用于从指定的.x文件创建网格模型,从接口ID3DXFileData创建网格模型,从输入的网格模型中创建新的网格模型。

函数CreateMaterials()用于创建网格模型中所需的材质和纹理。

函数Destroy()用来在程序退出时销毁指定的资源。

来看第一个Create()函数的实现:

HRESULT CDXUTMesh:

:

Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename )

{

    WCHAR        strPath[MAX_PATH];

    LPD3DXBUFFER pAdjacencyBuffer = NULL;

    LPD3DXBUFFER pMtrlBuffer = NULL;

    HRESULT      hr;

    // Cleanup previous mesh if any

    Destroy();

    // Find the path for the file, and convert it to ANSI (for the D3DX API)

    DXUTFindDXSDKMediaFileCch( strPath, sizeof(strPath) / sizeof(WCHAR), strFilename );

    // Load the mesh

    if(FAILED(hr = D3DXLoadMeshFromXW(strPath, D3DXMESH_MANAGED, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL,

                                      &m_dwNumMaterials, &m_pMesh)))

    {

        return hr;

    }

    // Optimize the mesh for performance

    if( FAILED( hr = m_pMesh->OptimizeInplace(

                        D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,

                        (DWORD*) pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL)))

    {

        SAFE_RELEASE( pAdjacencyBuffer );

        SAFE_RELEASE( pMtrlBuffer );

        return hr;

    }

    // Set strPath to the path of the mesh file

    WCHAR* pLastBSlash = wcsrchr( strPath, L'\\' );

    if( pLastBSlash )

        *(pLastBSlash + 1) = L'\0';

    else

        *strPath = L'\0';

    D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*) pMtrlBuffer->GetBufferPointer();

    hr = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials );

    SAFE_RELEASE( pAdjacencyBuffer );

    SAFE_RELEASE( pMtrlBuffer );

    // Extract data from m_pMesh for easy access

    D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];

    m_dwNumVertices    = m_pMesh->GetNumVertices();

    m_dwNumFaces       = m_pMesh->GetNumFaces();

    m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex();

    m_pMesh->GetIndexBuffer( &m_pIB );

    m_pMesh->GetVertexBuffer( &m_pVB );

    m_pMesh->GetDeclaration( decl );

    pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );

    return hr;

}

 

函数首先销毁旧的资源,并调用DXUTFindDXSDKMediaFileCch()通过文件名查找文件所在的路径,接着调用D3DXLoadMeshFromXW()从文件中加载网格模型。

DXUTFindDXSDKMediaFileCch()的实现分析请参阅DXUT源码分析----媒体文件查找函数。

WCHARstrPath[MAX_PATH];

LPD3DXBUFFERpAdjacencyBuffer=NULL;

LPD3DXBUFFERpMtrlBuffer=NULL;

HRESULThr;

//Cleanuppreviousmeshifany

Destroy();

//Findthepathforthefile,andconvertittoANSI(fortheD3DXAPI)

DXUTFindDXSDKMediaFileCch(strPath,sizeof(strPath)/sizeof(WCHAR),strFilename);

//Loadthemesh

if(FAILED(hr=D3DXLoadMeshFromXW(strPath,D3DXMESH_MANAGED,pd3dDevice,&pAdjacencyBuffer,&pMtrlBuffer,NULL,

&m_dwNumMaterials,&m_pMesh)))

{

returnhr;

}

接着调用OptimizeInplace()对网格模型进行优化,该函数调用时第一个参数的含义如下:

D3DXMESHOPT_COMPACT—从mesh中移除没有用的顶点和索引项。

D3DXMESHOPT_ATTRSORT—根据属性给三角形排序并调整属性表,这将使DrawSubset执行更有效。

D3DXMESHOPT_VERTEXCACHE—增加顶点缓存的命中率。

//Optimizethemeshforperformance

if(FAILED(hr=m_pMesh->OptimizeInplace(

D3DXMESHOPT_COMPACT|D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_VERTEXCACHE,

(DWORD*)pAdjacencyBuffer->GetBufferPointer(),NULL,NULL,NULL)))

{

SAFE_RELEASE(pAdjacencyBuffer);

SAFE_RELEASE(pMtrlBuffer);

returnhr;

}

接下来,函数将模型文件所在的路径存储在strPath,如果没有路径,则strPath置为NULL。

//SetstrPathtothepathofthemeshfile

WCHAR*pLastBSlash=wcsrchr(strPath,L'\\');

if(pLastBSlash)

*(pLastBSlash+1)=L'\0';

else

*strPath=L'\0';

接下来,函数调用CreateMaterials()创建存储材质和纹理的内存,并释放邻接信息缓存和材质缓存。

D3DXMATERIAL*d3dxMtrls=(D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();

hr=CreateMaterials(strPath,pd3dDevice,d3dxMtrls,m_dwNumMaterials);

SAFE_RELEASE(pAdjacencyBuffer);

SAFE_RELEASE(pMtrlBuffer);

最后,函数获取模型的顶点数,面数,每个顶点所占的字节大小,顶点索引缓存,顶点缓存,顶点声明,以方便以后访问。

//Extractdatafromm_pMeshforeasyaccess

m_dwNumVertices=m_pMesh->GetNumVertices();

m_dwNumFaces=m_pMesh->GetNumFaces();

m_dwBytesPerVertex=m_pMesh->GetNumBytesPerVertex();

m_pMesh->GetIndexBuffer(&m_pIB);

m_pMesh->GetVertexBuffer(&m_pVB);

m_pMesh->GetDeclaration(decl);

pd3dDevice->CreateVertexDeclaration(decl,&m_pDecl);

returnhr;

DXUT源码分析----类CDXUTMesh

(2)

函数CreateMaterials()用于创建网格模型中所需的材质和纹理,我们来看看CreateMaterials()的实现:

HRESULT CDXUTMesh:

:

CreateMaterials( LPCWSTR strPath, IDirect3DDevice9 *pd3dDevice, 

                                    D3DXMATERIAL* d3dxMtrls, DWORD dwNumMaterials )

{

    // Get material info for the mesh, get the array of materials out of the buffer.

    m_dwNumMaterials = dwNumMaterials;

    if( d3dxMtrls && m_dwNumMaterials > 0 )

    {

        // Allocate memory for the materials and textures

        m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];

        if( m_pMaterials == NULL )

            return E_OUTOFMEMORY;

        m_pTextures = new LPDIRECT3DBASETEXTURE9[m_dwNumMaterials];

        if( m_pTextures == NULL )

            return E_OUTOFMEMORY;

        m_strMaterials = new CHAR[m_dwNumMaterials][MAX_PATH];

        if( m_strMaterials == NULL )

            return E_OUTOFMEMORY;

        // Copy each material and create its texture

        for( DWORD i=0; i

        {

            // Copy the material

            m_pMaterials[i]         = d3dxMtrls[i].MatD3D;

            m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;    // add by me

            m_pTextures[i]          = NULL;

            // Create a texture

            if( d3dxMtrls[i].pTextureFilename )

            {

                StringCchCopyA( m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename );

                WCHAR strTexture[MAX_PATH];

                WCHAR strTextureTemp[MAX_PATH];

                D3DXIMAGE_INFO ImgInfo;

                // First attempt to look for texture

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 公务员考试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2