?? bumpearth.cpp
字號:
//-----------------------------------------------------------------------------
// File: BumpEarth.cpp
//
// Desc: Direct3D 環境貼圖/凹凸貼圖 實例。
//-----------------------------------------------------------------------------
#define STRICT
#include <Windows.h>
#include <commctrl.h>
#include <math.h>
#include <stdio.h>
#include <D3DX9.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "D3DFile.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "resource.h"
//-----------------------------------------------------------------------------
// 定義,常量,全局變量聲明
//-----------------------------------------------------------------------------
// Vertex 數據結構,bumpmapped environment map使用
struct BUMPVERTEX
{
D3DXVECTOR3 p;
D3DXVECTOR3 n;
FLOAT tu1, tv1;
FLOAT tu2, tv2;
static const DWORD FVF;
};
const DWORD BUMPVERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2;
// 將FLOAT轉換為DWORD,在SetRenderState()調用中將用到
inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc:
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
CD3DFont* m_pFont; //用于輸出文本
CD3DArcBall m_ArcBall; //用于鼠標輸入
LPDIRECT3DTEXTURE9 m_pBlockTexture; //黑,灰紋理
LPDIRECT3DTEXTURE9 m_pEarthTexture; //地表紋理
LPDIRECT3DTEXTURE9 m_pEnvMapTexture; //環境貼圖
LPDIRECT3DTEXTURE9 m_pEarthBumpTexture; //凹凸貼圖資源
LPDIRECT3DTEXTURE9 m_psBumpMap; //實際的凹凸貼圖
CD3DMesh* m_pSkyBox;
LPDIRECT3DTEXTURE9 m_pDispMapTexture; //偏移貼圖紋理
IDirect3DVertexShader9* m_pDispMapBumpShader;//偏移貼圖+凹凸貼圖著色
IDirect3DVertexShader9* m_pDispMapShader; //偏移貼圖+無凹凸貼圖著色
IDirect3DVertexDeclaration9* m_pDispMapVertexDecl;
D3DXMATRIXA16 m_matWorld;
D3DXMATRIXA16 m_matView;
D3DXMATRIXA16 m_matProj;
D3DFORMAT m_BumpMapFormat; //凹凸貼圖紋理格式
LPDIRECT3DVERTEXBUFFER9 m_pEarthVB; //地球幾何體
DWORD m_dwNumSphereVertices;
BOOL m_bHighTesselation; //用戶選項
BOOL m_bTextureOn;
BOOL m_bBumpMapOn;
BOOL m_bEnvMapOn;
BOOL m_bDeviceValidationFailed;
BOOL m_bDispMapOn; //偏移貼圖開關
BOOL m_bCanDoDispMap;
VOID SetMenuStates();
HRESULT CreateEarthVertexBuffer();
VOID ApplyEnvironmentMap();
HRESULT InitBumpMap();
protected:
HRESULT OneTimeSceneInit();
HRESULT InitDeviceObjects();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT DeleteDeviceObjects();
HRESULT Render();
HRESULT FrameMove();
HRESULT FinalCleanup();
HRESULT ConfirmDevice( D3DCAPS9*, DWORD, D3DFORMAT, D3DFORMAT );
public:
CMyD3DApplication();
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
};
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 程序入口。進行全部的初始化工作,然后進入消息處理循環,空閑時間被用來
// 進行渲染
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
CMyD3DApplication d3dApp;
InitCommonControls();
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc:
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
m_strWindowTitle = _T("BumpEarth: Direct3D BumpMapping Demo");
m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
m_bShowCursorWhenFullscreen = TRUE;
m_psBumpMap = NULL;
m_bTextureOn = TRUE;
m_bBumpMapOn = TRUE;
m_bEnvMapOn = TRUE;
m_bHighTesselation = TRUE;
m_bDispMapOn = FALSE;
m_bCanDoDispMap = FALSE;
m_pDispMapShader = NULL;
m_pDispMapBumpShader= NULL;
m_pDispMapVertexDecl= NULL;
m_pDispMapTexture = NULL;
m_pBlockTexture = NULL;
m_pEarthTexture = NULL;
m_pEarthBumpTexture = NULL;
m_pEnvMapTexture = NULL;
m_pSkyBox = NULL;
m_bDeviceValidationFailed = FALSE;
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_pEarthVB = NULL;
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: 在初始程序開始時調用。此函數進行所有常設值得初始化
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
// 設置指針使用戶可以用鼠標移動目標
#ifdef _WIN64
SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
#else
SetClassLong( m_hWnd, GCL_HCURSOR, HandleToLong( LoadCursor( NULL, IDC_SIZEALL ) ) );
#endif
m_pSkyBox = new CD3DMesh();
if( m_pSkyBox == NULL )
return E_OUTOFMEMORY;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ApplyEnvironmentMap()
// Desc: 計算每個頂點的法向,從而決定環境貼圖對應的紋理
//-----------------------------------------------------------------------------
VOID CMyD3DApplication::ApplyEnvironmentMap()
{
D3DXMATRIXA16 matWorldView;
D3DXMatrixMultiply( &matWorldView, &m_matWorld, &m_matView );
BUMPVERTEX* vtx;
m_pEarthVB->Lock( 0, 0, (void**)&vtx, 0 );
DWORD dwNumSphereRings = m_bHighTesselation ? 15 : 5;
DWORD dwNumSphereSegments = m_bHighTesselation ? 30 : 10;
FLOAT fDeltaRingAngle = ( D3DX_PI / dwNumSphereRings );
FLOAT fDeltaSegAngle = ( 2.0f * D3DX_PI / dwNumSphereSegments );
D3DXVECTOR4 vT;
FLOAT fScale;
for( DWORD ring = 0; ring < dwNumSphereRings; ring++ )
{
FLOAT r0 = sinf( (ring+0) * fDeltaRingAngle );
FLOAT r1 = sinf( (ring+1) * fDeltaRingAngle );
FLOAT y0 = cosf( (ring+0) * fDeltaRingAngle );
FLOAT y1 = cosf( (ring+1) * fDeltaRingAngle );
for( DWORD seg = 0; seg < (dwNumSphereSegments+1); seg++ )
{
FLOAT x0 = r0 * sinf( seg * fDeltaSegAngle );
FLOAT z0 = r0 * cosf( seg * fDeltaSegAngle );
FLOAT x1 = r1 * sinf( seg * fDeltaSegAngle );
FLOAT z1 = r1 * cosf( seg * fDeltaSegAngle );
(*vtx).p = (*vtx).n = D3DXVECTOR3(x0,y0,z0);
(*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
(*vtx).tv2 = (ring+0) / (FLOAT)dwNumSphereRings;
D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
fScale = 1.37f / D3DXVec4Length( &vT );
(*vtx).tu1 = 0.5f + fScale*vT.x;
(*vtx).tv1 = 0.5f - fScale*vT.y;
vtx++;
(*vtx).p = (*vtx).n = D3DXVECTOR3(x1,y1,z1);
(*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
(*vtx).tv2 = (ring+1) / (FLOAT)dwNumSphereRings;
D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
fScale = 1.37f / D3DXVec4Length( &vT );
(*vtx).tu1 = 0.5f + fScale*vT.x;
(*vtx).tv1 = 0.5f - fScale*vT.y;
vtx++;
}
}
m_pEarthVB->Unlock();
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
static FLOAT fRotationAngle = 0.0f;
if( FALSE == m_ArcBall.IsBeingDragged() )
fRotationAngle += m_fElapsedTime;
D3DXMatrixRotationY( &m_matWorld, -fRotationAngle );
D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetRotationMatrix() );
D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetTranslationMatrix() );
D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -3.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &m_matView, &vEyePt, &vLookatPt, &vUpVec );
ApplyEnvironmentMap();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
if( FAILED( m_pd3dDevice->BeginScene() ) )
return S_OK;
{
D3DXMATRIXA16 matWorldSkybox;
D3DXMatrixScaling( &matWorldSkybox, 10.0f, 10.0f, 10.0f );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorldSkybox );
D3DXMATRIXA16 matViewSkybox = m_matView;
matViewSkybox._41 = matViewSkybox._42 = matViewSkybox._43 = 0.0f;
m_pd3dDevice->SetTransform( D3DTS_VIEW, &matViewSkybox );
m_pd3dDevice->SetRenderState( D3DRS_WRAP0, 0 );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
if( (m_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) == D3DPTADDRESSCAPS_MIRROR )
{
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
}
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_ALPHAOP, D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );
m_pSkyBox->Render( m_pd3dDevice );
m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );
}
m_pd3dDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
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 );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
if( m_bTextureOn )
m_pd3dDevice->SetTexture( 0, m_pEarthTexture );
else
m_pd3dDevice->SetTexture( 0, m_pBlockTexture );
if( m_bDispMapOn )
{
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
m_pd3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 2 );
m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -