#include "dxstdafx.h" #include "media.h" #include ".\Explosion.h" Explosion::Explosion(void) { pSys.addSystem(PARTICLE_SYSTEM_1, true, D3DCOLOR_COLORVALUE(1.0f, 0.0f, 0.0f, 1.0f), 1.8, 2.2); pSys.addSystem(PARTICLE_SYSTEM_2, false, D3DCOLOR_COLORVALUE( 0.0f, 1.0f, 0.0f, 0.2f), 2.8, 3.5); pSys.addSystem(PARTICLE_SYSTEM_3, false, D3DCOLOR_COLORVALUE(0.0f, 0.0f, 1.0f, 0.015f), 9.0, 10.2); } Explosion::~Explosion(void) { } void Explosion::OnCreateDevice( IDirect3DDevice9* pd3dDevice) { this->pd3dDevice = pd3dDevice; mesh = new Mesh(SCENE_MESH, 1, D3DXVECTOR3(0,0,0)); ID3DXBuffer* errBuff = NULL; if( FAILED(D3DXCreateEffectFromFile( pd3dDevice, L"Media//Shaders/Scene.fx", NULL, NULL, NULL, NULL, &g_pEffect, &errBuff ))) { int BufSize = errBuff->GetBufferSize(); // displaying error message of arbitrary length wchar_t* wbuf = new wchar_t[BufSize]; mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize ); MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR); // show error message delete wbuf; exit(-1); } pSys.OnCreateDevice(pd3dDevice); } void Explosion::OnDestroyDevice() { delete mesh; SAFE_RELEASE( g_pEffect ); pSys.OnDestroyDevice(); } void Explosion::OnResetDevice(const D3DSURFACE_DESC* pBackBufferDesc ) { m_ScreenWidth = pBackBufferDesc->Width; m_ScreenHeight = pBackBufferDesc->Height; if( g_pEffect ) g_pEffect->OnResetDevice(); D3DXCreateTextureFromFile( pd3dDevice, COLOR_TEXTURE_PATH, &ColorTexture ); FrameBufferTexture = new CDXTexture(); if (!FrameBufferTexture->InitTex(pd3dDevice, "framebuffer", m_ScreenWidth, m_ScreenHeight, D3DFMT_A16B16G16R16F, false)) { MessageBox(NULL, L"FrameBufferTexture creation failed!",L"", MB_OK); } ParticleTexture = new CDXTexture(); createParticleTex(); PhaseTexture = new CDXTexture(); if (!PhaseTexture->InitTex(pd3dDevice, "phaseTexture", 256, 256, D3DFMT_A16B16G16R16F, false)) { MessageBox(NULL, L"PhaseTexture creation failed!",L"", MB_OK); } phaseCreated = false; pSys.setScreenDimensions(m_ScreenWidth, m_ScreenHeight); // create vertex buffer for full-screen quad pd3dDevice->CreateVertexBuffer(sizeof(float) * 18, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &FullScreenQuad, 0); float* snipet; FullScreenQuad->Lock(0, 0, (void**)&snipet, D3DLOCK_DISCARD); int index = 0; snipet[index++] = -1; snipet[index++] = -1; snipet[index++] = 0; snipet[index++] = 1; snipet[index++] = 1; snipet[index++] = 0; snipet[index++] = 1; snipet[index++] = -1; snipet[index++] = 0; snipet[index++] = -1; snipet[index++] = -1; snipet[index++] = 0; snipet[index++] = -1; snipet[index++] = 1; snipet[index++] = 0; snipet[index++] = 1; snipet[index++] = 1; snipet[index++] = 0; FullScreenQuad->Unlock(); pSys.OnResetDevice(); } void Explosion::OnLostDevice() { if( g_pEffect ) g_pEffect->OnLostDevice(); SAFE_RELEASE(ColorTexture); SAFE_RELEASE(FullScreenQuad); delete FrameBufferTexture; destroyParticleTex(); delete PhaseTexture; pSys.OnLostDevice(); } void Explosion::destroyParticleTex() { delete ParticleTexture; delete HeatTexture; } void Explosion::createParticleTex() { int width, height; int ratio = params->GetInt(fTexRatio); lastRatio = ratio; float r = pow(2.0, ratio); r = 1.0 / r; width = m_ScreenWidth * r; height = m_ScreenHeight * r; ParticleTexture = new CDXTexture(); if (!ParticleTexture->InitTex(pd3dDevice, "particleColor", width, height, D3DFMT_A16B16G16R16F, false)) { MessageBox(NULL, L"ParticleColorTexture creation failed!",L"", MB_OK); } HeatTexture = new CDXTexture(); if (!HeatTexture->InitTex(pd3dDevice, "particleHeat", width, height, D3DFMT_A16B16G16R16F, false)) { MessageBox(NULL, L"ParticleHeatTexture creation failed!",L"", MB_OK); } } void Explosion::slidersChanged() { int ratio = params->GetInt(fTexRatio); if(ratio != lastRatio) { destroyParticleTex(); createParticleTex(); } } void Explosion::renderPhaseTexture() { PhaseTexture->StartRender(); D3DCOLOR backgroundColor = D3DCOLOR_ARGB(0, 0, 0, 0); V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, backgroundColor, 1.0f, 0) ); UINT p; g_pEffect->SetTechnique("Phase"); g_pEffect->Begin(&p, 0 ); g_pEffect->BeginPass( 0 ); pd3dDevice->SetStreamSource(0, FullScreenQuad, 0, sizeof(float) * 3); pd3dDevice->SetFVF(D3DFVF_XYZ); pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); g_pEffect->EndPass(); g_pEffect->End(); PhaseTexture->EndRender(); phaseCreated = true; } void Explosion::OnFrameRender( D3DXMATRIXA16& mView, D3DXMATRIXA16& mProj ) { if(!phaseCreated) renderPhaseTexture(); FrameBufferTexture->StartRender(true, 0); D3DCOLOR backgroundColor = D3DCOLOR_ARGB(0, 0, 0, 0); V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, backgroundColor, 1.0f, 0) ); D3DXMATRIXA16 mWorld; D3DXMatrixIdentity(&mWorld); SetWorldViewProj(mWorld,mView,mProj); pSys.SetWorldViewProj(mWorld,mView,mProj); g_pEffect->SetTexture("ColorMap",ColorTexture); float lp[]={LightPos->x,LightPos->y,LightPos->z}; g_pEffect->SetFloatArray("mLightPos",lp,3); float cp[]={camera->GetEyePt()->x,camera->GetEyePt()->y,camera->GetEyePt()->z}; g_pEffect->SetFloatArray("mCameraPos",cp,3); g_pEffect->CommitChanges(); //rendertarget = scenetarget UINT p; g_pEffect->SetTechnique("NOSHADING"); g_pEffect->Begin(&p, 0 ); g_pEffect->BeginPass( 0 ); if(params->Get(bObjectOn)) mesh->Draw(); g_pEffect->EndPass(); g_pEffect->End(); FrameBufferTexture->EndRender(); ParticleTexture->StartRender(false, 0); HeatTexture->StartRender(false, 1); backgroundColor = D3DCOLOR_ARGB(0, 0, 0, 0); V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, backgroundColor, 1.0f, 0) ); pSys.setCameraPosition(*camera->GetEyePt()); pSys.draw(FrameBufferTexture->m_Tex, PhaseTexture->m_Tex); if(!params->Get(bPaused)) pSys.stepFrame(); ParticleTexture->EndRender(); HeatTexture->EndRender(); g_pEffect->SetFloat( "fireTemperature", pSys.getFireTemperature()); g_pEffect->SetTexture( "PlanckColors", pSys.getPlanckTexture()); g_pEffect->SetTexture("SceneTexture", FrameBufferTexture->m_Tex); g_pEffect->SetTexture("ParticleTexture", ParticleTexture->m_Tex); g_pEffect->SetTexture("HeatTexture", HeatTexture->m_Tex); //g_pEffect->SetTexture("HeatTexture", PhaseTexture->m_Tex); float shimmerOffset = params->Get(fShimmerAmount) / 20.0; g_pEffect->SetFloat("shimmerOffset", shimmerOffset); float bluramount = 1.0 - params->Get(fMotionBlur); g_pEffect->SetFloat("motionBlur", bluramount); g_pEffect->CommitChanges(); g_pEffect->SetTechnique("FullScreen"); g_pEffect->Begin(&p, 0 ); g_pEffect->BeginPass( 0 ); pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); pd3dDevice->SetStreamSource(0, FullScreenQuad, 0, sizeof(float) * 3); pd3dDevice->SetFVF(D3DFVF_XYZ); pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); g_pEffect->EndPass(); g_pEffect->End(); } void Explosion::addUiParams(Parameters& p) { pSys.setParams(p); params=&p; p.Add( fFireColor, "Fire temperature", 100); p.Add( fFireIntensity, "Fire density", 100); p.Add( fSmokeIntensity, "Smoke density", 100); p.Add( fDustIntensity, "Dust density", 100); p.Add( fShimmerAmount, "ShimmerAmount", 100); p.Add( fTexRatio, "Rendertexture ratio", 4); p.Add( fMotionBlur, "Motion blur amount", 100); } void Explosion::SetWorldViewProj(D3DXMATRIXA16& mWorld, D3DXMATRIXA16& mView, D3DXMATRIXA16& mProj ) { D3DXMATRIXA16 mWorldView = mWorld * mView; D3DXMATRIXA16 mWorldViewProjection = mWorldView * mProj; D3DXMATRIXA16 mWorldViewI, mWorldViewIT; D3DXMatrixInverse(&mWorldViewI, NULL, &mWorldView); D3DXMatrixTranspose(&mWorldViewIT, &mWorldViewI); V( g_pEffect->SetMatrix( "WorldView", &mWorldView ) ); V( g_pEffect->SetMatrix( "WorldViewIT", &mWorldViewIT ) ); V( g_pEffect->SetMatrix( "WorldViewProj", &mWorldViewProjection ) ); V( g_pEffect->SetMatrix( "Proj", &mWorldViewProjection ) ); V( g_pEffect->CommitChanges() ); }