📄 winmain.cpp
字号:
/**************************************************
WinMain.cpp
Chapter 6 XFile/Skinned Mesh Demo
Programming Role-Playing Games with DirectX
by Jim Adams (01 Jan 2002)
Required libraries:
WINMM.LIB, D3D8.LIB, D3DX8.LIB, and DXGUID.LIB
**************************************************/
// Macro to release COM objects
#define ReleaseCOM(x) if(x) { x->Release(); x = NULL; }
// Include files
#include <windows.h>
#include <stdio.h>
#include "d3d8.h"
#include "d3dx8.h"
#include "dxfile.h"
#include "rmxfguid.h"
#include "rmxftmpl.h"
// Window handles, class and caption text
HWND g_hWnd;
HINSTANCE g_hInst;
static char g_szClass[] = "XFileClass";
static char g_szCaption[] = "XFile Demo by Jim Adams";
// The Direct3D and Device object
IDirect3D8 *g_pD3D = NULL;
IDirect3DDevice8 *g_pD3DDevice = NULL;
// A mesh definition structure
typedef struct sMesh
{
char *m_Name; // Name of mesh
ID3DXMesh *m_Mesh; // Mesh object
ID3DXSkinMesh *m_SkinMesh; // Skin mesh object
DWORD m_NumMaterials; // # materials in mesh
D3DMATERIAL8 *m_Materials; // Array of materials
IDirect3DTexture8 **m_Textures; // Array of textures
DWORD m_NumBones; // # of bones
ID3DXBuffer *m_BoneNames; // Names of bones
ID3DXBuffer *m_BoneTransforms; // Internal transformations
D3DXMATRIX *m_BoneMatrices; // X file bone matrices
sMesh *m_Next; // Next mesh in list
sMesh()
{
m_Name = NULL; // Clear all structure data
m_Mesh = NULL;
m_SkinMesh = NULL;
m_NumMaterials = 0;
m_Materials = NULL;
m_Textures = NULL;
m_NumBones = 0;
m_BoneNames = NULL;
m_BoneTransforms = NULL;
m_Next = NULL;
}
~sMesh()
{
// Free all used resources
delete [] m_Name;
ReleaseCOM(m_Mesh);
ReleaseCOM(m_SkinMesh);
delete [] m_Materials;
if(m_Textures != NULL) {
for(DWORD i=0;i<m_NumMaterials;i++) {
ReleaseCOM(m_Textures[i]);
}
delete [] m_Textures;
}
ReleaseCOM(m_BoneNames);
ReleaseCOM(m_BoneTransforms);
delete m_Next; // Delete next mesh in list
}
} sMesh;
// Structure to contain frame information
typedef struct sFrame
{
char *m_Name; // Frame's name
sMesh *m_Mesh; // Linked list of meshes
sFrame *m_Sibling; // Sibling frame
sFrame *m_Child; // Child frame
sFrame()
{
// Clear all data
m_Name = NULL;
m_Mesh = NULL;
m_Sibling = m_Child = NULL;
}
~sFrame()
{
// Delete all used resources, including linked list of frames
delete m_Name;
delete m_Mesh;
delete m_Child;
delete m_Sibling;
}
} sFrame;
// Parent frame for .X file
sFrame *g_pParentFrame = NULL;
// Function prototypes
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, \
LPSTR szCmdLine, int nCmdShow);
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, \
WPARAM wParam, LPARAM lParam);
BOOL DoInit();
BOOL DoShutdown();
BOOL DoFrame();
BOOL SetupMesh();
sFrame *LoadFile(char *Filename);
sFrame *ParseXFile(char *Filename);
void ParseXFileData(IDirectXFileData *pDataObj, sFrame *ParentFrame);
void DrawFrame(sFrame *Frame);
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, \
LPSTR szCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
MSG Msg;
g_hInst = hInst;
// Create the window class here and register it
wcex.cbSize = sizeof(wcex);
wcex.style = CS_CLASSDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_szClass;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex))
return FALSE;
// Create the Main Window
g_hWnd = CreateWindow(g_szClass, g_szCaption,
WS_CAPTION | WS_SYSMENU,
0, 0, 400, 400,
NULL, NULL,
hInst, NULL );
if(!g_hWnd)
return FALSE;
ShowWindow(g_hWnd, SW_NORMAL);
UpdateWindow(g_hWnd);
// Run init function and return on error
if(DoInit() == FALSE)
return FALSE;
// Start message pump, waiting for signal to quit
ZeroMemory(&Msg, sizeof(MSG));
while(Msg.message != WM_QUIT) {
if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
if(DoFrame() == FALSE)
break;
}
// Run shutdown function
DoShutdown();
UnregisterClass(g_szClass, hInst);
return Msg.wParam;
}
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg, \
WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
BOOL DoInit()
{
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
D3DXMATRIX matProj, matView;
// Do a windowed mode initialization of Direct3D
if((g_pD3D = Direct3DCreate8(D3D_SDK_VERSION)) == NULL)
return FALSE;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
return FALSE;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pD3DDevice)))
return FALSE;
// Set the rendering states
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
// Create and set the projection matrix
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4.0f, 1.33333f, 1.0f, 1000.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
// Create and set the view matrix
D3DXMatrixLookAtLH(&matView, \
&D3DXVECTOR3(0.0f, 50.0f, -150.0f), \
&D3DXVECTOR3(0.0f, 50.0f, 0.0f), \
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
// Load a skinned mesh from an .X file
g_pParentFrame = LoadFile("warrior.x");
return TRUE;
}
BOOL DoShutdown()
{
// Release frames and meshes
if(g_pParentFrame != NULL)
delete g_pParentFrame;
// Release device and 3D objects
if(g_pD3DDevice != NULL)
g_pD3DDevice->Release();
if(g_pD3D != NULL)
g_pD3D->Release();
return TRUE;
}
BOOL DoFrame()
{
D3DXMATRIX matWorld;
// Clear device backbuffer
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_RGBA(0,64,128,255), 1.0f, 0);
// Begin scene
if(SUCCEEDED(g_pD3DDevice->BeginScene())) {
// Set world transformation to rotate on Y-axis
D3DXMatrixRotationY(&matWorld, (float)timeGetTime() / 1000.0f);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
// Draw frames
DrawFrame(g_pParentFrame);
// Release texture
g_pD3DDevice->SetTexture(0, NULL);
// End the scene
g_pD3DDevice->EndScene();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -