📄 blend_anim_demo.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// File: blend_anim_demo.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: Athlon 1800+ XP, 512 DDR, Radeon 9500 Pro, Windows XP, MSVC++ 7.0
//
// Desc: Driver file for the blended animation demo.
//
// Controls: The camera is setup to orbit the scene:
// Key 'W' moves the camera toward the origin.
// Key 'S' moves the camera away from the origin.
// Key 'UP Arrow' camera orbits in the up direction.
// Key 'DOWN Arrow' camera orbits in the down direction.
// Key 'LEFT Arrow' camera orbits in the left direction.
// Key 'RIGHT Arrow' camera orbits in the right direction.
//
// Press 'N' (for next) to cycle through tiny.x's _blended_
// animation sequences.
//
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <commctrl.h>
#include <cstdio>
#include <d3dx9.h>
#include "dxutil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "mlTinyx.h"
class BlendAnimDemoApp : public CD3DApplication
{
public:
BlendAnimDemoApp();
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
private:
HRESULT OneTimeSceneInit();
HRESULT InitDeviceObjects();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT DeleteDeviceObjects();
HRESULT FinalCleanup();
HRESULT FrameMove();
HRESULT Render();
HRESULT ConfirmDevice(D3DCAPS9* pCaps, DWORD dwBehavior,
D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat);
void updateFPSDisplay(float deltaTime);
private:
Tiny_X _tinyxMesh;
int _animationIndex;
D3DXMATRIX _world;
D3DXMATRIX _view;
D3DXMATRIX _proj;
D3DXMATRIX _worldViewProj;
float _rho;
float _theta;
float _phi;
};
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
BlendAnimDemoApp d3dApp;
InitCommonControls();
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
BlendAnimDemoApp::BlendAnimDemoApp()
{
m_strWindowTitle = ""; // We output frames per second to window caption.
m_d3dEnumeration.AppUsesDepthBuffer = true;
m_dwCreationWidth = 640;
m_dwCreationHeight = 480;
_animationIndex = 0;
// initial spherical coordinates
_rho = 800.0f;
_theta = 3.0f * D3DX_PI * 0.5f;
_phi = D3DX_PI / 2.0f;
}
LRESULT BlendAnimDemoApp::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
case WM_KEYDOWN:
if(wParam == 'N')
{
++_animationIndex;
if(_animationIndex >= 4)
_animationIndex = 0;
}
if(wParam == 'A') _rho += 8000.0f * m_fElapsedTime;
if(wParam == 'S') _rho -= 8000.0f * m_fElapsedTime;
if(wParam == VK_RIGHT) _theta += 50.0f * m_fElapsedTime;
if(wParam == VK_LEFT) _theta -= 50.0f * m_fElapsedTime;
if(wParam == VK_UP) _phi += 50.0f * m_fElapsedTime;
if(wParam == VK_DOWN) _phi -= 50.0f * m_fElapsedTime;
break;
};
return CD3DApplication::MsgProc(hWnd, uMsg, wParam, lParam);
}
HRESULT BlendAnimDemoApp::OneTimeSceneInit()
{
return D3D_OK;
}
HRESULT BlendAnimDemoApp::InitDeviceObjects()
{
try
{
_tinyxMesh.initDeviceObjects(m_pd3dDevice, "tiny_4anim.x");
// Tiny.x is orientated awkwardly, initially; align her body with the +y axis.
D3DXMATRIX Rx, Ry, T;
D3DXMatrixRotationX(&Rx, D3DX_PI * 0.5f);
D3DXMatrixRotationY(&Ry, D3DX_PI);
D3DXMatrixTranslation(&T, 0.0f, -200.0f, 0.0f);
_world = Ry * Rx * T;
float aspect = (float)m_d3dsdBackBuffer.Width / (float)m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovLH(&_proj, D3DX_PI * 0.25, aspect, 1.0f, 2000.0f);
}
catch(dx_err::DirectXError& e)
{
::MessageBox(0, e.getFullError().c_str(), 0, 0);
return E_FAIL;
}
return D3D_OK;
}
HRESULT BlendAnimDemoApp::RestoreDeviceObjects()
{
try
{
_tinyxMesh.restoreDeviceObjects();
}
catch(dx_err::DirectXError& e)
{
::MessageBox(0, e.getFullError().c_str(), 0, 0);
return E_FAIL;
}
return D3D_OK;
}
HRESULT BlendAnimDemoApp::InvalidateDeviceObjects()
{
try
{
_tinyxMesh.invalidateDeviceObjects();
}
catch(dx_err::DirectXError& e)
{
::MessageBox(0, e.getFullError().c_str(), 0, 0);
return E_FAIL;
}
return D3D_OK;
}
HRESULT BlendAnimDemoApp::DeleteDeviceObjects()
{
try
{
_tinyxMesh.deleteDeviceObjects();
}
catch(dx_err::DirectXError& e)
{
::MessageBox(0, e.getFullError().c_str(), 0, 0);
return E_FAIL;
}
return D3D_OK;
}
HRESULT BlendAnimDemoApp::FinalCleanup()
{
return D3D_OK;
}
HRESULT BlendAnimDemoApp::FrameMove()
{
// convert to cartesian
float cameraX = _rho * sinf(_phi) * cosf(_theta);
float cameraY = _rho * cosf(_phi);
float cameraZ = _rho * sinf(_phi) * sinf(_theta);
D3DXVECTOR3 pos( cameraX, cameraY, cameraZ);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&_view, &pos, &target, &up);
_worldViewProj = _world * _view * _proj;
switch( _animationIndex )
{
case 0:
_tinyxMesh.playWalkWaveBlend();
break;
case 1:
_tinyxMesh.playJogWaveBlend();
break;
case 2:
_tinyxMesh.playLoiterJogBlend();
break;
case 3:
_tinyxMesh.playLoiterWaveBlend();
break;
}
_tinyxMesh.frameMove(m_fElapsedTime, _worldViewProj);
updateFPSDisplay(m_fElapsedTime);
return D3D_OK;
}
HRESULT BlendAnimDemoApp::Render()
{
m_pd3dDevice->Clear(0L, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00cccccc, 1.0f, 0L);
m_pd3dDevice->BeginScene();
_tinyxMesh.render();
m_pd3dDevice->EndScene();
return D3D_OK;
}
HRESULT BlendAnimDemoApp::ConfirmDevice(D3DCAPS9* pCaps, DWORD dwBehavior,
D3DFORMAT adapterFormat,
D3DFORMAT backBufferFormat)
{
return _tinyxMesh.confirmDevice(pCaps);
}
void BlendAnimDemoApp::updateFPSDisplay(float deltaTime)
{
static float frameCount = 0;
static float timeElapsed = 0;
static float fps = 0;
static char fpsBuffer[16];
++frameCount;
timeElapsed += deltaTime;
if( timeElapsed > 1.0f ) // Only update once per second.
{
fps = frameCount / timeElapsed;
frameCount = 0.0f;
timeElapsed = 0.0f;
sprintf(fpsBuffer, "%f", fps);
std::string text0 = "www.moon-labs.com Blended Animation Demo; ";
std::string text1 = "FPS: " + std::string(fpsBuffer);
std::string text = text0 + text1;
::SetWindowText(m_hWnd, text.c_str());
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -