青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

網格模型高級技術(13)

類cAnimMesh是最關鍵的一個類,所有與骨骼動畫相關的具體實現細節都封裝在該類中,該類還定義了類cAllocateHierarchy的一個對象m_alloc_hierarchy,該對象完成從文件中加載動畫網格模型的骨骼層次結構、動畫數據以及其他用于繪制模型的幾何數據。


類cAnimMesh的定義如下所示:

class cAnimMesh
{
private:
cAllocateHierarchy* m_alloc_hierarchy;
IDirect3DDevice9* m_device;
D3DXFRAME* m_root_frame;
public:
D3DXVECTOR3 m_object_center;
float m_object_radius;
bool m_is_play_anim;
ID3DXAnimationController* m_anim_controller;
private:
HRESULT load_from_xfile(CONST WCHAR* wfilename);
void update_frame_matrices(D3DXFRAME* base_frame, CONST D3DXMATRIX* parent_matrix);
void draw_frame(CONST D3DXFRAME* frame);
void draw_mesh_container(CONST D3DXMESHCONTAINER* base_mesh_container, CONST D3DXFRAME* base_frame);
public:
HRESULT create(IDirect3DDevice9* device, CONST WCHAR* wfilename);
void render(CONST D3DXMATRIX* mat_world, double app_elapsed_time);
void destroy();
public:
cAnimMesh();
virtual ~cAnimMesh();
};

 

構造函數負責分配資源和初始化成員變量,析構函數負責釋放資源:

cAnimMesh::cAnimMesh()
{
m_is_play_anim = true;
m_device = NULL;
m_anim_controller = NULL;
m_root_frame = NULL;
	m_alloc_hierarchy = new cAllocateHierarchy();
}
cAnimMesh::~cAnimMesh()
{
D3DXFrameDestroy(m_root_frame, m_alloc_hierarchy);
release_com(m_anim_controller);
	delete m_alloc_hierarchy;
}

 

函數load_from_xfile()的主要任務是調用函數D3DXLoadMeshHierarchyFromX()從.x文件中加載動畫模型,其實現如下:

HRESULT cAnimMesh::load_from_xfile(CONST WCHAR* wfilename)
{
HRESULT hr;
	WCHAR wpath[MAX_PATH];
DXUTFindDXSDKMediaFileCch(wpath, sizeof(wpath) / sizeof(WCHAR), wfilename);
	V_RETURN(D3DXLoadMeshHierarchyFromXW(wpath, D3DXMESH_MANAGED, m_device, m_alloc_hierarchy, NULL, 
&m_root_frame, &m_anim_controller));
	V_RETURN(D3DXFrameCalculateBoundingSphere(m_root_frame, &m_object_center, &m_object_radius));
	return S_OK;
}

雖然該函數的實現代碼非常簡單,但其內部過程卻是很復雜的,關鍵是要弄清除D3DXLoadMeshHierarchyFromX()函數中m_alloc_hierarchy參數的作用。D3DXLoadMeshHierarchyFromX()函數在內部隱式地通過m_alloc_hierarchy調用加載網格模型具體數據的函數(即上面提到的cAllocateHeirarchy中的CreateFrame()和CreateMeshContainer()函數),這些函數是由用戶編寫的,但卻是由Direct3D在內部于適當機制調用。

來看看D3DXLoadMeshHierarchyFromX()的具體使用說明:

Loads the first frame hierarchy from a .x file.

HRESULT D3DXLoadMeshHierarchyFromX(
LPCSTR Filename,
DWORD MeshOptions,
LPDIRECT3DDEVICE9 pDevice,
LPD3DXALLOCATEHIERARCHY pAlloc,
LPD3DXLOADUSERDATA pUserDataLoader,
LPD3DXFRAME* ppFrameHierarchy,
LPD3DXANIMATIONCONTROLLER* ppAnimController
);

Parameters

Filename
[in] Pointer to a string that specifies the filename. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
MeshOptions
[in] Combination of one or more flags from the D3DXMESH enumeration that specify creation options for the mesh.
pDevice
[in] Pointer to an IDirect3DDevice9 interface, the device object associated with the mesh.
pAlloc
[in] Pointer to an ID3DXAllocateHierarchy interface.
pUserDataLoader
[in] Application provided interface that allows loading of user data.
ppFrameHierarchy
[out, retval] Returns a pointer to the loaded frame hierarchy.
ppAnimController
[out, retval] Returns a pointer to the animation controller corresponding to animation in the .x file. This is created with default tracks and events.

Return Values

If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following values: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

Remarks

The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXLoadMeshHierarchyFromXW. Otherwise, the function call resolves to D3DXLoadMeshHierarchyFromXA.

All the meshes in the file will be collapsed into one output mesh. If the file contains a frame hierarchy, all the transformations will be applied to the mesh.

D3DXLoadMeshHierarchyFromX loads the animation data and frame hierarchy from a .x file. It scans the .x file and builds a frame hierarchy and animation controller according to the ID3DXAllocateHierarchy-derived object passed to it through pAlloc. Loading the data requires several steps as follows:

  1. Derive ID3DXAllocateHierarchy, implementing each method. This controls how frames and meshes are allocated and freed.
  2. Derive ID3DXLoadUserData, implementing each method. If your .x file has no embedded user-defined data, or if you do not need it, you can skip this part.
  3. Create an object of your ID3DXAllocateHierarchy class, and optionally of your LoadUserData class. You do not need to call any methods of these objects yourself.
  4. Call D3DXLoadMeshHierarchyFromX, passing in your ID3DXAllocateHierarchy object and your ID3DXLoadUserData object (or NULL) to create the frame hierarchy and animation controller. All the animation sets and frames are automatically registered to the animation controller.

During the load, ID3DXAllocateHierarchy::CreateFrame and ID3DXLoadUserData::LoadFrameChildData are called back on each frame to control loading and allocation of the frame. The application defines these methods to control how frames are stored. ID3DXAllocateHierarchy::CreateMeshContainer and ID3DXLoadUserData::LoadMeshChildData are called back on each mesh object to control loading and allocation of mesh objects. ID3DXLoadUserData::LoadTopLevelData is called back for each top level object that doesn't get loaded by the other methods.

To free this data, call ID3DXAnimationController::Release to free the animation sets, and D3DXFRAMEDestroy, passing in the root node of the frame hierarchy and an object of your derived ID3DXAllocateHierarchy class. ID3DXAllocateHierarchy::DestroyFrame and ID3DXAllocateHierarchy::DestroyMeshContainer will each be called for every frame and mesh object in the frame hierarchy. Your implementation of ID3DXAllocateHierarchy::DestroyFrame should release everything allocated by ID3DXAllocateHierarchy::CreateFrame, and likewise for the mesh container methods.

 

因為在每次渲染網格模型前,只有知道每個框架的確切位置,才能在正確的位置上繪制出該框架包含的具體網格模型,所以需要計算得到各級框架的組合變換矩陣,函數update_frame_matrices()采用遞歸的方法計算各級框架的組合變換矩陣,具體實現代碼如下:

void cAnimMesh::update_frame_matrices(D3DXFRAME* base_frame, CONST D3DXMATRIX* parent_matrix)
{
D3DXFRAME_DERIVED* frame = (D3DXFRAME_DERIVED*) base_frame;
	if(parent_matrix != NULL)
D3DXMatrixMultiply(&frame->CombinedTransformMatrix, &frame->TransformationMatrix, parent_matrix);
else
frame->CombinedTransformMatrix = frame->TransformationMatrix;
	if(frame->pFrameSibling != NULL)
update_frame_matrices(frame->pFrameSibling, parent_matrix);
	if(frame->pFrameFirstChild != NULL)
update_frame_matrices(frame->pFrameFirstChild, &frame->CombinedTransformMatrix);
}

 

因為骨骼動畫網格模型是通過框架按照樹狀結構組織起來的,而網格模型又包含在框架之中,所以在為了渲染網格模型的同時能將其中的動畫播放出來,就需要逐個框架逐個網格模型地進行渲染,其中draw_mesh_container()負責渲染框架中包含的具體網格模型:

void cAnimMesh::draw_mesh_container(CONST D3DXMESHCONTAINER* base_mesh_container, CONST D3DXFRAME* base_frame)
{
D3DXMESHCONTAINER_DERIVED* mesh_container = (D3DXMESHCONTAINER_DERIVED*) base_mesh_container;
D3DXFRAME_DERIVED* frame = (D3DXFRAME_DERIVED*) base_frame;
	m_device->SetTransform(D3DTS_WORLD, &frame->CombinedTransformMatrix);
	for(UINT i = 0; i < mesh_container->NumMaterials; i++)
{
m_device->SetMaterial(&mesh_container->pMaterials[i].MatD3D);
m_device->SetTexture(0, mesh_container->ppTextures[i]);
		mesh_container->MeshData.pMesh->DrawSubset(i);
}
}

該函數的實現比較簡單,在渲染每個網格之前,首先調用函數SetTransform(),根據該網格在框架的組合變換矩陣,將網格中所包含的網格模型移動到正確的位置后,再設置材質、紋理,最后進行繪制。

 

函數draw_frame()以draw_mesh_container()為基礎,采用遞歸的方法,將整個網格模型繪制出來:

void cAnimMesh::draw_frame(CONST D3DXFRAME* frame)
{
D3DXMESHCONTAINER* mesh_container = frame->pMeshContainer;
	while(mesh_container != NULL)
{
draw_mesh_container(mesh_container, frame);
mesh_container = mesh_container->pNextMeshContainer;
}
	if(frame->pFrameSibling != NULL)
draw_frame(frame->pFrameSibling);
	if(frame->pFrameFirstChild != NULL)
draw_frame(frame->pFrameFirstChild);
}

在調用該函數時,只需將參數frame設置為網格模型的根節點就可以繪制出整個網格模型。

 

函數render()通過draw_frame()完成整個網格模型的渲染,其實現如下:

void cAnimMesh::render(CONST D3DXMATRIX* mat_world, double app_elapsed_time)
{
if(0.0f == app_elapsed_time)
return;
	if(m_is_play_anim && m_anim_controller != NULL)
m_anim_controller->AdvanceTime(app_elapsed_time, NULL);
	update_frame_matrices(m_root_frame, mat_world);
draw_frame(m_root_frame);
}

在渲染網格模型之前,首先使用動畫控制器m_anim_controller調用函數AdvanceTime()將網格模型動畫向前推進,然后調用函數update_frame_matrices(),根據當前網格模型的世界矩陣mat_world更新整個網格模型的層次,即計算每個框架的組合變換矩陣,最后調用draw_frame()函數渲染出整個網格模型。

 

create()函數用于根據參數指定的網格模型文件名創建骨骼動畫網格模型:

HRESULT cAnimMesh::create(IDirect3DDevice9* device, CONST WCHAR* wfilename)
{
m_device = device;
	HRESULT hr;
V_RETURN(load_from_xfile(wfilename));
	return S_OK;
}

函數destroy()只負責銷毀對象:

void cAnimMesh::destroy()
{
delete this;
}

posted on 2008-06-11 15:46 lovedday 閱讀(3317) 評論(1)  編輯 收藏 引用

評論

# re: 網格模型高級技術(13) 2012-03-13 14:24 小班

D3DXLoadMeshFromX()函數中返回一個LPD3DXMESM的網格對象,而你的個方法D3DXLoadMeshHierarchyFromX()是怎么返回的?急用  回復  更多評論   


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久热爱精品视频线路一| 伊人狠狠色丁香综合尤物| 欧美特黄一级| 国产精品久久看| 国产一区清纯| 日韩午夜电影av| 久久精品国产精品 | 欧美激情视频网站| 欧美婷婷六月丁香综合色| 国产精品日韩在线一区| 亚洲激情视频在线| 欧美一区二区三区精品| 91久久精品国产91久久性色| 亚洲国产女人aaa毛片在线| 欧美成人官网二区| 亚洲一区二区三区视频| 麻豆精品在线视频| 国产精品资源在线观看| 亚洲视屏在线播放| 欧美77777| 欧美三级视频在线观看| 久久精品三级| 欧美国产成人在线| 亚洲国产一成人久久精品| 日韩午夜三级在线| 久久视频这里只有精品| 国产欧美va欧美va香蕉在| 亚洲一级高清| 99精品国产在热久久| 欧美激情视频在线播放 | 亚洲男女自偷自拍图片另类| 欧美成黄导航| 国产精品久久| 午夜伦欧美伦电影理论片| 亚洲精品小视频| 欧美日本不卡视频| 亚洲美女少妇无套啪啪呻吟| 欧美激情视频给我| 媚黑女一区二区| 香港成人在线视频| 小嫩嫩精品导航| 国产欧美va欧美va香蕉在| 亚洲激情视频在线| 韩国成人精品a∨在线观看| 久久亚洲欧美| 久久久综合精品| 亚洲缚视频在线观看| 欧美aaaaaaaa牛牛影院| 国产精品夜色7777狼人| 亚洲精品欧美专区| 亚洲精品美女在线观看| 日韩亚洲欧美一区二区三区| 亚洲大黄网站| 亚洲精品中文在线| 亚洲激情专区| 老鸭窝亚洲一区二区三区| av成人免费在线观看| 日韩天堂在线观看| 亚洲精品影视在线观看| 久久亚洲精品中文字幕冲田杏梨| 久久成人人人人精品欧| 美国十次成人| 美腿丝袜亚洲色图| 欧美日韩免费观看一区二区三区| 一本色道久久综合| 欧美激情一级片一区二区| 欧美多人爱爱视频网站| 国产精品乱码一区二三区小蝌蚪| 亚洲激情网站| 一区二区三区鲁丝不卡| 欧美亚洲午夜视频在线观看| 亚洲高清自拍| 久久久久国内| 免费欧美在线| 亚洲啪啪91| 亚洲精品老司机| 国内一区二区三区| 久久久久一区二区三区| 欧美岛国在线观看| 99re在线精品| 国产精品久久一卡二卡| 午夜精品三级视频福利| 久久青青草原一区二区| 欧美视频在线不卡| 亚洲欧美日韩国产一区二区三区| 亚洲欧洲精品一区二区三区 | 欧美成人r级一区二区三区| 亚洲综合国产| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美中文在线观看| 韩国久久久久| 欧美精品不卡| 亚洲欧美日韩国产精品| 你懂的亚洲视频| 亚洲特级片在线| 国内一区二区在线视频观看| 欧美成人精品福利| 亚洲一级影院| 亚洲伊人一本大道中文字幕| 国产亚洲精品福利| 亚洲欧美大片| 欧美一区二区三区视频在线| 一区二区在线免费观看| 欧美一区二区三区久久精品 | 在线一区免费观看| 国产一区二区中文| 欧美电影在线播放| 午夜精品影院| 亚洲精品一区二区三| 久久久亚洲午夜电影| 在线亚洲自拍| 亚洲高清免费视频| 国产欧美一区二区三区另类精品 | 在线观看91精品国产麻豆| 欧美区视频在线观看| 欧美中文字幕视频| 久久午夜色播影院免费高清| 一区二区欧美日韩视频| 影音先锋久久精品| 国产日韩精品视频一区| 欧美日韩国产系列| 亚洲午夜一区二区三区| 欧美福利一区二区三区| 久久精品国产一区二区三区免费看| 亚洲免费精品| 亚洲国产精品电影在线观看| 国产日韩精品在线观看| 欧美中文字幕视频| 亚洲婷婷综合久久一本伊一区| 欧美激情精品久久久六区热门 | 午夜视频在线观看一区二区| 日韩视频精品| 亚洲美女免费精品视频在线观看| 免费在线看一区| 久久先锋资源| 久久久精品国产免大香伊| 在线成人激情视频| 好吊妞这里只有精品| 国产视频欧美视频| 国产美女精品人人做人人爽| 国产精品美女主播| 国产精品羞羞答答xxdd| 国产精品影片在线观看| 国产精品午夜在线| 国产乱码精品1区2区3区| 国产精品丝袜久久久久久app| 欧美性感一类影片在线播放| 国产精品国产三级国产专区53| 欧美日韩在线不卡一区| 欧美亚洲成人精品| 国产精品久久久久一区二区| 国产精品嫩草影院一区二区| 国产女人水真多18毛片18精品视频| 国产精品欧美精品| 国产一区二区三区丝袜 | 国产精品二区三区四区| 国产精品久久99| 国产亚洲精品aa| 亚洲国产精品va| 亚洲最快最全在线视频| 亚洲午夜久久久久久尤物 | 亚洲狼人精品一区二区三区| 日韩视频免费观看高清完整版| 99国内精品久久| 午夜精品亚洲一区二区三区嫩草| 欧美综合激情网| 欧美国产日本在线| 在线一区欧美| 亚洲国产中文字幕在线观看| 午夜在线精品| 裸体素人女欧美日韩| 亚洲激情欧美| 新片速递亚洲合集欧美合集| 久久久久久999| 欧美日韩国产限制| 国模私拍视频一区| 一本色道久久综合亚洲精品小说 | 欧美一区二区在线看| 久久综合伊人77777蜜臀| 亚洲精品一区久久久久久| 午夜免费电影一区在线观看| 欧美阿v一级看视频| 国产精品女同互慰在线看| 在线精品高清中文字幕| 亚洲永久精品国产| 欧美成人一区二区三区| 亚洲一区二区三区精品在线观看| 久久香蕉国产线看观看网| 国产精品成人一区二区| 亚洲高清电影| 久久久久国产一区二区| 日韩一级大片在线| 麻豆视频一区二区| 国产麻豆日韩| 亚洲一区二区三区高清| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲图片在线| 欧美日韩直播| 日韩午夜中文字幕| 欧美二区视频|