📄 md2file.cpp
字号:
// Md2File.cpp file implement.
#include "stdafx.h"
#include "Md2File.h"
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#pragma comment(lib,"d3d8.lib")
#pragma comment(lib,"d3dx8.lib")
#pragma comment(lib,"winmm.lib")
enum Tris_State{
STAND = 0,
RUN,ATTACK,PAIN,JUMP,FLIP,SALUTE,TAUNT,WAVE,POINTDIR,CRSTAND,
CRWALK,CRATTACK,CRPAIN,CRDEATH,DEATH,
};
TCHAR * g_astrTrisState[]=
{
_T("Standing"),_T("Running"),_T("Attacking"),_T("Paining"),_T("Jumping"),
_T("Fliping"),_T("Saluting"),_T("Taunting"),
_T("Waving"),_T("Pointing"),
_T("CrStanding"),_T("CrWalking"),_T("CrAttacking"),
_T("CrPaining"),_T("CrDeathing"),_T("Deathing"),NULL
};
////////////////////////////////////////////////////////////////////////
LPDIRECT3D8 g_pd3d = NULL;
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER8 g_pVBPos = 0;
LPDIRECT3DTEXTURE8 g_pTex = 0;
////////////////////////////////////////////////////////////////////////
TCHAR g_strInitialDir[MAX_PATH] = _T("");
TCHAR g_strMd2FileName[256] = _T("");
float g_Interpolate,g_Speed;
UINT g_StartFrame,g_CurrentFrame,g_EndFrame;
DWORD g_dwStartTime;
//////////////////////////////////////////////////////////////////////////
Md2Header_t g_Md2Header;
Md2FrameVector_t g_Md2FramesVector; //帧容器
Md2TexCoordVector_t g_Md2TexCoordVector;
Md2TriangleVector_t g_Md2TriangleVector;
Md2SkinNameVector_t g_Md2SkinNameVector;
//////////////////////////////////////////////////////////////////////////
//...消息函数.
///////////////////////////////////////////////////////////////////////////
// 函数:DlgProc()
// 描述:....
///////////////////////////////////////////////////////////////////////////
BOOL WINAPI DlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hwnd,WM_INITDIALOG,Dlg_OnInitDialog);
HANDLE_MSG(hwnd,WM_COMMAND,Dlg_OnCommand);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Dlg_OnInitDialog()
// 描述:....
///////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
SetWindowText(hwnd,_T("MD2"));
for( TCHAR** pstrTrisState = g_astrTrisState; *pstrTrisState; pstrTrisState++ )
{
ComboBox_AddString(GetDlgItem(hwnd,IDC_MD2_FRAME_NAME),*pstrTrisState );
}
ComboBox_SetCurSel(GetDlgItem(hwnd,IDC_MD2_FRAME_NAME),0);
Edit_LimitText(GetDlgItem(hwnd,IDC_MD2_SPEED),4);
Md2_SetState(0);
Md2_Init3DEntironment(GetDlgItem(hwnd,IDC_MD2_SHOW));
SetDlgItemInt(hwnd,IDC_MD2_VERTICES,g_Md2Header.m_iNumVertices,1);
SetDlgItemInt(hwnd,IDC_MD2_FRAMES,g_Md2Header.m_iNumFrames,1);
SetDlgItemInt(hwnd,IDC_MD2_SPEED,240,1);
g_dwStartTime = timeGetTime();
return 1;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Dlg_OnCommand()
// 描述:....
///////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDCANCEL:
PostQuitMessage(0);break;
case IDC_MD2_FRAME_NAME:
if (codeNotify == CBN_SELCHANGE )
{
Md2_SetState(ComboBox_GetCurSel(GetDlgItem(hwnd,IDC_MD2_FRAME_NAME)));
break;
}
case IDC_MD2_SPEED:
if (codeNotify == EN_CHANGE )
{
g_Speed = (float)GetDlgItemInt(hwnd,IDC_MD2_SPEED,0,1)/10.0f;
break;
}
default:break;
}
return 1;
}
///////////////////////////////////////////////////////////////////////////
//...功能函数.
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_Init3DEntironment()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_Init3DEntironment(HWND hwnd)
{
RECT rcClientRect;
long Width,Height;
GetClientRect(hwnd,&rcClientRect);
Width = rcClientRect.right - rcClientRect.left;
Height = rcClientRect.bottom - rcClientRect.top;
g_pd3d = Direct3DCreate8(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
g_pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
// 设置D3DPRESENT_PARAMETERS.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.hDeviceWindow = hwnd;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// 创建Device.
g_pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice);
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, (float)Width/Height, 1.0f, 2000.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0, 0.0f, -100.0f),
&D3DXVECTOR3(0, 0, 0),
&D3DXVECTOR3(0, 1, 0));
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xFFFFFFFF);
g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);
Md2_Parse("tris.md2");
g_pd3dDevice->CreateVertexBuffer(g_Md2Header.m_iNumTriangles*5*sizeof(float)*3,
0,D3DFVF_XYZ|D3DFVF_TEX1,D3DPOOL_MANAGED,&g_pVBPos);
D3DXCreateTextureFromFile(g_pd3dDevice,"tex.tga",&g_pTex);
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_Shutdown()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_Shutdown()
{
SAFE_RELEASE(g_pVBPos);
SAFE_RELEASE(g_pTex);
SAFE_RELEASE(g_pd3dDevice);
SAFE_RELEASE(g_pd3d);
g_Md2SkinNameVector.clear();
g_Md2TriangleVector.clear();
g_Md2TexCoordVector.clear();
g_Md2FramesVector.clear();
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_Render()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_Render()
{
D3DXMATRIX mat;
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0x33, 0x66, 0x99), 1.0f, 0);
g_pd3dDevice->BeginScene();
D3DXMatrixIdentity(&mat);
D3DXMatrixRotationY(&mat,timeGetTime()/1000.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&mat);
Md2_DrawFrame(timeGetTime(),g_Speed);
g_pd3dDevice->SetTexture(0,g_pTex);
g_pd3dDevice->SetVertexShader(D3DFVF_XYZ|D3DFVF_TEX1);
g_pd3dDevice->SetStreamSource(0, g_pVBPos, sizeof(float)*5);
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, g_Md2Header.m_iNumTriangles);
g_pd3dDevice->SetTexture(0,NULL);
g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_Parse()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_Parse(TCHAR * strFileName)
{
int i = 0,j = 0;
unsigned short Tex[2];
unsigned char Verts[4];
FILE *f = _tfopen(strFileName,"rb");
if ( f )
{
// Read Md2Header Info.
fread(&g_Md2Header,sizeof(Md2Header_t),1,f);
if ( g_Md2Header.m_iMagicNum != 0x32504449 )
{
fclose(f);
return E_FAIL;
}
// Alloc component space.
g_Md2SkinNameVector.resize(g_Md2Header.m_iNumSkins);
g_Md2TexCoordVector.resize(g_Md2Header.m_iNumCoordinates);
g_Md2TriangleVector.resize(g_Md2Header.m_iNumTriangles);
g_Md2FramesVector.resize(g_Md2Header.m_iNumFrames );
// Read texture coordinates.
fseek(f,g_Md2Header.m_iOffsetTexCoors,SEEK_SET);
for (i = 0; i< g_Md2Header.m_iNumCoordinates; i++)
{
fread(Tex,sizeof(short),2,f);
g_Md2TexCoordVector[i].m_fTex[0] = (float)Tex[0]/g_Md2Header.m_iSkinWidthPx;
g_Md2TexCoordVector[i].m_fTex[1] = (float)Tex[1]/g_Md2Header.m_iSkinHeightPx;
}
// Read frames.
fseek(f,g_Md2Header.m_iOffsetFrames,SEEK_SET);
for ( i = 0; i<g_Md2Header.m_iNumFrames;i++)
{
fread(g_Md2FramesVector[i].m_fScale,sizeof(float),3,f);
fread(g_Md2FramesVector[i].m_fTrans,sizeof(float),3,f);
fread(g_Md2FramesVector[i].m_caName,1,16,f);
g_Md2FramesVector[i].m_pVertices.resize(g_Md2Header.m_iNumVertices);
for ( j = 0; j < g_Md2Header.m_iNumVertices; j++)
{
// Decompression vertices.
fread(Verts, sizeof(char),4, f);
g_Md2FramesVector[i].m_pVertices[j].m_fVert[0] = Verts[0]*g_Md2FramesVector[i].m_fScale[0]+g_Md2FramesVector[i].m_fTrans[0];
g_Md2FramesVector[i].m_pVertices[j].m_fVert[1] = Verts[1]*g_Md2FramesVector[i].m_fScale[1]+g_Md2FramesVector[i].m_fTrans[1];
g_Md2FramesVector[i].m_pVertices[j].m_fVert[2] = Verts[2]*g_Md2FramesVector[i].m_fScale[2]+g_Md2FramesVector[i].m_fTrans[2];
}
}
// Read triangles.
fseek(f,g_Md2Header.m_iOffsetTriangles,SEEK_SET);
for (i = 0; i<g_Md2Header.m_iNumTriangles;i++)
{
fread(g_Md2TriangleVector[i].m_sVertIndices,1,sizeof(short)*3,f);
fread(g_Md2TriangleVector[i].m_sTexIndices,1,sizeof(short)*3,f);
}
// Read skin.
fseek(f,g_Md2Header.m_iOffsetSkins,SEEK_SET);
for (i = 0; i<g_Md2Header.m_iNumSkins;i++)
{
fread(g_Md2SkinNameVector[i].Skinname,1,sizeof(TCHAR)*256,f);
}
}
fclose(f);
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_DrawFrame()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_DrawFrame(DWORD NowTime,float Speed)
{
float * Ptr;
g_Interpolate = (float)(NowTime-g_dwStartTime)*0.001f * Speed / (g_EndFrame-g_StartFrame);
if(g_Interpolate >1.0f)
{
while (g_Interpolate >=1.0f)
{
g_Interpolate -= 1.0f;
g_CurrentFrame++;
}
g_dwStartTime = NowTime;
if (g_CurrentFrame >= g_EndFrame)
{
g_CurrentFrame = g_StartFrame;
}
}
Md2Frame_t * pStartFrame = &g_Md2FramesVector[g_CurrentFrame];
Md2Frame_t * pEndFrame = &g_Md2FramesVector[g_CurrentFrame+1];
g_pVBPos->Lock(0,0,(BYTE**)&Ptr,0);
for ( int i = 0; i<g_Md2Header.m_iNumTriangles; ++i)
{
Md2Triangle_t & pTriangle = g_Md2TriangleVector[i];
for (int k = 0;k<3;k++)
{
Md2Vertex_t &v0 = pStartFrame->m_pVertices[pTriangle.m_sVertIndices[k]];
Md2Vertex_t &v1 = pEndFrame->m_pVertices[pTriangle.m_sVertIndices[k]];
Md2TexCoord_t &t = g_Md2TexCoordVector[pTriangle.m_sTexIndices[k]];
*Ptr++ = v0.m_fVert[0]+g_Interpolate * (v1.m_fVert[0] - v0.m_fVert[0]);
*Ptr++ = v0.m_fVert[2]+g_Interpolate * (v1.m_fVert[2] - v0.m_fVert[2]);
*Ptr++ = v0.m_fVert[1]+g_Interpolate * (v1.m_fVert[1] - v0.m_fVert[1]);
*Ptr++ = t.m_fTex[0];
*Ptr++ = t.m_fTex[1];
}
}
g_pVBPos->Unlock();
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
// 函数:Md2_DrawFrame()
// 描述:....
///////////////////////////////////////////////////////////////////////////
HRESULT Md2_SetState(UINT State)
{
switch(State)
{
case STAND:
g_StartFrame = 0;
g_CurrentFrame = 0;
g_EndFrame = 39;break;
case RUN:
g_StartFrame = 40;
g_CurrentFrame = 40;
g_EndFrame = 45;break;
case ATTACK:
g_StartFrame = 46;
g_CurrentFrame = 46;
g_EndFrame = 53;break;
case PAIN:
g_StartFrame = 54;
g_CurrentFrame = 54;
g_EndFrame = 65;break;
case JUMP:
g_StartFrame = 66;
g_CurrentFrame = 66;
g_EndFrame = 71;break;
case FLIP:
g_StartFrame = 72;
g_CurrentFrame = 72;
g_EndFrame = 83;break;
case SALUTE:
g_StartFrame = 84;
g_CurrentFrame = 84;
g_EndFrame = 94;break;
case TAUNT:
g_StartFrame = 95;
g_CurrentFrame = 95;
g_EndFrame = 111;break;
case WAVE:
g_StartFrame = 112;
g_CurrentFrame = 112;
g_EndFrame = 122;break;
case POINTDIR:
g_StartFrame = 123;
g_CurrentFrame = 123;
g_EndFrame = 134;break;
case CRSTAND:
g_StartFrame = 135;
g_CurrentFrame = 135;
g_EndFrame = 153;break;
case CRWALK:
g_StartFrame = 154;
g_CurrentFrame = 154;
g_EndFrame = 159;break;
case CRATTACK:
g_StartFrame = 160;
g_CurrentFrame = 160;
g_EndFrame = 168;break;
case CRPAIN:
g_StartFrame = 169;
g_CurrentFrame = 169;
g_EndFrame = 172;break;
case CRDEATH:
g_StartFrame = 173;
g_CurrentFrame = 173;
g_EndFrame = 177;break;
case DEATH:
g_StartFrame = 178;
g_CurrentFrame = 178;
g_EndFrame = 197;break;
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -