类CDXUTMeshFrame

本文详细介绍了CDXUTMeshFrame类的功能和实现细节,包括构造与析构过程、递归查找函数、资源管理及网格渲染等核心方法。特别关注了如何通过递归方式高效地管理和渲染复杂的网格结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

首先来看看它的定义:

//-----------------------------------------------------------------------------
// 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。

EnMAP-Box是一款高效、便捷的遥感图像处理软件,其独特之处在于它是一个免安装的应用程序,用户可以直接运行而无需进行复杂的安装过程。这款工具主要用于处理和分析来自各种遥感传感器的数据,如EnMAP(环境多波段光谱成像仪)和其他同设备获取的高光谱图像。EnMAP-Box的设计目标是为科研人员和实践工作者提供一个直观、易用的平台,以执行复杂的遥感数据处理任务。 在使用EnMAP-Box之前,一个关键的前提条件是需要有一个兼容的IDL(Interactive Data Language)环境。IDL是一种强大的编程语言,特别适用于科学数据的处理和可视化,尤其是在地球科学和遥感领域。它提供了丰富的库函数,支持对多维数组操作,这使得它成为处理遥感图像的理想选择。EnMAP-Box是基于IDL开发的,因此,用户在使用该软件之前需要确保已经正确配置了IDL环境。 EnMAP-Box的主要功能包括: 1. 数据导入:能够读取多种遥感数据格式,如ENVI、HDF、GeoTIFF等,方便用户将不同来源的遥感图像导入到软件中进行分析。 2. 预处理:提供辐射校正、大气校正、几何校正等功能,用于改善原始图像的质量,确保后续分析的准确性。 3. 分光分析:支持高光谱图像的光谱特征提取,如光谱指数计算、光谱端元分离等,有助于识别地物型和监测环境变化。 4. 图像分:通过监督或非监督方法进行图像分,可以自动或半自动地将图像像素划分为不同的地物别。 5. 时间序列分析:对于多时相遥感数据,EnMAP-Box能进行时间序列分析,揭示地表动态变化趋势。 6. 结果导出与可视化:处理后的结果可以导出为各种格式,同时软件内置了图像显示和地图投影功能,帮助用户直观地查看和理解处理结果。 7. 自定义脚本:利用IDL的强大功能,用户可以编写自定义脚本来实现特定的遥感处理需求,增强了软件的灵活性和可扩展性。 在使用EnMAP-Box的过程中,用户可能会遇到一些挑战,例如对IDL编程语言不熟悉,或者对遥感数据处理的基本概念和方法缺乏了解。这时,可以通过查阅软件自带的文档、教程,以及在线资源来提升技能。同时,积极参与相关的学习社区和论坛,与其他用户交流经验,可以帮助解决遇到的问题。 EnMAP-Box作为一款基于IDL的遥感图像处理工具,为遥感数据分析提供了便利,但需要用户具备一定的IDL基础和遥感知识。通过熟练掌握EnMAP-Box,用户可以高效地处理和解析遥感数据,揭示地表信息,为环境保护、资源管理等领域提供科学支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值