📄 md3viewer.cpp
字号:
//-------------------------------------------------------------------------
// File: md3viewer.cpp
//
// Desc: Example code showing how to open and render
// a Quake 3 *.md3 file
//
// Last modified: 20. Dezember 2000
//
// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved.
// Copyright (c) 1999-2001 Wolfgang Engel wolf@direct3d.net
//--------------------------------------------------------------------------
#define STRICT
#include <stdio.h>
#include <windows.h>
#include <commdlg.h>
#include <D3DX8.h>
#include "D3DApp.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "resource.h"
#include "md3.h"
//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Main class to run this application. Most functionality is inherited
// from the CD3DApplication base class.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
CMD3Model* cmd3Model1;
CD3DArcBall m_ArcBall; // Mouse rotation utility
D3DXVECTOR3 m_vObjectCenter; // Center of bounding sphere of object
FLOAT m_fObjectRadius; // Radius of bounding sphere of object
CD3DFont* m_pFont; // Font for displaying help
BOOL m_bDisplayHelp;
// *.md3 file path
TCHAR m_strInitialDir[512];
TCHAR m_strFileName[512];
public:
HRESULT OneTimeSceneInit();
HRESULT InitDeviceObjects();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT DeleteDeviceObjects();
HRESULT Render();
HRESULT FrameMove();
HRESULT FinalCleanup();
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
HRESULT LoadFile(CMD3Model *model); // MD3 LoadFile dialog
CMyD3DApplication();
};
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
// message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
CMyD3DApplication d3dApp;
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Constructor
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
// Override base class members
m_strWindowTitle = _T("MD3 Viewer with D3D");
m_bUseDepthBuffer = TRUE;
m_bShowCursorWhenFullscreen = TRUE;
cmd3Model1 = new CMD3Model();
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_bDisplayHelp = FALSE;
m_fObjectRadius = 1.77f;
m_vObjectCenter = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
// Set cursor to indicate that user can move the object with the mouse
#ifdef _WIN64
SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
#else
SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)LoadCursor( NULL, IDC_SIZEALL ) );
#endif
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
// world transformation
D3DXMATRIX matRotationInverse, matWorld;
D3DXMatrixTranslation( &matWorld, -m_vObjectCenter.x,
-m_vObjectCenter.y,
-m_vObjectCenter.z );
D3DXMatrixInverse( &matRotationInverse, NULL, m_ArcBall.GetRotationMatrix() );
D3DXMatrixMultiply( &matWorld, &matWorld, &matRotationInverse );
D3DXMatrixMultiply( &matWorld, &matWorld, m_ArcBall.GetTranslationMatrix() );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Set up view matrix
D3DXMATRIX matView;
D3DXMatrixLookAtRH( &matView, &D3DXVECTOR3( 0, 0,-48*m_fObjectRadius ),
&D3DXVECTOR3( 0, 0, 0 ),
&D3DXVECTOR3( 0, 1, 0 ) );
/* To switch to a right handed coordinate system like in OpenGL, we have to
flip the sign of the _31, _32, _33, and _34 member of the D3DXMATRIX.
*/
matView._31 = -matView._31;
matView._32 = -matView._32;
matView._33 = -matView._33;
matView._34 = -matView._34;
m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
// rendering. This function sets up render states, clears the
// viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
// Clear the backbuffer
m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0x00000000, 1.0f, 0x00000000);
// set wireframe view
// m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME);
// Begin scene rendering
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
{
cmd3Model1->Render(m_pd3dDevice);
// Output statistics
m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats);
m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats);
// End the scene rendering
m_pd3dDevice->EndScene();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
// Initialize the font
m_pFont->InitDeviceObjects( m_pd3dDevice );
// Load a *.md3 file the first time around
static BOOL bFirstInstance = TRUE;
if( bFirstInstance )
{
Pause( TRUE );
LoadFile(cmd3Model1);
Pause( FALSE );
bFirstInstance = FALSE;
}
else
{
cmd3Model1->InitDeviceObjects( m_pd3dDevice );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
m_pFont->RestoreDeviceObjects();
D3DMATERIAL8 mtrl;
D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
m_pd3dDevice->SetMaterial( &mtrl );
// Setup render state
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
// Setup the light
D3DLIGHT8 light;
D3DUtil_InitLight(light, D3DLIGHT_DIRECTIONAL, 0.0f, -0.5f, 1.0f );
m_pd3dDevice->SetLight(0, &light );
m_pd3dDevice->LightEnable(0, TRUE );
m_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00333333);
// Set the arcball parameters
m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height,
0.85f );
m_ArcBall.SetRadius( m_fObjectRadius );
// Set the projection matrix
D3DXMATRIX matProj;
FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovRH( &matProj, D3DX_PI/4, fAspect, m_fObjectRadius/64.0f,
m_fObjectRadius*200.0f);
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
m_pFont->InvalidateDeviceObjects();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
// this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
m_pFont->DeleteDeviceObjects();
cmd3Model1->DeleteDeviceObjects();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
SAFE_DELETE( m_pFont );
SAFE_DELETE(cmd3Model1);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Message proc function to handle key and menu input
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam )
{
// Pass mouse messages to the ArcBall so it can build internal matrices
m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
// Trap the context menu
if( uMsg == WM_CONTEXTMENU )
return 0;
if( uMsg == WM_COMMAND )
{
// Handle the open file dialog
if( LOWORD(wParam) == IDM_OPENFILE)
{
Pause( TRUE );
LoadFile(cmd3Model1);
Pause( FALSE );
}
}
return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: LoadFile()
// Desc: Uses Windows' OpenFileName dialog to get the name of an X file to
// load, then proceeds to load that file.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::LoadFile(CMD3Model *model)
{
TCHAR strCurrentName[512] = "*.md3";
OPENFILENAME ofn = { sizeof(OPENFILENAME), m_hWnd, NULL,
"MD3 Files (*.md3)\0*.md3\0\0",
NULL, 0, 1, strCurrentName, 512, m_strFileName, 512,
m_strInitialDir, "Open MD3 File", OFN_FILEMUSTEXIST, 0, 1,
".md3", 0, NULL, NULL };
// Run the OpenFileName dialog.
if( FALSE == GetOpenFileName( &ofn ) )
return E_FAIL;
// Store the initial directory for next time
strcpy (m_strInitialDir, strCurrentName );
strstr (m_strInitialDir, m_strFileName )[0] = '\0';
if( FAILED (model->CreateModel(m_strFileName, m_pd3dDevice) ) )
{
MessageBox( NULL, TEXT("Error loading specified MD3 file"),
TEXT("MD3 Viewer"), MB_OK|MB_ICONERROR );
return E_FAIL;
}
// Return successful
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -