⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md2file.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 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 + -