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

📄 ch11p3_orthoproj.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
字号:
/*
#############################################################################

  Ch11p3_OrthoProj.cpp: a program that demonstrates orthographic projections,
  and how they can be used to copy a texture.
  
#############################################################################
*/

// include files ////////////////////////////////////////////////////////////
#define STRICT
#include <stdio.h>
#include <math.h>
#include <D3DX8.h>
#include "D3DApp.h"
#include "D3DFile.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "D3DHelperFuncs.h"
#include "Ch11p3_resource.h"
#include "CommonFuncs.h"

// A structure for our custom vertex type. 
struct CUSTOMVERTEX
{
  D3DXVECTOR3 position; // The position
  D3DCOLOR    color;    // The color
  FLOAT       tu, tv;   // The texture coordinates
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Application class. The base class (CD3DApplication) provides the 
//       generic functionality needed in all Direct3D samples. CMyD3DApplication 
//       adds functionality specific to this sample program.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
  // original and scratch textures
  LPDIRECT3DTEXTURE8 m_pImageTex;
  
  // width and height of texture image
  int m_iTextureWidth, m_iTextureHeight;
  
  // vertex buffer used to render texture onto back buffer
  LPDIRECT3DVERTEXBUFFER8 m_pVB;

  int m_dwNumVertices;

protected:
  void ProcessFeedback();
  HRESULT OneTimeSceneInit();
  HRESULT InitDeviceObjects();
  HRESULT RestoreDeviceObjects();
  HRESULT InvalidateDeviceObjects();
  HRESULT DeleteDeviceObjects();
  HRESULT FinalCleanup();
  HRESULT Render();
  HRESULT FrameMove();
  HRESULT ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format );
  LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

public:
  CMyD3DApplication();
};

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
//       message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
  CMyD3DApplication d3dApp;

  if( FAILED( d3dApp.Create( hInst ) ) )
    return 0;

  return d3dApp.Run();
}

//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
  m_strWindowTitle    = _T("Ch11p3_OrthoProj");
  m_bUseDepthBuffer   = TRUE;

  m_dwNumVertices    = 0;
  m_pImageTex        = NULL;
}


//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
//       permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
  FLOAT fSecsPerFrame = m_fElapsedTime;

  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
  // Set up an orthagonal projection matrix, so we can render the entire
  // texture.
  D3DXMATRIX mat;
  D3DXMatrixOrthoLH(&mat, (float)m_iTextureWidth, (float)m_iTextureHeight, 
    0.0, 100.0);
  m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat );

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

  // move the quad left and up 0.5 units, so that the texels are perfectly
  // centered on the screen pixels.
  D3DXMatrixMultiply(&matWorld, &matScale, D3DXMatrixTranslation(&matTrans, -0.5f, -0.5f, 0));

  // our matrix is now finished.  Tell D3D to use it!
  m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

  // Clear the backbuffer
  m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                       0x000000, 1.0f, 0L );

  // begin rendering the scene
  if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  {
    // no alpha blending
    m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
  
    // set our texture active...
    m_pd3dDevice->SetTexture( 0, m_pImageTex );

    // set up our texture stages for a simple texture copy...
    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 );

    // draw our quad
    m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
    m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

    // End the scene.
    m_pd3dDevice->EndScene();
  }

  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
  // set up a default view matrix.  since we're using an orthogonal projection,
  // we don't really care about the z-distance between the camera and the
  // object(s) we're viewing.  What's more important is the x and y alignment -
  // in this case, making sure that our camera is exactly perpendicular to our
  // quad, and positioned (and aimed at) the quad's exact center.
  D3DXMATRIX matView;
  D3DXVECTOR3 vEye = D3DXVECTOR3( 0.0f, -0.0f, -10.0f );
  D3DXVECTOR3 vAt  = D3DXVECTOR3( 0.0f, -0.0f, 0.0f );
  D3DXVECTOR3 vUp  = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  D3DXMatrixLookAtLH( &matView, &vEye, &vAt, &vUp );
  m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  
  // turn OFF linear filtering, so that if things are scaled the effects
  // are obvious.
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
  m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  
  return S_OK;
}

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

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

  D3DXIMAGE_INFO imageinfo;

  // create texture image.  It's possible your video card may not support textures
  // large enough to hold this 640x480 image.  If you get errors, try loading
  // Ch11p3_TestImage_160.png -- a 160x120 test image -- here instead.
  if (FAILED(hr = D3DXCreateTextureFromFileEx(m_pd3dDevice, "Ch11p3_TestImage.png", 
    D3DX_DEFAULT,
    D3DX_DEFAULT,
    1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
    0, &imageinfo, NULL, &m_pImageTex))) {
    return(hr);
  }
 
  // store texture width/height
  m_iTextureWidth = imageinfo.Width;
  m_iTextureHeight = imageinfo.Height;

  // 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;

    float tex1horz = (float)(m_iTextureWidth+1)/GetLowestPowerOf2(m_iTextureWidth);   
    float tex1vert = (float)(m_iTextureHeight+1)/GetLowestPowerOf2(m_iTextureHeight);  

    // first triangle
    pVertices[0].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
    pVertices[0].color    = D3DCOLOR_ARGB(255,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(255,0,0,0);
    pVertices[1].tu       = tex1horz;
    pVertices[1].tv       = 0.0f;

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

    // second triangle
    pVertices[3].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
    pVertices[3].color    = D3DCOLOR_ARGB(255,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(255,0,0,0);
    pVertices[4].tu       = tex1horz;
    pVertices[4].tv       = tex1vert;

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

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

  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
  SAFE_RELEASE( m_pVB );
  SAFE_RELEASE( m_pImageTex );
  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()
{
  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()
{
  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 + -