Fireworks.cpp
资源名称:DXGuide.zip [点击查看]
上传用户:wymy58
上传日期:2007-01-07
资源大小:2086k
文件大小:11k
源码类别:
DirextX编程
开发平台:
Visual C++
- // Fireworks.cpp : Defines the class behaviors for the application.
- #include "stdafx.h"
- #include "Fireworks.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- const bool g_bFullScreen
- #ifdef _DEBUG
- = false; // true;
- #else
- = true; // false;
- #endif // _DEBUG
- const bool g_bUseZBuffer = false;
- const DWORD g_dwWidth = 640; // 800; // 1024;
- const DWORD g_dwHeight = 480; // 600; // 768;
- const DWORD g_dwBPP = 16; // 32;
- const bool g_bUseVoodoo12 = false; // true;
- const _GUID* const g_lpGuidD3DDevice
- = NULL;
- // = &IID_IDirect3DTnLHalDevice;
- // = &IID_IDirect3DRGBDevice;
- // = &IID_IDirect3DHALDevice;
- // = &IID_IDirect3DRefDevice;
- #define rnd() (((FLOAT)rand() - (FLOAT)rand()) / (2L * RAND_MAX))
- #define RND() (((FLOAT)rand()) / RAND_MAX)
- // Data structure for each particle
- struct Particle
- {
- D3DVECTOR dvPosition;
- D3DVECTOR dvLaunchVelocity;
- D3DVECTOR dvInitialPosition;
- D3DVECTOR dvInitialVelocity;
- FLOAT r, g, b;
- FLOAT fLifetime;
- FLOAT fMaturity;
- WORD wType;
- FLOAT fSize;
- };
- #define NUM_PARTICLES 100
- Particle g_Particle[NUM_PARTICLES]; // Array of particles
- D3DVERTEX g_Mesh[4]; // Vertices used to render particles
- D3DTLVERTEX g_Background[4]; // Vertices used to render the backdrop
- FLOAT g_fStartTimeKey = 0.0f; // Time reference for calculations
- // Initialize a particle
- Particle SetParticle(WORD wType, FLOAT fLifeTime, D3DVECTOR vBasePosition,
- D3DVECTOR vBaseVelocity)
- {
- Particle ret;
- ret.dvInitialVelocity = 15 * ::Normalize(D3DVECTOR(rnd(), rnd(), rnd()));
- ret.dvInitialVelocity += vBaseVelocity + D3DVECTOR(rnd(), rnd(), rnd());
- ret.dvInitialPosition = vBasePosition;
- ret.dvLaunchVelocity = vBaseVelocity;
- ret.r = 1.0f;
- ret.g = 1.0f;
- ret.b = 1.0f;
- ret.fLifetime = fLifeTime + fLifeTime * rnd() / 2;
- ret.fMaturity = 0.0f;
- ret.fSize = 0.2f;
- ret.wType = wType;
- return ret;
- }
- CFireworksApp::CFireworksApp(void)
- {
- m_dwAppInitFlags &= ~CDirectXApp::DXAPPIF_DD;
- m_dwAppInitFlags |= CDirectXApp::DXAPPIF_D3DIM;
- SetFullScreen(g_bFullScreen);
- SetPackFileName(_T("Data"), _T("Data"));
- // Called during initial app startup, this function
- // performs all the permanent initialization.
- m_pD3DDevice = NULL;
- m_pD3DMaterial = NULL;
- // add your permanent init code here !
- m_pLakeTexture = NULL;
- m_pFireworkTexture = NULL;
- }
- // Called before the app exits, this function gives the app
- // the chance to cleanup after itself.
- CFireworksApp::~CFireworksApp()
- {
- // add your cleaup code here !
- }
- bool CFireworksApp::GetDXInitSettings(void)
- {
- if (m_pDirectSound != NULL)
- {
- if (m_pDirectSound->SelectDSDriver(0) == false)
- return false;
- }
- if (m_pDirectMusic != NULL)
- {
- if (m_pDirectMusic->SelectDefaultDMusPort() == false)
- return false;
- }
- if ((g_bUseVoodoo12 == false)
- || m_pDirectDraw->SelectDDDevice(0, 1) == false)
- {
- if (m_pDirectDraw->SelectDDDevice(0) == false)
- return false;
- }
- if (g_bUseZBuffer)
- m_dwDDInitFlags |= CDDDevice::D3DIF_ZBUFFER;
- if (GetFirstDDDevice()->IsCanRenderWindowed() == false)
- {
- m_dwDDInitFlags &= ~CDDDevice::DDIF_WINDOWED;
- m_dwDDInitFlags &= ~CDDDevice::DDIF_NO_FLIP;
- }
- else
- {
- m_dwDDInitFlags |= CDDDevice::DDIF_NO_FLIP;
- }
- if (g_lpGuidD3DDevice == NULL)
- {
- if (GetFirstDDDevice()->SelectDefaultD3DDevice() == false)
- return false;
- }
- else
- {
- if (GetFirstDDDevice()->SelectD3DDevice(g_lpGuidD3DDevice) == false)
- return false;
- }
- if (GetFirstDDDevice()->SelectDisplayMode(
- IsFullScreen(), g_dwWidth, g_dwHeight, g_dwBPP) == false)
- return false;
- return true;
- }
- // Called during device intialization, this code checks the device
- // for some minimum set of capabilities, Initialize scene objects.
- bool CFireworksApp::InitDXObjects(void)
- {
- m_pD3DDevice = GetFirstD3DDevice();
- ASSERT(m_pD3DDevice != NULL);
- m_pD3DMaterial = m_pD3DDevice->GetD3DMaterial();
- // add your init code here !
- D3DPRIMCAPS const* pdpc = m_pD3DDevice->GetTriCaps();
- if ((pdpc->dwSrcBlendCaps & pdpc->dwDestBlendCaps & D3DBLEND_ONE) == 0)
- return false;
- // Initialize the array of particles
- for (WORD i = 0; i < NUM_PARTICLES; ++ i)
- g_Particle[i] = SetParticle(WORD(i % 3), 4.0f, D3DVECTOR(0, 0, 0),
- D3DVECTOR(0, 30, 0));
- // Initializes vertices used to render the particles
- D3DVECTOR dvNorm = D3DVECTOR(0.0f, 0.0f, 1.0f);
- g_Mesh[0] = D3DVERTEX(D3DVECTOR(-1.0f, -1.0f, 0.0f), dvNorm, 0.0f, 1.0f);
- g_Mesh[1] = D3DVERTEX(D3DVECTOR(-1.0f, 1.0f, 0.0f), dvNorm, 0.0f, 0.0f);
- g_Mesh[2] = D3DVERTEX(D3DVECTOR(1.0f, -1.0f, 0.0f), dvNorm, 1.0f, 1.0f);
- g_Mesh[3] = D3DVERTEX(D3DVECTOR(1.0f, 1.0f, 0.0f), dvNorm, 1.0f, 0.0f);
- // Initializes vertices used to render the background
- g_Background[0] = D3DTLVERTEX(D3DVECTOR(0, 0, 0.5), 0.5, D3DRGB(1, 1, 1), 0, 0, 1);
- g_Background[1] = D3DTLVERTEX(D3DVECTOR(0, 0, 0.5), 0.5, D3DRGB(1, 1, 1), 0, 0, 0);
- g_Background[2] = D3DTLVERTEX(D3DVECTOR(0, 0, 0.5), 0.5, D3DRGB(1, 1, 1), 0, 1, 1);
- g_Background[3] = D3DTLVERTEX(D3DVECTOR(0, 0, 0.5), 0.5, D3DRGB(1, 1, 1), 0, 1, 0);
- // Load in textures
- m_pLakeTexture = new CD3DTexture;
- if (m_pLakeTexture->Create(m_pD3DDevice, _T("lake.bmp"), m_pPackFileManager, 0, 0) == false)
- {
- return false;
- }
- m_pFireworkTexture = new CD3DTexture;
- if (m_pFireworkTexture->Create(m_pD3DDevice, _T("firework.bmp"), m_pPackFileManager, 0, 0) == false)
- {
- return false;
- }
- // Initialize scene objects
- // Set up the dimensions for the background image
- g_Background[0].sy = (FLOAT)m_pD3DDevice->GetHeight();
- g_Background[2].sy = (FLOAT)m_pD3DDevice->GetHeight();
- g_Background[2].sx = (FLOAT)m_pD3DDevice->GetWidth();
- g_Background[3].sx = (FLOAT)m_pD3DDevice->GetWidth();
- // Set the transform matrices
- D3DVECTOR dvEyePt = D3DVECTOR(0.0f, 0.0f, -20.0f);
- D3DVECTOR dvLookatPt = D3DVECTOR(0.0f, 0.0f, 0.0f);
- D3DVECTOR dvUpVec = D3DVECTOR(0.0f, 0.0f, 1.0f);
- CD3DMatrix matView;
- matView.SetView(dvEyePt, dvLookatPt, dvUpVec);
- CD3DMatrix matProj;
- matProj.SetProjection(1.57f, 1.0f, 1.0f, 100.0f);
- m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView);
- m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &matProj);
- // Set any appropiate state
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xFFFFFFFF);
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE);
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE);
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
- m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
- return true;
- }
- // Called when the app is exitting, or the device is being changed,
- // this function deletes any device dependant objects.
- bool CFireworksApp::DestroyDXObjects(void)
- {
- // add your destroy code here !
- if (m_pLakeTexture != NULL)
- {
- delete m_pLakeTexture;
- m_pLakeTexture = NULL;
- }
- if (m_pFireworkTexture != NULL)
- {
- delete m_pFireworkTexture;
- m_pFireworkTexture = NULL;
- }
- m_pD3DMaterial = NULL;
- m_pD3DDevice = NULL;
- return CDirectXApp::DestroyDXObjects();
- }
- // Called once per frame, the call is the entry point for
- // animating the scene. This function sets up render states,
- // clears the viewport, and renders the scene.
- bool CFireworksApp::UpdateFrame(void)
- {
- // add your code here !
- // Get the relative time, in seconds
- FLOAT fTimeKey = ::timeGetTime() * 0.001f;
- D3DVECTOR a0 = D3DVECTOR( 0.0, -9.8f, 0.0f );
- FLOAT t = fTimeKey - g_fStartTimeKey;
- FLOAT k = 1.8f;
- DWORD dwNumOldParticles = 0L;
- // Store the particles positions
- for (DWORD i = 0; i < NUM_PARTICLES; ++ i)
- {
- if (t < 0.0f) // Particle is in "launch" mode
- {
- D3DVECTOR v0 = g_Particle[i].dvLaunchVelocity;
- D3DVECTOR r0 = g_Particle[i].dvInitialPosition;
- g_Particle[i].dvPosition = r0 + v0*(t-RND()/10)/1.5f;
- }
- else // Particle is in "explode" mode
- {
- D3DVECTOR v0 = g_Particle[i].dvInitialVelocity;
- D3DVECTOR r0 = g_Particle[i].dvInitialPosition;
- FLOAT fDamping = (1.0f - (FLOAT)exp(-k * t)) / (k * k);
- g_Particle[i].dvPosition = r0 + a0 * t / k + (k * v0 + a0) * fDamping;
- g_Particle[i].fMaturity = t / g_Particle[i].fLifetime;
- FLOAT st = g_Particle[i].fMaturity + 0.5f;
- g_Particle[i].r = (FLOAT)exp(-0.5f * st * st);
- g_Particle[i].g = (FLOAT)exp(-1.8f * st * st);
- g_Particle[i].b = (FLOAT)exp(-2.0f * st * st);
- g_Particle[i].fSize = (FLOAT)exp(-1.0f * st * st);
- if (g_Particle[i].fMaturity > 1.0f)
- ++ dwNumOldParticles;
- }
- }
- if (NUM_PARTICLES == dwNumOldParticles)
- {
- g_fStartTimeKey = fTimeKey + 1.0f;
- D3DVECTOR dvLaunchVelocity = D3DVECTOR(40.0f * rnd(), 30.0f, 0.0f);
- for (WORD i = 0; i < NUM_PARTICLES; i ++)
- g_Particle[i] = SetParticle(WORD(i % 3), 4.0f, D3DVECTOR(0,0,0),
- dvLaunchVelocity);
- }
- // Begin the scene
- if (SUCCEEDED(m_pD3DDevice->BeginScene()))
- {
- // code !
- // Draw the background
- m_pLakeTexture->SetAsCurrent();
- m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
- D3DFVF_TLVERTEX, g_Background, 4, 0);
- // Render the particles
- RenderParticles();
- // End the scene.
- m_pD3DDevice->EndScene();
- }
- return CDirectXApp::UpdateFrame();
- }
- // ---- add your functions ! ----
- // Draws the system of particles
- void CFireworksApp::RenderParticles(void)
- {
- // Turn on alpha blending for the particles
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
- m_pFireworkTexture->SetAsCurrent();
- D3DCOLORVALUE dcvColor;
- dcvColor.dvA = 0.0f;
- // Do the particles
- for (DWORD i = 0; i < NUM_PARTICLES; ++ i)
- {
- if (g_Particle[i].fMaturity > 1.0f)
- continue;
- // Set up the emissive color of the particle
- m_pD3DMaterial->SetColor(g_Particle[i].r, g_Particle[i].g, g_Particle[i].b, 0.0f, D3D_M_EMISSIVE);
- m_pD3DMaterial->Set();
- // Translate and scale the world matrix for each particle
- CD3DMatrix matWorld;
- matWorld.SetTranslate(g_Particle[i].dvPosition);
- matWorld._11 = g_Particle[i].fSize;
- matWorld._22 = g_Particle[i].fSize;
- // Set the new world transform and render the particle
- m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorld);
- m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX,
- g_Mesh, 4, 0);
- }
- // Restore the material and states
- m_pD3DMaterial->SetColor(1.0f, 1.0f, 1.0f, 0.0f, D3D_M_EMISSIVE);
- m_pD3DMaterial->Set();
- m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
- }
- // ----
- #if _MSC_VER >= 1200 && _MSC_VER < 1400
- #ifdef _DEBUG
- #pragma comment(lib, "DXGuideD_VC6.lib")
- #else
- #pragma comment(lib, "DXGuide_VC6.lib")
- #endif // _DEBUG
- #endif // _MSC_VER
- #if _MSC_VER >= 1000 && _MSC_VER < 1200
- #ifdef _DEBUG
- #pragma comment(lib, "DXGuideD_VC5.lib")
- #else
- #pragma comment(lib, "DXGuide_VC5.lib")
- #endif // _DEBUG
- #endif // _MSC_VER
- BEGIN_MESSAGE_MAP(CFireworksApp, CDirectXApp)
- //{{AFX_MSG_MAP(CFireworksApp)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- CFireworksApp theApp;