新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → DXUT源码分析 ---- 类CDXUTMeshFrame 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 8395 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: DXUT源码分析 ---- 类CDXUTMeshFrame 举报  打印  转邮箱  推荐  站内收藏  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      院校:(无权查看)
      注册:2004/7/21
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 DXUT源码分析 ---- 类CDXUTMeshFrame
    类CDXUTMeshFrame封装了CDXUTMesh,与CDXUTMesh不同的是,类CDXUTMeshFrame可以包含框架层次结构,适用于更复杂的网格模型,框架层次正是骨骼动画所必须的。

    首先来看看它的定义:


    //-----------------------------------------------------------------------------
    // Name: class CDXUTMeshFrame
    // Desc: Class for loading and rendering file-based meshes
    //-----------------------------------------------------------------------------
    class CDXUTMeshFrame
    {
    public:
        WCHAR            m_strName[512];     // 框架名称
        D3DXMATRIX        m_mat;               // 框架变换矩阵(相对于网格模型的原点)
        CDXUTMesh*        m_pMesh;           // 指向CDXUTMesh对象

        CDXUTMeshFrame* m_pNext;         // 指向下一个框架对象
        CDXUTMeshFrame* m_pChild;         // 指向子框架对象

    public:
        // Matrix access
        void        SetMatrix( D3DXMATRIX* pmat ) { m_mat = *pmat; }
        D3DXMATRIX* GetMatrix()                   { return &m_mat; }

        CDXUTMesh*         FindMesh( LPCWSTR strMeshName );
        CDXUTMeshFrame*  FindFrame( LPCWSTR strFrameName );

        bool EnumMeshes( bool (*EnumMeshCB)(CDXUTMesh*, void*), void* pContext );

        HRESULT Destroy();
        HRESULT RestoreDeviceObjects(LPDIRECT3DDEVICE9 pd3dDevice);
        HRESULT InvalidateDeviceObjects();

        HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice,
                        bool bDrawOpaqueSubsets = true,
                        bool bDrawAlphaSubsets = true,
                        D3DXMATRIX* pmatWorldMatrix = NULL);

        CDXUTMeshFrame( LPCWSTR strName = L"CDXUTMeshFile_Frame" );
        virtual ~CDXUTMeshFrame();
    };

    构造函数和析构函数只是负责初始化数据和释放分配的资源:

    CDXUTMeshFrame::CDXUTMeshFrame( LPCWSTR strName ){    StringCchCopy(m_strName, 512, strName);
        D3DXMatrixIdentity(&m_mat);
        m_pMesh  = NULL;    m_pChild = NULL;    m_pNext  = NULL;}
    CDXUTMeshFrame::~CDXUTMeshFrame(){    SAFE_DELETE( m_pChild );    SAFE_DELETE( m_pNext );}

    FindMesh()和FindFrame()是两个递归查找函数,根据输入的网格名称和框架名称查找对应的网格和框架:

    CDXUTMesh* CDXUTMeshFrame::FindMesh( LPCWSTR strMeshName ){    CDXUTMesh* pMesh;
        if( m_pMesh )        if( !lstrcmpi(m_pMesh->m_strName, strMeshName) )            return m_pMesh;
        if( m_pChild )        if( NULL != ( pMesh = m_pChild->FindMesh(strMeshName) ) )            return pMesh;
        if( m_pNext )        if( NULL != ( pMesh = m_pNext->FindMesh(strMeshName) ) )            return pMesh;
        return NULL;}
    CDXUTMeshFrame* CDXUTMeshFrame::FindFrame( LPCWSTR strFrameName ){    CDXUTMeshFrame* pFrame;
        if( !lstrcmpi(m_strName, strFrameName) )        return this;
        if( m_pChild )        if( NULL != ( pFrame = m_pChild->FindFrame(strFrameName) ) )            return pFrame;
        if( m_pNext )        if( NULL != ( pFrame = m_pNext->FindFrame(strFrameName) ) )            return pFrame;
        return NULL;}

    lstrcmpi()在比较两个字符串时忽略大小写:

    The lstrcmpi function compares two character strings. The comparison is not case sensitive.
    To perform a comparison that is case sensitive, use the lstrcmp function.

    Syntax

    int lstrcmpi(          LPCTSTR lpString1,    LPCTSTR lpString2);
    Parameters

    lpString1
    [in] Pointer to the first null-terminated string to be compared.
    lpString2
    [in] Pointer to the second null-terminated string to be compared.
    Return Value

    If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. If the strings are equal, the return value is zero.

    Remarks

    The lstrcmpi function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

    Note that the lpString1 and lpString2 parameters must be null terminated, otherwise the string comparison can be incorrect.

    The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmpi determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

    The language (user locale) selected by the user at setup time, or through Control Panel, determines which string is greater (or whether the strings are the same). If no language (user locale) is selected, the system performs the comparison by using default values.

    For some locales, the lstrcmpi function may be insufficient. If this occurs, use CompareString to ensure proper comparison. For example, in Japan call with the NORM_IGNORECASE, NORM_IGNOREKANATYPE, and NORM_IGNOREWIDTH values to achieve the most appropriate non-exact string comparison. The NORM_IGNOREKANATYPE and NORM_IGNOREWIDTH values are ignored in non-Asian locales, so you can set these values for all locales and be guaranteed to have a culturally correct "insensitive" sorting regardless of the locale. Note that specifying these values slows performance, so use them only when necessary.

    With a double-byte character set (DBCS) version of the system, this function can compare two DBCS strings.

    The lstrcmpi function uses a word sort, rather than a string sort. A word sort treats hyphens and apostrophes differently than it treats other symbols that are not alphanumeric, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list. For a detailed discussion of word sorts and string sorts, see the Remarks section for the CompareString function.

    EnumMeshes()是一个递归枚举函数,对所有框架的所有网格递归调用传递进来的函数:

    bool CDXUTMeshFrame::EnumMeshes( bool (*EnumMeshCB)(CDXUTMesh*, void*), void* pContext ){    if( m_pMesh )        EnumMeshCB( m_pMesh, pContext );
        if( m_pChild )        m_pChild->EnumMeshes( EnumMeshCB, pContext );
        if( m_pNext )        m_pNext->EnumMeshes( EnumMeshCB, pContext );
        return TRUE;}

    Destroy()、RestoreDeviceObjects()、InvalidateDeviceObjects()分别当摧毁网格框架、设备恢复、设备丢失时调用,需要注意的是该类的析构函数并没有释放分配的资源,只是删除了链表指针,必须显式调用Destroy()来释放资源:

    HRESULT CDXUTMeshFrame::Destroy(){    if( m_pMesh )  m_pMesh->Destroy();    if( m_pChild ) m_pChild->Destroy();    if( m_pNext )  m_pNext->Destroy();
        SAFE_DELETE( m_pMesh );    SAFE_DELETE( m_pNext );    SAFE_DELETE( m_pChild );
        return S_OK;}
    HRESULT CDXUTMeshFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice ){    if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );    if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );    if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
        return S_OK;}
    HRESULT CDXUTMeshFrame::InvalidateDeviceObjects(){    if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();    if( m_pChild ) m_pChild->InvalidateDeviceObjects();    if( m_pNext )  m_pNext->InvalidateDeviceObjects();
        return S_OK;}

    Render()负责网格框架的绘制,它只是调用CDXUTMesh::Render()来负责网格的绘制,由于框架的层次包含关系,所以该函数也是一个递归函数。需要注意的是该函数包含的最后一个参数,它允许用户指定世界坐标变换矩阵,如果该参数为NULL,则从设备获取已设置好的世界坐标矩阵,注意如果是虚拟设备,必须设置该矩阵,不能为NULL。

    HRESULT CDXUTMeshFrame::Render( LPDIRECT3DDEVICE9 pd3dDevice,    bool bDrawOpaqueSubsets, bool bDrawAlphaSubsets,    D3DXMATRIX* pmatWorldMatrix ){    // For pure devices, specify the world transform.     // If the world transform is not specified on pure devices, this function will fail.
        D3DXMATRIX matSavedWorld, matWorld;
        if (NULL == pmatWorldMatrix)        pd3dDevice->GetTransform(D3DTS_WORLD, &matSavedWorld);    else        matSavedWorld = *pmatWorldMatrix;
        D3DXMatrixMultiply(&matWorld, &m_mat, &matSavedWorld);    pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
        if( m_pMesh )        m_pMesh->Render(pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets);
        if( m_pChild )        m_pChild->Render(pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld);
        pd3dDevice->SetTransform(D3DTS_WORLD, &matSavedWorld);
        if( m_pNext )        m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
        return S_OK;}
    代码中需要注意的一点是,调用Render()绘制兄弟框架时传递的世界坐标矩阵是matSavedWorld,而绘制子框架时传递的世界坐标矩阵是matWorld。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/26 10:51:00
      鲜花(0)  鸡蛋(0)        点击这里获取本站专享China-pub购书优惠券
     秋十三 帅哥哟,离线,有人找我吗?
      
      
      等级:大三(要不要学学XML呢?)
      文章:124
      积分:593
      门派:XML.ORG.CN
      院校:(无权查看)
      注册:2008/11/12
    给秋十三发送一个短消息 把秋十三加入好友 查看秋十三的个人资料 搜索秋十三在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看秋十三的博客2
    发贴心情 
    好!!!!!!!!!!
    我顶啊
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2009/1/2 20:30:00
            点击这里获取本站专享China-pub购书优惠券
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/23 2:16:50

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms