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

📄 ch13p1_simplefeedback.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
📖 第 1 页 / 共 2 页
字号:

  // get the current rendering target (we'll set it back later)
  LPDIRECT3DSURFACE8 pOldRenderTarget;
  m_pd3dDevice->GetRenderTarget(&pOldRenderTarget);

  // get surface interfaces for our textures, so we can set them as rendering
  // surfaces later.
  LPDIRECT3DSURFACE8 pScratchSurf, pOrigSurf;
  m_pScratchTexture->GetSurfaceLevel(0, &pScratchSurf);
  m_pOrigTexture->GetSurfaceLevel(0, &pOrigSurf);

  // set scratch surface active and clear it.
  // SetRenderTarget will also set our viewport so that it completely fills
  // pScratchSurf.
  m_pd3dDevice->SetRenderTarget(pScratchSurf, NULL);
  m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x000000, 1.0f, 0L );
  
  // set up texture stage states, turn off z buffering (we don't need it!)
  m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  
  // render transformed image onto scratch surface
  {
    // set up orthogonal projection matrix, so that one texel = one pixel in the final
    // image, with no perspective correction.
    D3DXMATRIX mat;
    D3DXMatrixOrthoLH(&mat, (float)m_iTextureWidth, (float)m_iTextureHeight, 0.0, 100.0);
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat );

    // set up world matrix so that it rotates the quad slightly.
    D3DXMATRIX scalemat,destmat,rotmat;
    D3DXMatrixIdentity( &mat );
    D3DXMatrixRotationZ(&mat, D3DXToRadian(m_fFeedbackRotation));

    // scaling: dividing by 2 will make the texture completely fill the rendering surface
    // (because our ortho projection made one texel=one pixel, and the quad's local origin is
    // in its exact center.)
    // So, dividing by 1.8 will enlarge the image slightly, creating the "tunneling" effect
    // of this feedback system.
    D3DXMatrixMultiply(&destmat, &mat, 
      D3DXMatrixScaling(&scalemat, (float)m_iTextureWidth/1.8, (float)m_iTextureHeight/1.8, 1.0));

    m_pd3dDevice->SetTransform( D3DTS_WORLD, &destmat );

    // set the original texture active
    m_pd3dDevice->SetTexture(0, m_pOrigTexture);
    m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

    // begin rendering the scene
    if (FAILED(m_pd3dDevice->BeginScene())) return;
    m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
    m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );

    // this "blits" the slightly rotated and scaled quad.
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

    // randomly put original image on texture to keep feedback going
    m_pd3dDevice->SetTexture(0, m_pImageTexture);
    //D3DXMatrixScaling(&scalemat, (float)m_iTextureWidth/m_fFeedbackScale, (float)m_iTextureHeight/m_fFeedbackScale, 1.0);
    D3DXMatrixScaling(&scalemat, (float)m_iTextureWidth/5, (float)m_iTextureHeight/5, 1.0);
    D3DXMatrixMultiply(&destmat, &scalemat, D3DXMatrixRotationZ(&rotmat, D3DXToRadian(m_fImageRotation)));
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &destmat );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

    // end scene
    m_pd3dDevice->EndScene();
  }

  // at this point, our scratch surface contains a rotated/scaled version of our original image.
  // now we need to blend the scratch surface back onto the original image.
  
  // set original surface active (DON'T clear it)
  m_pd3dDevice->SetRenderTarget(pOrigSurf, NULL);
  
  // turn alpha blitting on
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
  m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

  // blend scratch surface back onto original surface.
  // This is the feedback portion of the feedback effect.
  {
    if (FAILED(m_pd3dDevice->BeginScene())) return;

    // this world matrix, combined with orthogonal projection, causes the texture to completely 
    // and exactly fill the rendering surface.
    D3DXMATRIX matWorld;
    D3DXMatrixScaling(&matWorld, (float)m_iTextureWidth/2.0f, (float)m_iTextureHeight/2.0f, 1.0);
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    m_pd3dDevice->SetTexture(0, m_pScratchTexture);
    m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
    m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
    m_pd3dDevice->EndScene();
  }
  
  // release the surface of the scratch texture.
  pOrigSurf->Release();
  pScratchSurf->Release();

  // set the rendering target back to the old target.
  m_pd3dDevice->SetRenderTarget(pOldRenderTarget, pDepthSurf);
  m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  pOldRenderTarget->Release();

  // release the depth surface interface.
  pDepthSurf->Release();
}

//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
  HRESULT hr;

  m_pFont->RestoreDeviceObjects();
  m_pFontSmall->RestoreDeviceObjects();

  // Setup render states
  m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

  // Create vertex buffer
  {
    CUSTOMVERTEX* pVertices;

    if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX),
                                                       0, D3DFVF_CUSTOMVERTEX,
                                                       D3DPOOL_MANAGED, &m_pVB ) ) )
      return hr;

    if( FAILED( hr = m_pVB->Lock( 0, m_dwNumVertices*sizeof(CUSTOMVERTEX), (BYTE**)&pVertices, 0 ) ) )
      return hr;

    // first triangle
    pVertices[0].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
    pVertices[0].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[0].tu       = 0.0f;
    pVertices[0].tv       = 0.0f;

    pVertices[1].position = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
    pVertices[1].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[1].tu       = 1.0f;
    pVertices[1].tv       = 0.0f;

    pVertices[2].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
    pVertices[2].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[2].tu       = 1.0f;
    pVertices[2].tv       = 1.0f;

    // second triangle
    pVertices[3].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
    pVertices[3].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[3].tu       = 0.0f;
    pVertices[3].tv       = 0.0f;

    pVertices[4].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
    pVertices[4].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[4].tu       = 1.0f;
    pVertices[4].tv       = 1.0f;

    pVertices[5].position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
    pVertices[5].color    = D3DCOLOR_ARGB(200,0,0,0);
    pVertices[5].tu       = 0.0f;
    pVertices[5].tv       = 1.0f;

    if( FAILED( hr = m_pVB->Unlock() ) )
      return hr;
  }

  // create original image texture.  This must be created as a render target.
  if (FAILED(hr = D3DXCreateTextureFromFileEx(m_pd3dDevice, "Ch13p1_trippy256.bmp", 
    0, 0, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
    0, NULL, NULL, &m_pImageTexture))) {
    return(hr);
  }
 
  D3DSURFACE_DESC desc;
  m_pImageTexture->GetLevelDesc(0, &desc);
  
  m_iTextureWidth = desc.Width;
  m_iTextureHeight = desc.Height;

  // create scratch texture that's the same size as the image texture.
  // this also must be created as a render target.
  if (FAILED(hr = D3DXCreateTexture(m_pd3dDevice, m_iTextureWidth, m_iTextureHeight, 1, D3DUSAGE_RENDERTARGET,
    D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pOrigTexture))) {
    return(hr);
  }
  
  if (FAILED(hr = D3DXCreateTexture(m_pd3dDevice, m_iTextureWidth, m_iTextureHeight, 1, D3DUSAGE_RENDERTARGET,
    D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pScratchTexture))) {
    return(hr);
  }
  
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
  m_pFont->InvalidateDeviceObjects();
  m_pFontSmall->InvalidateDeviceObjects();
  SAFE_RELEASE( m_pVB );
  SAFE_RELEASE( m_pScratchVB );
  SAFE_RELEASE( m_pOrigTexture );
  SAFE_RELEASE( m_pImageTexture );
  SAFE_RELEASE( m_pScratchTexture );
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
  m_pFont->DeleteDeviceObjects();
  m_pFontSmall->DeleteDeviceObjects();
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
//       to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
  SAFE_DELETE( m_pFont );
  SAFE_DELETE( m_pFontSmall );
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: ConfirmDevice()
// Desc: Called during device intialization, this code checks the device
//       for some minimum set of capabilities
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
                                          D3DFORMAT Format )
{
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Message proc function to handle key and menu input
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                                    LPARAM lParam )
{
  // Pass remaining messages to default handler
  return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}

⌨️ 快捷键说明

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