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

📄 ch21p1_lasergun.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
字号:
#include "Ch21p1_LaserGun.h"
#include "D3DUtil.h"

CLaserGun::CLaserGun()
{
  m_bIsFiring = false;
}

CLaserGun::~CLaserGun()
{
}

HRESULT CLaserGun::RestoreDeviceObjects(LPDIRECT3DDEVICE8 pDev, const char *strMeshFilename)
{
  HRESULT hr = S_OK;

  hr = CGun::RestoreDeviceObjects(pDev, strMeshFilename);
  if(FAILED(hr)) return(hr);

  hr = m_pd3dDevice->CreateVertexBuffer( 4*sizeof(VERTEX_XYZ_DIFFUSE_TEX1),
                                         D3DUSAGE_WRITEONLY, D3DFVF_XYZ_DIFFUSE_TEX1,
                                         D3DPOOL_MANAGED, &m_pVBLaser );
  if(FAILED(hr)) return(hr);

  hr = m_pd3dDevice->CreateIndexBuffer( 6*sizeof(WORD),
                                        D3DUSAGE_WRITEONLY,
                                        D3DFMT_INDEX16, D3DPOOL_MANAGED,
                                        &m_pIBLaser );
  if(FAILED(hr)) return(hr);

  m_pAnim = new CAnimSequence(pDev);
  m_pAnim->AddFrame("Ch21p1_Laser.dds", 200000.0f);

  std::string strScript;
  LoadFileIntoString("Ch21p1_LaserScript.txt", strScript);
  m_Emitter.RestoreDeviceObjects(m_pd3dDevice);
  m_Emitter.Compile(strScript.c_str());
  return(S_OK);
}

void CLaserGun::InvalidateDeviceObjects()
{
  CGun::InvalidateDeviceObjects();
  SAFE_RELEASE(m_pVBLaser);
  SAFE_RELEASE(m_pIBLaser);
  SAFE_DELETE(m_pAnim);
  m_Emitter.InvalidateDeviceObjects();

}

void CLaserGun::Render(CCamera &camera)
{
  if (!m_pd3dDevice) return;

  // create a light 
  {
    D3DLIGHT8 light; ZeroMemory(&light, sizeof(D3DLIGHT8));

    // Laser gun looks red
    D3DUtil_InitLight(light, D3DLIGHT_DIRECTIONAL, -10.0f, 20.0f, -20.0f);
    light.Ambient.a = 1.0f; 
    light.Ambient.g = 0.0f;
    light.Ambient.b = 0.0f;
    light.Ambient.r = 0.1f;
    light.Diffuse.a = 1.0f; 
    light.Diffuse.g = 0.0f;
    light.Diffuse.b = 0.0f;
    light.Diffuse.r = 0.3f;
    light.Direction = D3DXVECTOR3(1.0f, -1.0f, 1.0f);

    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE);
    m_pd3dDevice->SetLight(0, &light);
    m_pd3dDevice->LightEnable(0, true);
  }

  // if firing, render laser
  if (m_Timer.IsRunning()) {
    WORD* pIndices;
    if( FAILED(m_pIBLaser->Lock( 0, 6*sizeof(WORD), (BYTE**)&pIndices, 0 ))) return;

    VERTEX_XYZ_DIFFUSE_TEX1* pVertices;
    if(FAILED(m_pVBLaser->Lock(0, 0, (BYTE**)&pVertices, NULL))) return;

    pIndices[0] = 3; pIndices[1] = 2; pIndices[2] = 1;
    pIndices[3] = 3; pIndices[4] = 1; pIndices[5] = 0;

    float a = 1.0f-(m_Timer.GetTime()*2);
    if (a < 0.0f) a = 0.0f;

    pVertices[0].color = D3DXCOLOR(1.0, 0.0, 0.0, 0.0);
    pVertices[1].color = D3DXCOLOR(1.0, 0.0, 0.0, 0.0);
    pVertices[2].color = D3DXCOLOR(1.0, 0.0, 0.0, a);
    pVertices[3].color = D3DXCOLOR(1.0, 0.0, 0.0, a);

    pVertices[0].tu = 0.0f; pVertices[0].tv = 0.0f;
    pVertices[1].tu = 1.0f; pVertices[1].tv = 0.0f;
    pVertices[2].tu = 1.0f; pVertices[2].tv = 100.0f;
    pVertices[3].tu = 0.0f; pVertices[3].tv = 100.0f;

    pVertices[0].position = D3DXVECTOR3(-0.15f,   -0.05f,  -100.0f);
    pVertices[1].position = D3DXVECTOR3( 0.15f,  -0.05f,  -100.0f);
    pVertices[2].position = D3DXVECTOR3( 0.15f, -0.05f, -2.0f);
    pVertices[3].position = D3DXVECTOR3(-0.15f, -0.05f, -2.0f);
    
    m_pVBLaser->Unlock();
    m_pIBLaser->Unlock();

    // now render!
    m_pd3dDevice->SetTexture(0, m_pAnim->GetCurFrameTexture(m_Timer));

    m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld );

    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,  D3DCULL_NONE );

    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE);
    m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);

    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );

    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

    m_pd3dDevice->SetVertexShader(D3DFVF_XYZ_DIFFUSE_TEX1);
    m_pd3dDevice->SetStreamSource( 0, m_pVBLaser, sizeof(VERTEX_XYZ_DIFFUSE_TEX1) );
    m_pd3dDevice->SetIndices( m_pIBLaser, 0L );
    m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2);

    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);


  }

  // render gun model
  {
    float fOffsetZ = -1.0f+(m_Timer.GetTime()*3);
    if (fOffsetZ > 0.0f) fOffsetZ = 0.0f;

    D3DXMATRIX matWorld;
    AssembleWorldMatrix(camera, matWorld, 
      m_Timer.IsRunning() ? 
        D3DXVECTOR3(0.0f, 0.0f, fOffsetZ) :
        D3DXVECTOR3(0.0f, 0.0f, 0.0f));

    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,  D3DCULL_CCW );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE);
    m_pMesh->Render(m_pd3dDevice);
  }
  // render particle system
  m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
  m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, 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_ALPHAARG1, D3DTA_DIFFUSE );
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

  m_Emitter.Render();
  
}

void CLaserGun::Update(float fElapsedTime)
{
  m_Emitter.Update(fElapsedTime, fElapsedTime);
  
  if (m_Timer.GetTime() > 1.0f) {
    m_Timer.Stop();
    m_Emitter.Stop();
  }
}

void CLaserGun::Fire(CCamera &camera)
{
  m_Timer.Start();
  m_Emitter.Start();

  D3DXMATRIX matEmitterWorld, matInvView, matTrans, matRot, matGunTrans;
  float fDet;
  D3DXMatrixInverse(&matInvView, &fDet, &camera.GetViewMatrix());
  D3DXMatrixTranslation(&matTrans, 0.0f, 0.0f, 0.0f);
  D3DXMatrixRotationYawPitchRoll(&matRot, (float)PI, 0.0f, 0.0f);
  D3DXMatrixTranslation(&matGunTrans, m_vPos.x, m_vPos.y, m_vPos.z);
  m_matWorld = matRot * matGunTrans * matTrans * matInvView;

  D3DXMatrixTranslation(&matTrans, 0.0f, 0.0f, 2.8f);
  matEmitterWorld = matRot * matGunTrans * matTrans * matInvView;

  m_Emitter.SetPos(D3DXVECTOR3(
    matEmitterWorld._41,
    matEmitterWorld._42,
    matEmitterWorld._43)
  );

}

bool CLaserGun::CanFire()
{
  return(!m_Timer.IsRunning());
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -