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

天行健 君子當自強而不息

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 閱讀(911) 評論(1)  編輯 收藏 引用

評論

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

好,努力  回復  更多評論   

公告

導航

統計

常用鏈接

隨筆分類(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>
            亚洲一区久久久| 黄色成人在线| 久久久久久一区二区| 亚洲综合视频一区| 欧美一级久久久| 久久久久久亚洲精品杨幂换脸| 久久人人爽人人爽| 欧美电影免费观看网站| 欧美激情一区二区| 国产精品高潮呻吟视频| 国产欧美日韩一级| 1024欧美极品| 在线综合+亚洲+欧美中文字幕| 午夜精品久久久久久久久久久久| 久久国产88| 亚洲黄色三级| 99国产精品国产精品久久| 午夜精品视频在线| 猛男gaygay欧美视频| 国产精品高潮呻吟久久av无限| 国产在线一区二区三区四区| 最新精品在线| 久久动漫亚洲| 中文欧美在线视频| 免费一级欧美片在线播放| 国产精品区免费视频| 亚洲国产日本| 亚洲欧美日韩国产一区二区| 你懂的视频欧美| 亚洲小说欧美另类婷婷| 久久久久久夜| 欧美日韩国产在线播放网站| 国产啪精品视频| 一区二区欧美在线| 免费观看成人网| 亚洲欧美日韩人成在线播放| 欧美日本簧片| 亚洲欧洲精品一区二区精品久久久| 欧美一级在线亚洲天堂| 亚洲欧洲一区二区三区久久| 欧美在线视频一区二区| 国产精品成人一区二区三区夜夜夜| 亚洲第一精品电影| 久久蜜桃精品| 欧美一区成人| 国产欧美日韩一级| 亚洲欧美在线一区| 夜夜爽99久久国产综合精品女不卡| 麻豆久久久9性大片| 韩日午夜在线资源一区二区| 亚洲欧美国产va在线影院| 亚洲美女黄色| 欧美日本韩国一区| 99在线|亚洲一区二区| 亚洲国产精品电影| 欧美成人一区在线| 亚洲精品乱码久久久久久蜜桃91| 麻豆精品视频| 玖玖视频精品| 亚洲二区在线| 亚洲国产精品va在看黑人| 美日韩精品免费| 亚洲精品孕妇| 99在线热播精品免费99热| 欧美色图首页| 欧美一区二区三区免费大片| 亚洲欧美综合一区| 国产一区二区三区四区老人| 久久久久久久尹人综合网亚洲 | 亚洲盗摄视频| 久久中文精品| 日韩一二三在线视频播| 亚洲免费av网站| 欧美午夜精品久久久久久孕妇 | 欧美伊人久久久久久午夜久久久久| 亚洲手机成人高清视频| 国产九九精品视频| 久久一区二区三区超碰国产精品| 久久国产一区二区| 亚洲欧洲美洲综合色网| 99精品欧美一区二区蜜桃免费| 国产精品成人一区二区艾草| 久久精品三级| 美女诱惑一区| 亚洲视频中文字幕| 欧美一区二区三区免费看| 在线亚洲欧美专区二区| 亚洲激情偷拍| 国产精品xvideos88| 久久精品人人| 欧美精品aa| 久久成人精品电影| 欧美xx69| 欧美中文字幕不卡| 欧美 日韩 国产 一区| 亚洲一区欧美激情| 久久av在线| 亚洲图片你懂的| 久久蜜桃资源一区二区老牛| 在线亚洲国产精品网站| 久久精品国亚洲| 亚洲天堂成人在线观看| 欧美在线视频a| 国产精品99久久久久久www| 久久久7777| 欧美在线视频全部完| 欧美老女人xx| 欧美黄污视频| 激情久久久久久| 亚洲欧美日韩天堂| 亚洲视频在线一区| 欧美国产亚洲精品久久久8v| 久久久久久**毛片大全| 国产精品欧美一区喷水| 亚洲精品少妇| 亚洲精品美女在线观看| 久久视频这里只有精品| 久久九九久久九九| 国产欧美日韩综合一区在线观看| 亚洲精选视频免费看| 亚洲精品一区二区三区99| 久久久久久久久伊人| 欧美在线观看视频一区二区| 欧美日韩视频免费播放| 亚洲国产精品第一区二区| 亚洲国产岛国毛片在线| 久久精品国产久精国产思思| 久久精品国产一区二区三| 国产精品一区二区三区四区| 中文一区在线| 先锋影音久久| 国产精品视区| 亚洲欧美综合另类中字| 欧美中日韩免费视频| 国产日韩在线看片| 欧美在线观看一二区| 久久久噜噜噜久噜久久| 国模套图日韩精品一区二区| 欧美淫片网站| 免费在线看成人av| 最新中文字幕亚洲| 欧美激情综合在线| 日韩一级精品视频在线观看| 亚洲在线一区二区| 国产欧美韩日| 久久久xxx| 亚洲国产天堂久久综合网| 99精品99久久久久久宅男| 欧美三级视频在线| 亚洲免费影视| 蜜桃久久av一区| 亚洲精品少妇30p| 欧美性猛交99久久久久99按摩| 亚洲综合色自拍一区| 欧美在线欧美在线| 亚洲已满18点击进入久久| 国产精品久久久久9999高清| 午夜精品成人在线| 免费欧美电影| 夜夜爽夜夜爽精品视频| 国产麻豆综合| 亚洲精品色婷婷福利天堂| 欧美一区二区视频在线观看| 国产一区激情| 欧美精品一区二区三区在线播放| 这里只有精品视频| 嫩模写真一区二区三区三州| 欧美午夜影院| 久久不射中文字幕| 亚洲福利小视频| 中日韩高清电影网| 狠狠入ady亚洲精品经典电影| 欧美大尺度在线| 亚洲欧美国产精品va在线观看| 可以免费看不卡的av网站| 六月婷婷久久| 亚洲综合久久久久| 亚洲精品免费电影| 久久综合色8888| 亚洲午夜免费福利视频| 影音先锋日韩资源| 国产精品免费电影| 欧美国产欧美亚州国产日韩mv天天看完整 | 久久精品二区亚洲w码| 亚洲国产高清视频| 久久精品中文字幕一区| 亚洲免费观看| 在线观看国产日韩| 国产麻豆综合| 欧美视频一区二区三区| 蜜臀av性久久久久蜜臀aⅴ| 亚洲免费在线视频| 日韩亚洲欧美精品| 欧美激情视频给我| 久久综合久久综合九色| 香蕉成人久久| 国产精品v欧美精品v日韩| 欧美不卡三区| 亚洲欧美精品| 夜夜嗨av一区二区三区四区|