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

天行健 君子當自強而不息

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>
            欧美日韩小视频| 亚洲高清电影| 亚洲乱码国产乱码精品精| 亚洲视频二区| 日韩一级大片在线| 亚洲成人影音| 亚洲国产岛国毛片在线| 尤物视频一区二区| 欲香欲色天天天综合和网| 国产在线一区二区三区四区| 精品9999| 日韩亚洲欧美高清| 亚洲欧美一区在线| 亚洲欧美日韩在线高清直播| 久久大综合网| 亚洲欧洲视频| 99一区二区| 久久国产直播| 欧美国产亚洲另类动漫| 亚洲免费高清| 91久久精品国产| 日韩一级黄色大片| 欧美一级大片在线观看| 免费h精品视频在线播放| 欧美黄色一级视频| 国产精品网站视频| 亚洲免费观看高清在线观看| 亚洲欧美日韩在线不卡| 亚洲国产免费看| 久久国产精品99精品国产| 欧美va亚洲va香蕉在线| 国产日韩欧美三级| 亚洲午夜视频在线| 亚洲国产欧美一区二区三区久久 | 国产精品porn| 在线电影国产精品| 久久久久国产精品午夜一区| 亚洲国产婷婷综合在线精品| 久久高清免费观看| 黑人操亚洲美女惩罚| 久久丁香综合五月国产三级网站| 一本色道久久综合亚洲精品婷婷 | 久久精品一区二区三区不卡牛牛| 欧美日韩精品不卡| 久久亚洲图片| 韩日欧美一区二区| 欧美在线视频在线播放完整版免费观看 | 久久精品欧美日韩| 午夜电影亚洲| 黄色成人在线网站| 免费欧美视频| 欧美日韩精品一区二区天天拍小说| 99国内精品久久久久久久软件| 亚洲国产影院| 国产欧美欧美| 日韩亚洲视频| 在线精品视频一区二区| 亚洲欧洲精品一区| 国产亚洲一区在线播放| 国产在线成人| 亚洲国产精品99久久久久久久久| 欧美日韩国产欧| 久久精品国产亚洲aⅴ| 欧美日韩在线免费| 国产精品久久7| 久久都是精品| 欧美激情精品久久久久久变态| 欧美日韩免费观看一区| 亚洲国产成人91精品| 国产精品一二三| 最近中文字幕mv在线一区二区三区四区| 久久这里有精品15一区二区三区| 亚洲国产高清aⅴ视频| 亚洲午夜三级在线| 亚洲黄色在线| 久久综合中文字幕| 日韩一区二区久久| 久久成人18免费观看| 欧美专区亚洲专区| 国产日韩欧美高清| 久久久亚洲国产天美传媒修理工 | 亚洲第一毛片| 久久久久久午夜| 欧美国产三区| 精品1区2区| 欧美福利视频在线| 欧美成人高清视频| 亚洲欧洲日本专区| 亚洲日韩视频| 亚洲国产一区二区视频| 欧美成人精品在线| 日韩一本二本av| 午夜精品久久久久久久男人的天堂| 国内精品国语自产拍在线观看| 亚洲福利视频一区二区| 亚洲日本免费| 亚洲三级性片| 亚洲免费电影在线| 99xxxx成人网| 久久女同精品一区二区| 亚洲免费视频一区二区| 夜夜夜久久久| 亚洲国产精品福利| 久久精品123| 欧美一区二区三区视频免费播放| 久久综合久久美利坚合众国| 中国成人亚色综合网站| 99re在线精品| 亚洲国产精品日韩| 国产精品久久中文| 亚洲人成人一区二区三区| 一区二区高清视频| 亚洲主播在线| 六月婷婷一区| 国产欧美一区二区精品秋霞影院 | 久久久久国产精品一区三寸| 在线一区二区三区四区| 亚洲精品乱码久久久久久蜜桃91 | 欧美一级视频精品观看| 亚洲视频自拍偷拍| 国产午夜精品美女毛片视频| 午夜精品久久久久久久男人的天堂| 亚洲综合不卡| 久久久久久久999| 午夜精品99久久免费| 亚洲午夜成aⅴ人片| 日韩一级在线观看| 国产精品va在线播放我和闺蜜| 9l国产精品久久久久麻豆| 欧美一级视频| 亚洲人成网站777色婷婷| 国产精品久久久久一区二区三区共 | 欧美成va人片在线观看| 欧美成人一区二区三区在线观看| 艳女tv在线观看国产一区| 国内成人精品视频| 毛片精品免费在线观看| 一区二区三区日韩欧美| 欧美顶级艳妇交换群宴| 久久久国产一区二区| 国产美女精品免费电影| 久久亚洲午夜电影| 久久精品视频导航| 日韩视频在线观看| 亚洲激情视频在线| 在线观看欧美日韩国产| 国产精品美女| 国产色视频一区| 国产亚洲精品bv在线观看| 国产精品丝袜白浆摸在线| 国产精品日韩一区| 国产午夜精品麻豆| 极品尤物一区二区三区| 激情久久综艺| 日韩午夜电影| 久久久国产视频91| 欧美电影专区| 一区二区三区日韩| 久久精品在这里| 免费视频久久| 国产精品高潮呻吟久久av黑人| 国产精品99一区二区| 国产一区二区三区高清| 亚洲美女毛片| 久久久久久久综合| 中文久久乱码一区二区| 久久精品国产999大香线蕉| 欧美日韩国产成人精品| 国产日韩欧美综合精品| 狠狠色狠色综合曰曰| 这里只有精品视频| 久久综合狠狠综合久久综合88| 欧美国产第一页| 午夜欧美大片免费观看| 欧美日韩亚洲综合| 狠狠色综合网站久久久久久久| 欧美一级在线播放| 久久综合中文| 亚洲综合三区| 欧美理论电影在线播放| 精品成人一区| 久久久人成影片一区二区三区观看 | 欧美日韩岛国| 国产在线一区二区三区四区| 亚洲女同同性videoxma| 欧美高清不卡| 国产亚洲一区二区三区| 亚洲一区二区在线免费观看| 亚洲国产综合在线看不卡| 久久精品国产一区二区三区免费看| 一本色道久久综合狠狠躁的推荐| 欧美成人a∨高清免费观看| 亚洲人成在线影院| 性视频1819p久久| 欧美另类在线播放| 美女精品在线观看| 亚洲免费在线精品一区| 国产欧美日韩免费| 亚洲国产精品久久久久| 国产美女精品免费电影|