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

📄 blend_anim_demo.cpp

📁 这是一个混合动画的实例代码
💻 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 + -