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

天行健 君子當自強而不息

Using the .X File Format(11)

Loading Frame Hierarchies from .X

Skeletal animation systems require a frame hierarchy (which represents the bone structure) to orient each bone during rendering. The .X file format defines a frame−of−reference data template that you can use to define your bone hierarchy. This template, Frame, is merely a placeholder of sorts. It allows any type of data object to be embedded in it so you can reference the instanced Frame object by its assigned instance name and allow all contained objects to be addressed as well.

Building a frame hierarchy involves parsing an .X file, in which you link each Frame object to another. The relationship is very important−a Frame object can either be a sibling or a child to another Frame object, and it can have an unlimited number of siblings and/or child objects linked to it.

In DirectX 9, you have access to a special DirectX structure called D3DXFRAME to contain each frame in your hierarchy. In this section, you'll use D3DXFRAME to contain a frame hierarchy.

The exact way you parse and build your Frame objects is really up to you. You can use the D3DX library to help, or you can parse/build the hierarchy yourself using your custom .X parser. Which is better for you? Whereas the D3DX library is great to use, I find the methods of using the library to load a frame hierarchy overly complicated, with no less than two interfaces to use and an entire memory−handling class of your own to be written. Why bother when you can load a frame hierarchy using one small .X parser class you created?

Instead, load up your trusty .X parser (which you developed earlier in this chapter, in the "Constructing an .X Parser Class" section) and derive a version that scans for Frame data objects. I'll start you off by showing you the derived class you can use.

class cXFrameParser : public cXParser
{
public:
// declare an extended version of D3DXFRAME
// that contains a constructor and destructor
struct D3DXFRAME_EX : public D3DXFRAME
{
D3DXFRAME_EX()
{
Name = NULL;
pFrameSibling = NULL; pFrameFirstChild = NULL;
}
		~D3DXFRAME_EX()
{
delete [] Name;
delete pFrameFirstChild;
delete pFrameSibling;
}
} D3DXFRAME_EX;
	// Instance the root frame of the hierarchy
D3DXFRAME_EX *m_RootFrame;
public:
cXFrameParser() { m_RootFrame = NULL; }
~cXFrameParser() { delete m_RootFrame; }
	BOOL BeginParse(void **Data)
{
// Clear hierarchy
delete m_RootFrame; m_RootFrame = NULL;
}
	BOOL ParseObject(IDirectXFileData *pDataObj, 
IDirectXFileData *pParentDataObj,
DWORD Depth,
void **Data,
BOOL Reference)
{
// Skip reference frames
if(Reference == TRUE)
return TRUE;
		// Make sure template being parsed is a frame
if(*GetObjectGUID(pDataObj) == TID_D3DRMFrame)
{
// Allocate a frame structure
D3DXFRAME_EX *Frame = new D3DXFRAME_EX();
			// Get frame name (assign one if none found)
if((Frame−>Name = GetObjectName(pDataObj)) == NULL)
Frame−>Name = strdup("No Name");
			// Link frame structure into list
if(Data == NULL)
{
// Link as sibling of root
Frame−>pFrameSibling = m_RootFrame;
m_RootFrame = Frame;
Data = (void**)&m_RootFrame;
}
else
{
// Link as child of supplied frame
D3DXFRAME_EX *FramePtr = (D3DXFAME_EX*)*Data;
Frame−>pFrameSibling = FramePtr−>pFrameFirstChild;
FramePtr−>pFrameFirstChild = Frame;
Data = (void**)&Frame;
}
}
		return ParseChildObjects(pDataObj,Depth,Data,Reference);
}
};
cXFrameParser Parser;
Parser.Parse("frames.x");
// Parser.m_RootFrame now points to root frame of hierarchy

There you have it. Once the cXFrameParser::Parse function is complete, you'll have a self−contained frame hierarchy ready to use in your project. The ParseFrame demo loads an .X file of your choice and displays the frame hierarchy inside a list box.

 

ParseFrame Demo

This demo uses the information on loading a frame hierarchy from an .X file. As shown in Figure 3.2, the ParseFrame demo has a button labeled Select .X File. Click that button, locate an .X file to load, and click Open.

Figure 3.2: The ParseFrame demo's dialog box contains two controls−a button you click to load an .X file and a list box that displays the frame hierarchy.

After selecting an .X file to load and clicking Open, you'll be treated to a display of the frame hierarchy contained within the file. To make things easier to understand, the frames are indented by their level in the hierarchy.

Because IDirectXFile interface has been deprecated, I translate this interface into ID3DXFile.

WinMain.cpp:

#include <stdio.h>
#include 
<windows.h>
#include 
<d3d9.h>
#include 
<d3dx9.h>
#include 
<rmxfguid.h>
#include 
"Direct3D.h"
#include 
"XParser.h"
#include 
"resource.h"

#pragma warning(disable : 
4996)

extern unsigned char D3DRM_XTEMPLATES[];

D3DXFRAME_EX
* g_root_frame;

const char g_class_name[] = "ParseFrameClass";
const char g_caption[]      = ".X Frame Parser Demo";

////////////////////////////////////////////////////////////////////////////////////////////////

LRESULT FAR PASCAL window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

bool do_init(HWND hwnd);
void do_shutdown();
void do_frame();

void add_frames_to_list(D3DXFRAME_EX* frame, DWORD indent, HWND list_handle);

//////////////////////////////////////////////////////////////////////////////////////////////

class cXFrameParser : public cXParser
{
protected:
    D3DXFRAME_EX
* m_root_frame;

protected:
    
virtual bool parse_objects(ID3DXFileData* xfile_data,
                               ID3DXFileData
* parent_xfile_data,
                               DWORD  depth,
                               
void** data,
                               
bool   force_ref)
    {
        GUID type;
        get_object_guid(xfile_data, 
&type);

        
// make sure template being parsed is a mesh (non-referenced)
        if(type == TID_D3DRMFrame && force_ref == false)
        {
            D3DXFRAME_EX
* frame = new D3DXFRAME_EX;

            
// get frame name (assign one if none found)

            frame
->Name = get_object_name(xfile_data);

            
if(frame->Name == NULL)
                frame
->Name = strdup("NoNameFrame");

            
// link frame structure into list

            
if(data == NULL)
            {
                
// link as sibling of root
                frame->pFrameSibling = m_root_frame;
                m_root_frame 
= frame;
                data 
= (void**&m_root_frame;
            }
            
else
            {
                
// link as child of supplied frame
                D3DXFRAME_EX* frame_ptr = (D3DXFRAME_EX*) (*data);
                frame
->pFrameSibling = frame_ptr->pFrameFirstChild;
                frame_ptr
->pFrameFirstChild = frame;
                data 
= (void**&frame_ptr->pFrameFirstChild;
            }

            frame 
= NULL;    // clear frame pointer since it's been assigned
        }

        
return parse_child_objects(xfile_data, depth, data, force_ref);
    }

public:
    
bool load(const char* filename, D3DXFRAME_EX** ret_frame)
    {
        
bool rv = false;
        m_root_frame 
= NULL;

        
if(parse(filename, NULL))
        {
            
*ret_frame = m_root_frame;
            rv 
= true;
        }
        
else
        {
            
*ret_frame = NULL;
        }

        
return rv;
    }
};

//////////////////////////////////////////////////////////////////////////////////////////////

int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR, int cmd_show)
{      
    CoInitialize(NULL);    
// Initialize the COM system

    
// Create the window class here and register it

    WNDCLASSEX win_class;  

    win_class.cbSize        
= sizeof(win_class);
    win_class.style         
= CS_HREDRAW | CS_VREDRAW;
    win_class.lpfnWndProc   
= window_proc;
    win_class.cbClsExtra    
= 0;
    win_class.cbWndExtra    
= DLGWINDOWEXTRA;
    win_class.hInstance     
= inst;
    win_class.hIcon         
= LoadIcon(NULL, IDI_APPLICATION);
    win_class.hCursor       
= LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground 
= (HBRUSH)(COLOR_BTNFACE + 1);
    win_class.lpszMenuName  
= NULL;
    win_class.lpszClassName 
= g_class_name;
    win_class.hIconSm       
= LoadIcon(NULL, IDI_APPLICATION);

    
if(!RegisterClassEx(&win_class))
        
return -1;

    
// create the dialog box window and show it
    HWND hwnd = CreateDialog(inst, MAKEINTRESOURCE(IDD_FRAMEVIEW), 0, NULL);

    ShowWindow(hwnd, cmd_show);
    UpdateWindow(hwnd);

    MSG msg;    
    ZeroMemory(
&msg, sizeof(MSG));

    
// Start message pump, waiting for user to exit
    while(msg.message != WM_QUIT) 
    {
        
if(PeekMessage(&msg, NULL, 00, PM_REMOVE)) 
        {
            TranslateMessage(
&msg);
            DispatchMessage(
&msg);
        }
    }

    UnregisterClass(g_class_name, inst);
    CoUninitialize();

    
return 0;
}

LRESULT FAR PASCAL window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    OPENFILENAME ofn;
    
char filename[MAX_PATH] = {0};
    
    
// Only handle window destruction messages
    switch(msg) 
    {
    
case WM_COMMAND:
        
switch(LOWORD(wParam))
        {
        
case IDC_SELECT:
            ZeroMemory(
&ofn, sizeof(OPENFILENAME));

            ofn.lStructSize        
= sizeof(OPENFILENAME);
            ofn.nMaxFile        
= MAX_PATH;
            ofn.nMaxFileTitle    
= MAX_PATH;
            ofn.Flags            
= OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
            ofn.hwndOwner        
= hwnd;
            ofn.lpstrFile        
= filename;
            ofn.lpstrTitle        
= "Load and Parse .x file";
            ofn.lpstrFilter        
= ".X Files (*.x)\0*.x\0All Files (*.*)\0*.*\0\0";
            ofn.lpstrDefExt        
= "x";

            
if(! GetOpenFileName(&ofn))
                
return 0;

            
// get rid of last loaded mesh list
            delete g_root_frame;
            g_root_frame 
= NULL;

            
// parse .x file and display hierarchy

            cXFrameParser mesh_parser;

            
if(mesh_parser.load(filename, &g_root_frame))
            {
                SendMessage(GetDlgItem(hwnd, IDC_FRAMELIST), LB_RESETCONTENT, 
00);
                add_frames_to_list(g_root_frame, 
2, GetDlgItem(hwnd, IDC_FRAMELIST));
            }

            
break;
        }

        
break;
    
    
case WM_DESTROY:
        delete g_root_frame;
        g_root_frame 
= NULL;
        PostQuitMessage(
0);
        
break;

    
case WM_KEYDOWN:
        
if(wParam == VK_ESCAPE)
            DestroyWindow(hwnd);

        
break;
    }

    
return DefWindowProc(hwnd, msg, wParam, lParam);
}

void add_frames_to_list(D3DXFRAME_EX* frame, DWORD indent, HWND list_handle)
{
    
if(frame == NULL)
        
return;

    
// add siblings to list first
    if(frame->pFrameSibling)
        add_frames_to_list((D3DXFRAME_EX
*) frame->pFrameSibling, indent, list_handle);

    
// build text to add to list

    
char text[1024];

    memset(text, 
' ', indent);
    text[indent] 
= '\0';
    strcat(text, frame
->Name);    

    SendMessage(list_handle, LB_ADDSTRING, 
0, (LPARAM) text);

    
// add children to list
    if(frame->pFrameFirstChild)
        add_frames_to_list((D3DXFRAME_EX
*) frame->pFrameFirstChild, indent+4, list_handle);
}
 

download source file


Loading Custom Data from .X

As I've expressed throughout this chapter, the .X file format is completely open−ended; there is no limit to the type of data you can store. With that in mind, you can create any type of data storage you want, and accessing that data will be just as easy as accessing the mesh and frame data we've already covered.

Jump back to your ContactEntry template and see just how to parse an .X file and display every instance of ContactEntry. Again, a single small derived class of cXParser will work perfectly here.

#include "initguid.h"
// First declare the ContactEntry GUID
DEFINE_GUID(ContactEntry, \
0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, \
0x1f, 0x50, 0x7e, 0x45, 0xff);
// Now, define the .X parser class
class cXContactParser : public cXParser
{
public:
BOOL ParseObject(IDirectXFileData *pDataObj,
IDirectXFileData *pParentDataObj,
DWORD Depth,
void **Data,
BOOL Reference)
{
// Skip reference objects
if(Reference == TRUE)
return TRUE;
		// Make sure object being parsed is ContactEntry
if(*GetObjectGUID(pDataObj) == CONTACTENTRY)
{
// Get the data pointer and size
DWORD DataSize;
DWORD *DataPtr;
			DataPtr = (DWORD*)GetObjectData(pDataObj, &DataSize);
			// Get name from object data
char *Name = (char*)*DataPtr++;
			// Get phone # from object data
char *PhoneNum = (char*)*DataPtr++;
			// Get age from object data
DWORD Age = *DataPtr++;
			// Display contact information
char Text[1024];
sprintf(Text, "Name: %s\r\nPhone #: %s\r\nAge: %lu", Name, PhoneNum, Age);
MessageBox(NULL, Text, "Contact", MB_OK);
}
		return ParseChildObjects(pDataObj,Depth,Data,Reference);
}
};
cXContactParser Parser;
Parser.Parse("contacts.x");

With a single call to cXContactParser::Parse, you're treated to a list of people's names, phone numbers, and ages−all contained in the contacts.x file! Now wasn't that easy? See, you don't have to be afraid of the .X file format. I personally use .X to store as much custom data as I can.


posted on 2008-04-18 14:35 lovedday 閱讀(917) 評論(1)  編輯 收藏 引用

評論

# re: Using the .X File Format(11) 2009-07-07 11:34 blueesoft

好,努力  回復  更多評論   


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   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>
            久久婷婷麻豆| 狠狠色噜噜狠狠狠狠色吗综合| 中文精品一区二区三区| 91久久精品美女| 久久亚洲风情| 欧美韩国日本一区| 亚洲日本一区二区三区| 一本色道综合亚洲| 午夜在线播放视频欧美| 久久久综合精品| 欧美电影免费网站| 欧美日韩中文| 国产一区二区在线观看免费播放| 国际精品欧美精品| 亚洲精品乱码久久久久| 亚洲尤物在线| 久久综合九色九九| 亚洲美女少妇无套啪啪呻吟| 亚洲一区国产| 免费观看欧美在线视频的网站| 欧美日韩高清在线一区| 国产一区二区在线免费观看| 亚洲精品国产日韩| 欧美一区1区三区3区公司| 农夫在线精品视频免费观看| 亚洲私人影吧| 欧美激情亚洲国产| 国产最新精品精品你懂的| 亚洲一区免费在线观看| 欧美激情中文字幕一区二区| 午夜久久黄色| 欧美性猛交xxxx乱大交退制版| 亚洲第一在线视频| 久久精品免费看| 中文日韩在线| 欧美另类变人与禽xxxxx| 一区二区亚洲精品| 欧美在线看片| 一本久久综合亚洲鲁鲁| 欧美激情国产精品| 在线观看亚洲视频| 久久精品青青大伊人av| 亚洲特色特黄| 欧美精品一区二区蜜臀亚洲| 樱桃国产成人精品视频| 久久国产一区二区三区| 亚洲一区二区三区四区五区午夜| 欧美人成在线| 日韩亚洲欧美一区二区三区| 模特精品在线| 久久久国产午夜精品| 国产日韩欧美a| 欧美一级久久久| 亚洲国产精品第一区二区| 久久阴道视频| 久久精品视频在线| 国产色综合天天综合网| 欧美一区二区三区视频| 亚洲欧美日本国产专区一区| 欧美日韩中文精品| 亚洲免费在线观看| 一个色综合av| 国产精品久久久久久五月尺| 亚洲在线不卡| 亚洲一区二区三区影院| 国产精品亚洲综合久久| 久久黄色小说| 久久久人成影片一区二区三区观看| 黄色成人在线免费| 欧美国产精品劲爆| 欧美大胆成人| 亚洲一区二区三区免费视频| 亚洲视频网站在线观看| 国产日韩精品在线| 麻豆成人在线观看| 欧美成人第一页| 亚洲色无码播放| 亚洲欧美高清| 1769国内精品视频在线播放| 亚洲第一主播视频| 欧美日韩国产大片| 欧美在线高清| 久久综合色8888| 亚洲午夜精品网| 欧美淫片网站| 99在线|亚洲一区二区| 亚洲午夜精品久久久久久app| 国产亚洲欧美一级| 亚洲国产午夜| 国产偷国产偷精品高清尤物| 欧美成人伊人久久综合网| 欧美视频在线观看| 榴莲视频成人在线观看| 欧美日韩国产黄| 午夜日韩福利| 欧美成人精品一区| 欧美一激情一区二区三区| 欧美bbbxxxxx| 久久精品视频播放| 欧美啪啪一区| 噜噜噜91成人网| 欧美午夜不卡影院在线观看完整版免费| 久久精品亚洲一区二区| 欧美激情国产日韩精品一区18| 先锋亚洲精品| 欧美大片在线观看一区二区| 久久av一区二区三区亚洲| 欧美啪啪成人vr| 亚洲大胆人体在线| 国产一区在线免费观看| 一区二区免费在线播放| 亚洲高清视频一区| 欧美亚洲综合另类| 亚洲直播在线一区| 欧美好吊妞视频| 蜜臀a∨国产成人精品| 国产精品永久免费视频| 亚洲一级电影| 欧美成人视屏| 欧美99在线视频观看| 国产欧美日韩视频在线观看 | 欧美激情一区三区| 国产色综合天天综合网| 正在播放亚洲一区| 日韩一二三在线视频播| 免费在线观看成人av| 蜜桃久久精品一区二区| 激情文学综合丁香| 久久精品国产亚洲aⅴ| 欧美一区二区视频97| 欧美日韩在线观看一区二区| 91久久精品www人人做人人爽| 在线精品观看| 久久综合精品一区| 美女黄网久久| 国色天香一区二区| 久久久久青草大香线综合精品| 久久国产视频网站| 国产欧美亚洲日本| 欧美一区2区视频在线观看 | 欧美视频你懂的| 亚洲精品自在在线观看| 日韩午夜免费视频| 免费av成人在线| 亚洲精品一区二区三区福利 | 免费国产自线拍一欧美视频| 国产婷婷色一区二区三区在线| 亚洲欧美日韩视频二区| 性亚洲最疯狂xxxx高清| 国产日韩欧美在线视频观看| 欧美一区二区日韩| 欧美成人精品三级在线观看 | 一本色道88久久加勒比精品 | 欧美 日韩 国产 一区| 亚洲国产人成综合网站| 欧美精品福利| 99在线精品视频| 性欧美18~19sex高清播放| 国产视频亚洲| 免费成年人欧美视频| 亚洲精品社区| 久久爱91午夜羞羞| 亚洲国产高清自拍| 欧美日本在线一区| 亚洲视频碰碰| 免费在线一区二区| 亚洲专区一区二区三区| 极品少妇一区二区三区| 欧美精品七区| 欧美一区二区三区四区视频 | 蜜桃久久av| 中文国产成人精品久久一| 国产亚洲欧美一区二区三区| 亚洲精品一级| 久久精品欧洲| 99av国产精品欲麻豆| 国产日产亚洲精品| 欧美激情第1页| 欧美在线免费| 亚洲图片欧美日产| 亚洲国产成人精品久久| 欧美亚洲网站| 夜夜嗨av一区二区三区免费区| 国产日韩av在线播放| 免费日本视频一区| 欧美一区二区三区四区在线观看| 亚洲欧洲一区二区三区在线观看| 欧美一区二区三区免费视频| 亚洲狼人综合| 亚洲二区视频| 国产视频亚洲| 国产精品三区www17con| 欧美日本中文字幕| 久久天堂成人| 性欧美精品高清| 一区二区三区四区五区在线| 久久在线观看视频| 欧美一级视频精品观看| 宅男66日本亚洲欧美视频| 91久久精品国产91性色|