BumpEarth.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:36k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. // File: BumpEarth.cpp
  3. //
  4. // Desc: Direct3D 环境贴图/凹凸贴图 实例。
  5. //-----------------------------------------------------------------------------
  6. #define STRICT
  7. #include <Windows.h>
  8. #include <commctrl.h>
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <D3DX9.h>
  12. #include "DXUtil.h"
  13. #include "D3DEnumeration.h"
  14. #include "D3DSettings.h"
  15. #include "D3DApp.h"
  16. #include "D3DFile.h"
  17. #include "D3DFont.h"
  18. #include "D3DUtil.h"
  19. #include "resource.h"
  20. //-----------------------------------------------------------------------------
  21. // 定义,常量,全局变量声明
  22. //-----------------------------------------------------------------------------
  23. // Vertex 数据结构,bumpmapped environment map使用
  24. struct BUMPVERTEX
  25. {
  26.     D3DXVECTOR3 p;
  27.     D3DXVECTOR3 n;
  28.     FLOAT       tu1, tv1;
  29.     FLOAT       tu2, tv2;
  30.         static const DWORD FVF;
  31. };
  32. const DWORD BUMPVERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2;
  33. // 将FLOAT转换为DWORD,在SetRenderState()调用中将用到
  34. inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
  35. //-----------------------------------------------------------------------------
  36. // Name: class CMyD3DApplication
  37. // Desc:  
  38. //-----------------------------------------------------------------------------
  39. class CMyD3DApplication : public CD3DApplication
  40. {
  41.     CD3DFont*     m_pFont;                  //用于输出文本
  42.     CD3DArcBall   m_ArcBall;                //用于鼠标输入
  43.     LPDIRECT3DTEXTURE9 m_pBlockTexture;    //黑,灰纹理
  44.     LPDIRECT3DTEXTURE9 m_pEarthTexture;     //地表纹理
  45.     LPDIRECT3DTEXTURE9 m_pEnvMapTexture;    //环境贴图
  46.     LPDIRECT3DTEXTURE9 m_pEarthBumpTexture; //凹凸贴图资源
  47.     LPDIRECT3DTEXTURE9 m_psBumpMap;         //实际的凹凸贴图
  48.     CD3DMesh* m_pSkyBox;
  49.     LPDIRECT3DTEXTURE9 m_pDispMapTexture;   //偏移贴图纹理
  50.     IDirect3DVertexShader9* m_pDispMapBumpShader;//偏移贴图+凹凸贴图着色
  51.     IDirect3DVertexShader9* m_pDispMapShader;    //偏移贴图+无凹凸贴图着色
  52.     IDirect3DVertexDeclaration9*   m_pDispMapVertexDecl;
  53.     D3DXMATRIXA16 m_matWorld;
  54.     D3DXMATRIXA16 m_matView;
  55.     D3DXMATRIXA16 m_matProj;
  56.     D3DFORMAT     m_BumpMapFormat;         //凹凸贴图纹理格式
  57.     LPDIRECT3DVERTEXBUFFER9 m_pEarthVB;   //地球几何体
  58.     DWORD         m_dwNumSphereVertices;
  59.     BOOL          m_bHighTesselation;      //用户选项
  60.     BOOL          m_bTextureOn;
  61.     BOOL          m_bBumpMapOn;
  62.     BOOL          m_bEnvMapOn;
  63.     BOOL          m_bDeviceValidationFailed;
  64.     BOOL          m_bDispMapOn;            //偏移贴图开关
  65.     BOOL          m_bCanDoDispMap;
  66.     VOID    SetMenuStates();
  67.     HRESULT CreateEarthVertexBuffer();
  68.     VOID    ApplyEnvironmentMap();
  69.     HRESULT InitBumpMap();
  70. protected:
  71.     HRESULT OneTimeSceneInit();
  72.     HRESULT InitDeviceObjects();
  73.     HRESULT RestoreDeviceObjects();
  74.     HRESULT InvalidateDeviceObjects();
  75.     HRESULT DeleteDeviceObjects();
  76.     HRESULT Render();
  77.     HRESULT FrameMove();
  78.     HRESULT FinalCleanup();
  79.     HRESULT ConfirmDevice( D3DCAPS9*, DWORD, D3DFORMAT, D3DFORMAT );
  80. public:
  81.     CMyD3DApplication();
  82.     LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  83. };
  84. //-----------------------------------------------------------------------------
  85. // Name: WinMain()
  86. // Desc: 程序入口。进行全部的初始化工作,然后进入消息处理循环,空闲时间被用来
  87. //       进行渲染
  88. //-----------------------------------------------------------------------------
  89. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  90. {
  91.     CMyD3DApplication d3dApp;
  92.     InitCommonControls();
  93.     if( FAILED( d3dApp.Create( hInst ) ) )
  94.         return 0;
  95.     return d3dApp.Run();
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Name: CMyD3DApplication()
  99. // Desc: 
  100. //-----------------------------------------------------------------------------
  101. CMyD3DApplication::CMyD3DApplication()
  102. {
  103.     m_strWindowTitle    = _T("BumpEarth: Direct3D BumpMapping Demo");
  104.     m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
  105.     m_bShowCursorWhenFullscreen = TRUE;
  106.     m_psBumpMap         = NULL;
  107.     m_bTextureOn        = TRUE;
  108.     m_bBumpMapOn        = TRUE;
  109.     m_bEnvMapOn         = TRUE;
  110.     m_bHighTesselation  = TRUE;
  111.     m_bDispMapOn        = FALSE;
  112.     m_bCanDoDispMap     = FALSE;
  113.     m_pDispMapShader    = NULL;
  114.     m_pDispMapBumpShader= NULL;
  115.     m_pDispMapVertexDecl= NULL;
  116.     m_pDispMapTexture   = NULL;
  117.     m_pBlockTexture     = NULL;
  118.     m_pEarthTexture     = NULL;
  119.     m_pEarthBumpTexture = NULL;
  120.     m_pEnvMapTexture    = NULL;
  121.     m_pSkyBox           = NULL;
  122.     m_bDeviceValidationFailed = FALSE;
  123.     m_pFont             = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  124.     m_pEarthVB          = NULL;
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Name: OneTimeSceneInit()
  128. // Desc: 在初始程序开始时调用。此函数进行所有常设值得初始化
  129. //-----------------------------------------------------------------------------
  130. HRESULT CMyD3DApplication::OneTimeSceneInit()
  131. {
  132.     // 设置指针使用户可以用鼠标移动目标
  133. #ifdef _WIN64
  134.     SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
  135. #else
  136.     SetClassLong( m_hWnd, GCL_HCURSOR, HandleToLong( LoadCursor( NULL, IDC_SIZEALL ) ) );
  137. #endif
  138.     m_pSkyBox      = new CD3DMesh();
  139.     if( m_pSkyBox == NULL )
  140.         return E_OUTOFMEMORY;
  141.     return S_OK;
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Name: ApplyEnvironmentMap()
  145. // Desc: 计算每个顶点的法向,从而决定环境贴图对应的纹理
  146. //-----------------------------------------------------------------------------
  147. VOID CMyD3DApplication::ApplyEnvironmentMap()
  148. {
  149.     D3DXMATRIXA16 matWorldView;
  150.     D3DXMatrixMultiply( &matWorldView, &m_matWorld, &m_matView );
  151.     
  152.     BUMPVERTEX* vtx;
  153.     m_pEarthVB->Lock( 0, 0, (void**)&vtx, 0 );
  154.     DWORD dwNumSphereRings    = m_bHighTesselation ? 15 :  5;
  155.     DWORD dwNumSphereSegments = m_bHighTesselation ? 30 : 10;
  156.     FLOAT fDeltaRingAngle = ( D3DX_PI / dwNumSphereRings );
  157.     FLOAT fDeltaSegAngle  = ( 2.0f * D3DX_PI / dwNumSphereSegments );
  158.     D3DXVECTOR4 vT;
  159.     FLOAT fScale;
  160.    for( DWORD ring = 0; ring < dwNumSphereRings; ring++ )
  161.     {
  162.         FLOAT r0 = sinf( (ring+0) * fDeltaRingAngle );
  163.         FLOAT r1 = sinf( (ring+1) * fDeltaRingAngle );
  164.         FLOAT y0 = cosf( (ring+0) * fDeltaRingAngle );
  165.         FLOAT y1 = cosf( (ring+1) * fDeltaRingAngle );
  166.         for( DWORD seg = 0; seg < (dwNumSphereSegments+1); seg++ )
  167.         {
  168.             FLOAT x0 =  r0 * sinf( seg * fDeltaSegAngle );
  169.             FLOAT z0 =  r0 * cosf( seg * fDeltaSegAngle );
  170.             FLOAT x1 =  r1 * sinf( seg * fDeltaSegAngle );
  171.             FLOAT z1 =  r1 * cosf( seg * fDeltaSegAngle );
  172.             (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x0,y0,z0);
  173.             (*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
  174.             (*vtx).tv2 = (ring+0) / (FLOAT)dwNumSphereRings;
  175.             D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
  176.             fScale = 1.37f / D3DXVec4Length( &vT );
  177.             (*vtx).tu1 = 0.5f + fScale*vT.x;
  178.             (*vtx).tv1 = 0.5f - fScale*vT.y;
  179.             vtx++;
  180.             (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x1,y1,z1);
  181.             (*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
  182.             (*vtx).tv2 = (ring+1) / (FLOAT)dwNumSphereRings;
  183.             D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
  184.             fScale = 1.37f / D3DXVec4Length( &vT );
  185.             (*vtx).tu1 = 0.5f + fScale*vT.x;
  186.             (*vtx).tv1 = 0.5f - fScale*vT.y;
  187.             vtx++;
  188.         }
  189.     }
  190.     m_pEarthVB->Unlock();
  191. }
  192. //-----------------------------------------------------------------------------
  193. // Name: FrameMove()
  194. // Desc: 
  195. //-----------------------------------------------------------------------------
  196. HRESULT CMyD3DApplication::FrameMove()
  197. {
  198.     static FLOAT fRotationAngle = 0.0f;
  199.     if( FALSE == m_ArcBall.IsBeingDragged() )
  200.         fRotationAngle += m_fElapsedTime;
  201.     D3DXMatrixRotationY( &m_matWorld, -fRotationAngle );
  202.     D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetRotationMatrix() );
  203.     D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetTranslationMatrix() );
  204.     D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -3.0f );
  205.     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
  206.     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  207.     D3DXMatrixLookAtLH( &m_matView, &vEyePt, &vLookatPt, &vUpVec );
  208.     ApplyEnvironmentMap();
  209.     return S_OK;
  210. }
  211. //-----------------------------------------------------------------------------
  212. // Name: Render()
  213. // Desc: 
  214. //-----------------------------------------------------------------------------
  215. HRESULT CMyD3DApplication::Render()
  216. {
  217.     if( FAILED( m_pd3dDevice->BeginScene() ) )
  218.         return S_OK; 
  219.     {
  220.         D3DXMATRIXA16 matWorldSkybox;
  221.         D3DXMatrixScaling( &matWorldSkybox, 10.0f, 10.0f, 10.0f );
  222.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorldSkybox );
  223.         D3DXMATRIXA16 matViewSkybox = m_matView;
  224.         matViewSkybox._41 = matViewSkybox._42 = matViewSkybox._43 = 0.0f;
  225.         m_pd3dDevice->SetTransform( D3DTS_VIEW, &matViewSkybox );
  226.         m_pd3dDevice->SetRenderState( D3DRS_WRAP0, 0 );
  227.         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  228.         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  229.         if( (m_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) == D3DPTADDRESSCAPS_MIRROR )
  230.         {
  231.             m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU,  D3DTADDRESS_MIRROR );
  232.             m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV,  D3DTADDRESS_MIRROR );
  233.         }
  234.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  235.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
  236.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  237.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
  238.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  239.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  240.         m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );
  241.         m_pSkyBox->Render( m_pd3dDevice );
  242.         m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
  243.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
  244.         m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );
  245.     }
  246.     m_pd3dDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V );
  247.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  248.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  249.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  250.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  251.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  252.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  253.     if( m_bTextureOn )
  254.         m_pd3dDevice->SetTexture( 0, m_pEarthTexture );
  255.     else
  256.         m_pd3dDevice->SetTexture( 0, m_pBlockTexture );
  257.     if( m_bDispMapOn )
  258.     {
  259.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
  260.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
  261.         m_pd3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 2 );
  262.         m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
  263.         m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
  264.         m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  265.         m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  266.         m_pd3dDevice->SetTexture(D3DDMAPSAMPLER,  m_pDispMapTexture);
  267.         D3DXMATRIX m;
  268.         D3DXMatrixMultiply(&m, &m_matWorld, &m_matView);
  269.         D3DXMatrixMultiplyTranspose(&m, &m, &m_matProj);
  270.         m_pd3dDevice->SetVertexShaderConstantF(0, (float*)&m, 4);
  271.         float c[4] = {0.15f,0,0,0};
  272.         m_pd3dDevice->SetVertexShaderConstantF(4, c, 1);
  273.         m_pd3dDevice->SetNPatchMode(4);
  274.         m_pd3dDevice->SetVertexDeclaration( m_pDispMapVertexDecl );
  275.         if( m_bBumpMapOn && m_bEnvMapOn )
  276.         {
  277.             m_pd3dDevice->SetVertexShader( m_pDispMapBumpShader );
  278.         }
  279.         else
  280.         {
  281.             m_pd3dDevice->SetVertexShader( m_pDispMapShader );
  282.         }
  283.     }
  284.     else
  285.     {
  286.         m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );
  287.         m_pd3dDevice->SetFVF( BUMPVERTEX::FVF );
  288.     }
  289.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  290.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  291.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  292.     if( m_bBumpMapOn && m_bEnvMapOn )
  293.     {
  294.         m_pd3dDevice->SetTexture( 1, m_psBumpMap );
  295.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
  296.         if( m_BumpMapFormat == D3DFMT_V8U8 )
  297.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP );
  298.         else
  299.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE );
  300.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  301.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  302.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT00, F2DW(0.5f) );
  303.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT01, F2DW(0.0f) );
  304.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT10, F2DW(0.0f) );
  305.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVMAT11, F2DW(0.5f) );
  306.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVLSCALE, F2DW(4.0f) );
  307.         m_pd3dDevice->SetTextureStageState( 1, D3DTSS_BUMPENVLOFFSET, F2DW(0.0f) );
  308.         if( m_bEnvMapOn )
  309.         {
  310.             m_pd3dDevice->SetTexture( 2, m_pEnvMapTexture );
  311.             if( !m_bDispMapOn )
  312.                 m_pd3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 0 );
  313.             m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_ADD );
  314.             m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  315.             m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
  316.         }
  317.         else
  318.             m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
  319.     }
  320.     else
  321.     {
  322.         if( m_bEnvMapOn )
  323.         {
  324.             m_pd3dDevice->SetTexture( 1, m_pEnvMapTexture );
  325.             if( !m_bDispMapOn )
  326.                 m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );
  327.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADD );
  328.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  329.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  330.         }
  331.         else
  332.             m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  333.         m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
  334.     }
  335.     m_pd3dDevice->SetStreamSource( 0, m_pEarthVB, 0, sizeof(BUMPVERTEX) );
  336.     DWORD dwNumPasses;
  337.     HRESULT hr;
  338.     hr = m_pd3dDevice->ValidateDevice( &dwNumPasses );
  339.     if ( ( D3D_OK == hr) || ( D3DERR_DEVICELOST == hr ) )
  340.     {
  341.         m_bDeviceValidationFailed = FALSE;
  342.     }
  343.     else
  344.     {
  345.         m_bDeviceValidationFailed = TRUE;
  346.     }
  347.     m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, m_dwNumSphereVertices-2 );
  348.     if ( m_bDispMapOn )
  349.     {
  350.         m_pd3dDevice->SetNPatchMode(0);
  351.         m_pd3dDevice->SetVertexShader( NULL );
  352.     }
  353.     m_pd3dDevice->SetTexture( 0, NULL );
  354.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
  355.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  356.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  357.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  358.     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  359.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  360.     m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  361.     m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
  362.     m_pd3dDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  363.     m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
  364.     m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
  365.     if( m_bDeviceValidationFailed )
  366.     {
  367.         m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,0,0),
  368.             _T("Warning: Device validation failed.  Rendering may not look right.") );
  369.     }
  370.     m_pd3dDevice->EndScene();
  371.     return S_OK;
  372. }
  373. //-----------------------------------------------------------------------------
  374. // Name: InitBumpMap()
  375. // Desc: 
  376. //-----------------------------------------------------------------------------
  377. HRESULT CMyD3DApplication::InitBumpMap()
  378. {
  379.     LPDIRECT3DTEXTURE9 psBumpSrc = m_pEarthBumpTexture;
  380.     D3DSURFACE_DESC    d3dsd;
  381.     D3DLOCKED_RECT     d3dlr;
  382.     psBumpSrc->GetLevelDesc( 0, &d3dsd );
  383.     if( FAILED( m_pd3dDevice->CreateTexture( d3dsd.Width, d3dsd.Height, 1, 0,
  384.         m_BumpMapFormat, D3DPOOL_MANAGED, &m_psBumpMap, NULL ) ) )
  385.     {
  386.         return E_FAIL;
  387.     }
  388.     psBumpSrc->LockRect( 0, &d3dlr, 0, 0 );
  389.     DWORD dwSrcPitch = (DWORD)d3dlr.Pitch;
  390.     BYTE* pSrcTopRow = (BYTE*)d3dlr.pBits;
  391.     BYTE* pSrcCurRow = pSrcTopRow;
  392.     BYTE* pSrcBotRow = pSrcTopRow + (dwSrcPitch * (d3dsd.Height - 1) );
  393.     m_psBumpMap->LockRect( 0, &d3dlr, 0, 0 );
  394.     DWORD dwDstPitch = (DWORD)d3dlr.Pitch;
  395.     BYTE* pDstTopRow = (BYTE*)d3dlr.pBits;
  396.     BYTE* pDstCurRow = pDstTopRow;
  397.     for( DWORD y=0; y<d3dsd.Height; y++ )
  398.     {
  399.         BYTE* pSrcB0; 
  400.         BYTE* pSrcB1; 
  401.         BYTE* pSrcB2; 
  402.         BYTE* pDstT; 
  403.         pSrcB0 = pSrcCurRow;
  404.         if( y == d3dsd.Height - 1)
  405.             pSrcB1 = pSrcTopRow;
  406.         else
  407.             pSrcB1 = pSrcCurRow + dwSrcPitch;
  408.         if( y == 0 )
  409.             pSrcB2 = pSrcBotRow;
  410.         else
  411.             pSrcB2 = pSrcCurRow - dwSrcPitch;
  412.         pDstT = pDstCurRow;
  413.         for( DWORD x=0; x<d3dsd.Width; x++ )
  414.         {
  415.             LONG v00; 
  416.             LONG v01; 
  417.             LONG vM1; 
  418.             LONG v10; 
  419.             LONG v1M; 
  420.             v00 = *(pSrcB0+0);
  421.             if( x == d3dsd.Width - 1 )
  422.                 v01 = *(pSrcCurRow);
  423.             else
  424.                 v01 = *(pSrcB0+4);
  425.             if( x == 0 )
  426.                 vM1 = *(pSrcCurRow + (4 * (d3dsd.Width - 1)));
  427.             else
  428.                 vM1 = *(pSrcB0-4);
  429.             v10 = *(pSrcB1+0);
  430.             v1M = *(pSrcB2+0);
  431.             LONG iDu = (vM1-v01); 
  432.             LONG iDv = (v1M-v10); 
  433.             WORD uL = ( v00>1 ) ? 63 : 127;
  434.             switch( m_BumpMapFormat )
  435.             {
  436.                 case D3DFMT_V8U8:
  437.                     *pDstT++ = (BYTE)iDu;
  438.                     *pDstT++ = (BYTE)iDv;
  439.                     break;
  440.                 case D3DFMT_L6V5U5:
  441.                     *(WORD*)pDstT  = (WORD)( ( (iDu>>3) & 0x1f ) <<  0 );
  442.                     *(WORD*)pDstT |= (WORD)( ( (iDv>>3) & 0x1f ) <<  5 );
  443.                     *(WORD*)pDstT |= (WORD)( ( ( uL>>2) & 0x3f ) << 10 );
  444.                     pDstT += 2;
  445.                     break;
  446.                 case D3DFMT_X8L8V8U8:
  447.                     *pDstT++ = (BYTE)iDu;
  448.                     *pDstT++ = (BYTE)iDv;
  449.                     *pDstT++ = (BYTE)uL;
  450.                     *pDstT++ = (BYTE)0L;
  451.                     break;
  452.             }
  453.             pSrcB0+=4;
  454.             pSrcB1+=4;
  455.             pSrcB2+=4;
  456.         }
  457.         pSrcCurRow += dwSrcPitch;
  458.         pDstCurRow += dwDstPitch;
  459.     }
  460.     m_psBumpMap->UnlockRect(0);
  461.     psBumpSrc->UnlockRect(0);
  462.     return S_OK;
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Name: InitDeviceObjects()
  466. // Desc: 
  467. //-----------------------------------------------------------------------------
  468. HRESULT CMyD3DApplication::InitDeviceObjects()
  469. {
  470.     m_pFont->InitDeviceObjects( m_pd3dDevice );
  471.     if( FAILED( m_pSkyBox->Create( m_pd3dDevice, _T("lobby_skybox.x") ) ) )
  472.         return D3DAPPERR_MEDIANOTFOUND;
  473.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Block.bmp"),
  474.                                        &m_pBlockTexture, D3DFMT_R5G6B5 ) ) )
  475.         return D3DAPPERR_MEDIANOTFOUND;
  476.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Earth.bmp"),
  477.                                        &m_pEarthTexture, D3DFMT_R5G6B5 ) ) )
  478.         return D3DAPPERR_MEDIANOTFOUND;
  479.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Earthbump.bmp"),
  480.                                        &m_pEarthBumpTexture, D3DFMT_A8R8G8B8 ) ) )
  481.         return D3DAPPERR_MEDIANOTFOUND;
  482.     if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("EarthEnvMap.bmp"),
  483.                                        &m_pEnvMapTexture, D3DFMT_R5G6B5 ) ) )
  484.         return D3DAPPERR_MEDIANOTFOUND;
  485.     D3DFORMAT adapterFormat = m_d3dSettings.DisplayMode().Format;
  486.     BOOL bCanDoV8U8   = SUCCEEDED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
  487.                                    m_d3dCaps.DeviceType, adapterFormat,
  488.                                    0, D3DRTYPE_TEXTURE,
  489.                                    D3DFMT_V8U8 ) ) &&
  490.                         (m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP );
  491.     BOOL bCanDoL6V5U5 = SUCCEEDED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
  492.                                    m_d3dCaps.DeviceType, adapterFormat,
  493.                                    0, D3DRTYPE_TEXTURE,
  494.                                    D3DFMT_L6V5U5 ) ) &&
  495.                         (m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE );
  496.     BOOL bCanDoL8V8U8 = SUCCEEDED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
  497.                                    m_d3dCaps.DeviceType, adapterFormat,
  498.                                    0, D3DRTYPE_TEXTURE,
  499.                                    D3DFMT_X8L8V8U8 ) ) &&
  500.                         (m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE );
  501.     if( bCanDoV8U8 )        m_BumpMapFormat = D3DFMT_V8U8;
  502.     else if( bCanDoL6V5U5 ) m_BumpMapFormat = D3DFMT_L6V5U5;
  503.     else if( bCanDoL8V8U8 ) m_BumpMapFormat = D3DFMT_X8L8V8U8;
  504.     else                    return E_FAIL;
  505.     m_bCanDoDispMap = ( (m_pd3dDevice->GetSoftwareVertexProcessing() == FALSE) && 
  506.                         (m_d3dCaps.DevCaps2 & D3DDEVCAPS2_DMAPNPATCH ) &&
  507.                         m_d3dCaps.VertexShaderVersion >= D3DVS_VERSION(1,1) &&
  508.                         SUCCEEDED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
  509.                                                             m_d3dCaps.DeviceType,
  510.                                                             adapterFormat,
  511.                                                             D3DUSAGE_DMAP,
  512.                                                             D3DRTYPE_TEXTURE,
  513.                                                             D3DFMT_L8 ) ) );
  514.     if( !m_bCanDoDispMap )
  515.         m_bDispMapOn = false;
  516.     HMENU hMenu = GetMenu( m_hWnd );
  517.     EnableMenuItem( hMenu, IDM_U8V8,   bCanDoV8U8   ? MF_ENABLED : MF_GRAYED );
  518.     EnableMenuItem( hMenu, IDM_U5V5L6, bCanDoL6V5U5 ? MF_ENABLED : MF_GRAYED );
  519.     EnableMenuItem( hMenu, IDM_U8V8L8, bCanDoL8V8U8 ? MF_ENABLED : MF_GRAYED );
  520.     EnableMenuItem( hMenu, IDM_DISPMAPTOGGLE, m_bCanDoDispMap? MF_ENABLED : MF_GRAYED );
  521.     SetMenuStates();
  522.     if( FAILED( CreateEarthVertexBuffer() ) )
  523.         return E_FAIL;
  524.     if( FAILED( InitBumpMap() ) )
  525.         return E_FAIL;
  526.     if( m_bCanDoDispMap )
  527.     {
  528.         HRESULT hr;
  529.         TCHAR strPath[MAX_PATH];
  530.         if( FAILED( hr = DXUtil_FindMediaFileCb( strPath, sizeof(strPath), TEXT("Earthbump.bmp") ) ) )
  531.             return hr;
  532.         hr = D3DXCreateTextureFromFileEx( m_pd3dDevice,
  533.                                           strPath,
  534.                                           D3DX_DEFAULT,         
  535.                                           D3DX_DEFAULT,         
  536.                                           D3DX_DEFAULT,         
  537.                                           D3DUSAGE_DMAP,
  538.                                           D3DFMT_L8,
  539.                                           D3DPOOL_MANAGED,
  540.                                           D3DX_DEFAULT,         
  541.                                           D3DX_DEFAULT,         
  542.                                           0,                    
  543.                                           NULL,                 
  544.                                           NULL,                 
  545.                                           &m_pDispMapTexture );
  546.         if( FAILED(hr) )
  547.             return D3DAPPERR_MEDIANOTFOUND;
  548.         if( FAILED( hr = DXUtil_FindMediaFileCch( strPath, MAX_PATH,
  549.                                                 TEXT("EarthDispMap.fx") ) ) )
  550.         {
  551.             return hr;
  552.         }
  553.         LPD3DXEFFECT  pEffect;
  554.         if( FAILED( hr = D3DXCreateEffectFromFile( m_pd3dDevice, strPath, NULL, NULL,
  555.                                                 0, NULL, &pEffect, NULL ) ) )
  556.         {
  557.             return hr;
  558.         }
  559.         D3DXHANDLE h = pEffect->GetParameterByName( NULL, TEXT("EarthBumpMap") );
  560.         if( h == 0 )
  561.         {
  562.             SAFE_RELEASE( pEffect );
  563.             return E_FAIL;
  564.         }
  565.         if( FAILED (hr = pEffect->GetVertexShader(h, &m_pDispMapBumpShader) ) )
  566.             return hr;
  567.         h = pEffect->GetParameterByName( NULL, TEXT("EarthNoBumpMap") );
  568.         if( h == 0 )
  569.         {
  570.             SAFE_RELEASE( pEffect );
  571.             return E_FAIL;
  572.         }
  573.         if( FAILED (hr = pEffect->GetVertexShader(h, &m_pDispMapShader) ) )
  574.         {
  575.             SAFE_RELEASE( pEffect );
  576.             return hr;
  577.         }
  578.         SAFE_RELEASE( pEffect );
  579.         D3DVERTEXELEMENT9 decl[] =
  580.         {
  581.             {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
  582.             {0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
  583.             {0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
  584.             {0, 32, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
  585.             {0, 32, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_LOOKUP,  D3DDECLUSAGE_SAMPLE, 0},
  586.             D3DDECL_END()
  587.         };
  588.         if (FAILED(hr = m_pd3dDevice->CreateVertexDeclaration(decl, &m_pDispMapVertexDecl)))
  589.         {
  590.             return hr;
  591.         }
  592.     }
  593.     m_bDeviceValidationFailed = FALSE;
  594.     return S_OK;
  595. }
  596. //-----------------------------------------------------------------------------
  597. // Name: RestoreDeviceObjects()
  598. // Desc: 初始化scene 对象
  599. //-----------------------------------------------------------------------------
  600. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  601. {
  602.     m_pFont->RestoreDeviceObjects();
  603.     m_pSkyBox->RestoreDeviceObjects( m_pd3dDevice );
  604.     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
  605.     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
  606.     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  607.     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  608.     m_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
  609.     m_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
  610.     m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  611.     m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  612.     m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
  613.     m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
  614.     m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  615.     m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  616.     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  617.     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
  618.     //设置投影矩阵 
  619.     D3DXMatrixPerspectiveFovLH( &m_matProj, D3DX_PI/4, fAspect, 0.1f, 225.0f );
  620.     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProj );
  621.   
  622. //设置ArcBall参数
  623.     m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 3.0f );
  624.     m_ArcBall.SetRadius( 1.0f );
  625.     return S_OK;
  626. }
  627. //-----------------------------------------------------------------------------
  628. // Name: InvalidateDeviceObjects()
  629. // Desc:
  630. //-----------------------------------------------------------------------------
  631. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  632. {
  633.     m_pFont->InvalidateDeviceObjects();
  634.     m_pSkyBox->InvalidateDeviceObjects();
  635.     return S_OK;
  636. }
  637. //-----------------------------------------------------------------------------
  638. // Name: DeleteDeviceObjects()
  639. // Desc: 程序退出或者设备改变时调用,该函数删除一切设备相关的对象
  640. //-----------------------------------------------------------------------------
  641. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  642. {
  643.     SAFE_RELEASE( m_pBlockTexture );
  644.     SAFE_RELEASE( m_pEarthTexture );
  645.     SAFE_RELEASE( m_pEarthBumpTexture );
  646.     SAFE_RELEASE( m_pEnvMapTexture );
  647.     SAFE_RELEASE( m_pDispMapBumpShader );
  648.     SAFE_RELEASE( m_pDispMapShader );
  649.     SAFE_RELEASE( m_pDispMapVertexDecl );
  650.     SAFE_RELEASE( m_pDispMapTexture );
  651.     m_pFont->DeleteDeviceObjects();
  652.     m_pSkyBox->Destroy();
  653.     SAFE_RELEASE( m_psBumpMap );
  654.     SAFE_RELEASE( m_pEarthVB );
  655.     return S_OK;
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Name: FinalCleanup()
  659. // Desc:
  660. //-----------------------------------------------------------------------------
  661. HRESULT CMyD3DApplication::FinalCleanup()
  662. {
  663.     SAFE_DELETE( m_pFont );
  664.     SAFE_DELETE( m_pSkyBox );
  665.     return S_OK;
  666. }
  667. //-----------------------------------------------------------------------------
  668. // Name: ConfirmDevice()
  669. // Desc: 设备初始化时调用,此函数检查设备必须具备的最低限度的功能
  670. //-----------------------------------------------------------------------------
  671. HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
  672.                                           D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat )
  673. {
  674.     if( pCaps->TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE )
  675.     {
  676.         if( SUCCEEDED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
  677.                                                   pCaps->DeviceType, adapterFormat,
  678.                                                   0, D3DRTYPE_TEXTURE,
  679.                                                   D3DFMT_X8L8V8U8 ) ) )
  680.         {
  681.             return S_OK;
  682.         }
  683.         if( SUCCEEDED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
  684.                                                   pCaps->DeviceType, adapterFormat,
  685.                                                   0, D3DRTYPE_TEXTURE,
  686.                                                   D3DFMT_L6V5U5 ) ) )
  687.         {
  688.             return S_OK;
  689.         }
  690.     }
  691.     if( pCaps->TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP )
  692.     {
  693.         if( SUCCEEDED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
  694.                                                   pCaps->DeviceType, adapterFormat,
  695.                                                   0, D3DRTYPE_TEXTURE,
  696.                                                   D3DFMT_V8U8 ) ) )
  697.         {
  698.             return S_OK;
  699.         }
  700.     }
  701.     
  702.     return E_FAIL;
  703. }
  704. //-----------------------------------------------------------------------------
  705. // Name: CreateEarthVertexBuffer()
  706. // Desc: 建立要进行凹凸贴图地球体各个定点
  707. //-----------------------------------------------------------------------------
  708. HRESULT CMyD3DApplication::CreateEarthVertexBuffer()
  709. {
  710.     SAFE_RELEASE( m_pEarthVB );
  711.     // 选择 tesselation级
  712.     DWORD dwNumSphereRings    = m_bHighTesselation ? 15 :  5;
  713.     DWORD dwNumSphereSegments = m_bHighTesselation ? 30 : 10;
  714.     m_dwNumSphereVertices = 2 * dwNumSphereRings * (dwNumSphereSegments+1);
  715.     DWORD usage = D3DUSAGE_WRITEONLY;
  716.     if( m_bDispMapOn )
  717.         usage |= D3DUSAGE_NPATCHES;
  718.     // 创建顶点缓冲
  719. if( FAILED( m_pd3dDevice->CreateVertexBuffer( m_dwNumSphereVertices*sizeof(BUMPVERTEX),
  720.                                                   usage, BUMPVERTEX::FVF,
  721.                                                   D3DPOOL_MANAGED, &m_pEarthVB, NULL ) ) )
  722.         return E_FAIL;
  723.     return S_OK;
  724. }
  725. //-----------------------------------------------------------------------------
  726. // Name: SetMenuStates()
  727. // Desc:
  728. //-----------------------------------------------------------------------------
  729. VOID CMyD3DApplication::SetMenuStates()
  730. {
  731.     HMENU hMenu = GetMenu( m_hWnd );
  732.     CheckMenuItem( hMenu, IDM_TEXTURETOGGLE,
  733.                     m_bTextureOn ? MF_CHECKED : MF_UNCHECKED );
  734.     CheckMenuItem( hMenu, IDM_BUMPMAPTOGGLE,
  735.                     m_bBumpMapOn ? MF_CHECKED : MF_UNCHECKED );
  736.     CheckMenuItem( hMenu, IDM_ENVMAPTOGGLE,
  737.                     m_bEnvMapOn ? MF_CHECKED : MF_UNCHECKED );
  738.     CheckMenuItem( hMenu, IDM_DISPMAPTOGGLE,
  739.                     m_bDispMapOn ? MF_CHECKED : MF_UNCHECKED );
  740.     CheckMenuItem( hMenu, IDM_U8V8L8,
  741.                     m_BumpMapFormat==D3DFMT_X8L8V8U8 ? MF_CHECKED : MF_UNCHECKED );
  742.     CheckMenuItem( hMenu, IDM_U5V5L6,
  743.                     m_BumpMapFormat==D3DFMT_L6V5U5 ? MF_CHECKED : MF_UNCHECKED );
  744.     CheckMenuItem( hMenu, IDM_U8V8,
  745.                     m_BumpMapFormat==D3DFMT_V8U8 ? MF_CHECKED : MF_UNCHECKED );
  746.     CheckMenuItem( hMenu, IDM_LOW_TESSELATION,
  747.                     (!m_bHighTesselation) ? MF_CHECKED : MF_UNCHECKED );
  748.     CheckMenuItem( hMenu, IDM_HIGH_TESSELATION,
  749.                     m_bHighTesselation ? MF_CHECKED : MF_UNCHECKED );
  750. }
  751. //-----------------------------------------------------------------------------
  752. // Name: MsgProc()
  753. // Desc: 消息处理函数,处理来自键盘和菜单的消息
  754. //-----------------------------------------------------------------------------
  755. LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  756.                                     LPARAM lParam )
  757. {
  758.     // 将鼠标消息传递给 ArcBall ,从而建立变换矩阵
  759.     m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
  760.     // Trap context menu
  761.     if( WM_CONTEXTMENU == uMsg )
  762.         return 0;
  763.     //处理菜单命令
  764.     if( WM_COMMAND == uMsg )
  765.     {
  766.         switch( LOWORD(wParam) )
  767.         {
  768.             case IDM_TEXTURETOGGLE:
  769.                 m_bTextureOn = !m_bTextureOn;
  770.                 break;
  771.             case IDM_BUMPMAPTOGGLE:
  772.                 m_bBumpMapOn = !m_bBumpMapOn;
  773.                 break;
  774.             case IDM_DISPMAPTOGGLE:
  775.                 m_bDispMapOn  = !m_bDispMapOn;
  776.                 CreateEarthVertexBuffer();
  777.                 break;
  778.             case IDM_ENVMAPTOGGLE:
  779.                 m_bEnvMapOn  = !m_bEnvMapOn;
  780.                 break;
  781.             case IDM_U8V8L8:
  782.                 SAFE_RELEASE( m_psBumpMap );
  783.                 m_BumpMapFormat = D3DFMT_X8L8V8U8;
  784.                 InitBumpMap();
  785.                 break;
  786.             case IDM_U5V5L6:
  787.                 SAFE_RELEASE( m_psBumpMap );
  788.                 m_BumpMapFormat = D3DFMT_L6V5U5;
  789.                 InitBumpMap();
  790.                 break;
  791.             case IDM_U8V8:
  792.                 SAFE_RELEASE( m_psBumpMap );
  793.                 m_BumpMapFormat = D3DFMT_V8U8;
  794.                 InitBumpMap();
  795.                 break;
  796.             case IDM_LOW_TESSELATION:
  797.                 m_bHighTesselation = FALSE;
  798.                 CreateEarthVertexBuffer();
  799.                 break;
  800.             case IDM_HIGH_TESSELATION:
  801.                 m_bHighTesselation = TRUE;
  802.                 CreateEarthVertexBuffer();
  803.                 break;
  804.         }
  805.         // 当有状态变化时,更新菜单
  806. SetMenuStates();
  807.     }
  808.     // 将其他消息传递给默认处理函数
  809.     return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
  810. }