随笔 - 505  文章 - 1034  trackbacks - 0
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011


子曾经曰过:编程无他,唯手熟尔!

常用链接

留言簿(94)

随笔分类(649)

随笔档案(505)

相册

BCB

Crytek

  • crymod
  • Crytek's Offical Modding Portal

Game Industry

OGRE

other

Programmers

Qt

WOW Stuff

搜索

  •  

积分与排名

  • 积分 - 894862
  • 排名 - 14

最新随笔

最新评论

阅读排行榜

评论排行榜







EffectParam.fx

//==============================================================
// Desc: 效果文件
//==============================================================


//--------------------------------------------------------------
// 全局变量
//--------------------------------------------------------------
shared float4x4 g_mWorld;
shared float4x4 g_mView;
shared float4x4 g_mProj;

shared float4 g_vLight      
= float4( 0.0f0.0f-10.0f1.0f );  //光源在观察空间中的位置
shared float4 g_vLightColor = float4( 1.0f1.0f1.0f1.0f );
texture  g_txScene;
float4   Diffuse;


//--------------------------------------------------------------
// 纹理采样器
//--------------------------------------------------------------
sampler2D g_samScene = sampler_state
{
    Texture 
= <g_txScene>;
    MinFilter 
= Linear;
    MagFilter 
= Linear;
    MipFilter 
= Linear;
};


//--------------------------------------------------------------
// Desc: 顶点渲染
//--------------------------------------------------------------
void VertScene( float4 vPos : POSITION,
                float3 vNormal : NORMAL,
                float2 vTex0 : TEXCOORD0,
                
out float4 oDiffuse : COLOR0,
                
out float4 oPos : POSITION,
                
out float2 oTex0 : TEXCOORD0 )
{
    
//顶点坐标变换
    oPos = mul( vPos, g_mWorld );
    oPos 
= mul( oPos, g_mView );
    oPos 
= mul( oPos, g_mProj );

    
//计算顶点在观察空间中的坐标
    float4 wPos = mul( vPos, g_mWorld );
    wPos 
= mul( wPos, g_mView );

    
//计算顶点在观察空间中的法线向量
    float3 N =  mul( vNormal, (float3x3)g_mWorld );
    N 
= normalize( mul( N, (float3x3)g_mView ) );

    
//计算灯光方向
    float3 InvL = g_vLight - wPos;
    InvL 
= normalize( InvL );

    
//计算顶点漫反射颜色
    oDiffuse = saturate( dot( N, InvL ) ) * Diffuse * g_vLightColor;

    
//简单复制输出纹理坐标
    oTex0 = vTex0;
}


//--------------------------------------------------------------
// Desc: 像素渲染
//--------------------------------------------------------------
float4 PixScene( float4 Diffuse : COLOR0,
                 float2 Tex0 : TEXCOORD0 ) : COLOR0
{
    
return tex2D( g_samScene, Tex0 ) * Diffuse;
}


//--------------------------------------------------------------
// Desc: 技术
//-------------------------------------------------------------
technique RenderScene
{
    pass P0
    {
        VertexShader 
= compile vs_2_0 VertScene();
        PixelShader  
= compile ps_2_0 PixScene();
    }
}


//=============================================================================
// Desc: 主程序源文件
//=============================================================================
#include "dxstdafx.h"
#include 
"resource.h"
#include 
<crtdbg.h>

//#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
//#define DEBUG_PS   // Uncomment this line to debug pixel shaders 

// SCROLL_TIME dictates the time one scroll op takes, in seconds.
#define SCROLL_TIME 0.5f

//-----------------------------------------------------------------------------
// Desc: 网格列表结构
//-----------------------------------------------------------------------------
struct MESHLISTDATA
{
    WCHAR wszName[MAX_PATH];
    WCHAR wszFile[MAX_PATH];
    DWORD dwNumMat;  
//材质数量
} g_MeshListData[] =
{
    { L
"Car", L"car2.x"0 },
    { L
"Banded Earth", L"sphereband.x"0 },
    { L
"Dwarf", L"dwarf\\DwarfWithEffectInstance.x"0 },
    { L
"Virus", L"cytovirus.x"0 },
    { L
"Car", L"car2.x"0 },
    { L
"Banded Earth", L"sphereband.x"0 },
    { L
"Dwarf", L"dwarf\\DwarfWithEffectInstance.x"0 },
};


//-----------------------------------------------------------------------------
// Desc: 顶点结构和灵活顶点格式
//-----------------------------------------------------------------------------
struct MESHVERTEX
{
    D3DXVECTOR3 Position;
    D3DXVECTOR3 Normal;
    D3DXVECTOR2 Tex;

    
const static D3DVERTEXELEMENT9 Decl[4];
};


//-----------------------------------------------------------------------------
// Desc: 顶点声明
//-----------------------------------------------------------------------------
const D3DVERTEXELEMENT9 MESHVERTEX::Decl[] =
{
    { 
00,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
    { 
012, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
    { 
024, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
    D3DDECL_END()
};


//-----------------------------------------------------------------------------
// Desc: 网格材质结构
//-----------------------------------------------------------------------------
struct CMeshMaterial
{
    ID3DXEffect        
*m_pEffect;
    D3DXHANDLE          m_hParam;
    IDirect3DTexture9  
*m_pTexture;

public:
    CMeshMaterial()
    {
        m_pEffect  
= NULL;
        m_hParam   
= NULL;
        m_pTexture 
= NULL;
    }

    
~CMeshMaterial()
    {
        SAFE_RELEASE( m_pEffect );
        SAFE_RELEASE( m_pTexture );
    }

    
const CMeshMaterial &operator=const CMeshMaterial &rhs )
    {
        m_pEffect 
= rhs.m_pEffect;
        m_hParam 
= rhs.m_hParam;
        m_pTexture 
= rhs.m_pTexture;
        m_pEffect
->AddRef();
        m_pTexture
->AddRef();
        
return *this;
    }
};


//外部变量
extern ID3DXEffect* g_pEffect;                //效果
extern IDirect3DTexture9* g_pDefaultTex;      //纹理
extern IDirect3DCubeTexture9* g_pEnvMapTex;   //立方体纹理


//-----------------------------------------------------------------------------
// Desc: 效果网格类
//-----------------------------------------------------------------------------
class CEffectMesh
{
    WCHAR          m_wszMeshFile[MAX_PATH];
    ID3DXMesh     
*m_pMesh;
    CMeshMaterial 
*m_pMaterials;
    DWORD          m_dwNumMaterials;

public:
    CEffectMesh()
    {
        m_pMesh          
= NULL;
        m_pMaterials     
= NULL;
        m_dwNumMaterials 
= 0;
    }

    CEffectMesh( 
const CEffectMesh &old )
    {
        m_pMesh 
= NULL; 
        m_pMaterials 
= NULL;
        
*this = old;
    }

    
~CEffectMesh()
    {
        Destroy();
    }

    
const CEffectMesh &operator=const CEffectMesh &rhs )
    {
        
ifthis == &rhs )
            
return *this;

        StringCchCopyW( m_wszMeshFile, MAX_PATH, rhs.m_wszMeshFile );
        m_dwNumMaterials 
= rhs.m_dwNumMaterials;
        SAFE_RELEASE( m_pMesh );
        
if( ( m_pMesh = rhs.m_pMesh ) != 0 ) m_pMesh->AddRef();
        delete[] m_pMaterials;
        m_pMaterials 
= new CMeshMaterial[m_dwNumMaterials];
        
if( m_pMaterials )
        {
            
for( UINT i = 0; i < m_dwNumMaterials; ++i )
                m_pMaterials[i] 
= rhs.m_pMaterials[i];
        }
        
return *this;
    }

    DWORD GetNumMaterials() 
const { return m_dwNumMaterials; }
    ID3DXMesh 
*GetMesh() { return m_pMesh; }

    HRESULT Create( LPCWSTR wszFileName, IDirect3DDevice9 
*pd3dDevice );

    HRESULT Destroy()
    {
        delete[] m_pMaterials;
        m_pMaterials 
= NULL;
        m_dwNumMaterials 
= 0;
        SAFE_RELEASE( m_pMesh );
        
return S_OK;
    }

    
void Render( IDirect3DDevice9 *pd3dDevice )
    {
        HRESULT hr;

        
for( UINT i = 0; i < m_dwNumMaterials; ++i )
        {
            CMeshMaterial 
*pMat = &m_pMaterials[i];
            V( pMat
->m_pEffect->ApplyParameterBlock( pMat->m_hParam ) );

            UINT cPasses;
            V( pMat
->m_pEffect->Begin( &cPasses, 0 ) );
            
for( UINT p = 0; p < cPasses; ++p )
            {
                V( pMat
->m_pEffect->BeginPass( p ) );
                V( m_pMesh
->DrawSubset( i ) );
                V( pMat
->m_pEffect->EndPass() );
            }
            V( pMat
->m_pEffect->End() );
        }
    }
};


//-----------------------------------------------------------------------------
// Desc: 网格控制球类
//-----------------------------------------------------------------------------
class CMeshArcBall : public CD3DArcBall
{
public:
    
void OnBegin( int nX, int nY, D3DXMATRIXA16 *pmInvViewRotate )
    {
        m_bDrag 
= true;
        m_qDown 
= m_qNow;
        m_vDownPt 
= ScreenToVector( (float)nX, (float)nY );
        D3DXVECTOR4 v;
        D3DXVec3Transform( 
&v, &m_vDownPt, pmInvViewRotate );
        m_vDownPt 
= (D3DXVECTOR3)v;
    }

    
void OnMove( int nX, int nY, D3DXMATRIXA16 *pmInvViewRotate )
    {
        
if (m_bDrag) 
        { 
            m_vCurrentPt 
= ScreenToVector( (float)nX, (float)nY );
            D3DXVECTOR4 v;
            D3DXVec3Transform( 
&v, &m_vCurrentPt, pmInvViewRotate );
            m_vCurrentPt 
= (D3DXVECTOR3)v;
            m_qNow 
= m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt );
        }
    }

    LRESULT HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, D3DXMATRIXA16 
*pmInvViewRotate )
    {
        
// Current mouse position
        int iMouseX = (short)LOWORD(lParam);
        
int iMouseY = (short)HIWORD(lParam);

        
switch( uMsg )
        {
            
case WM_LBUTTONDOWN:
            
case WM_LBUTTONDBLCLK:
                SetCapture( hWnd );
                OnBegin( iMouseX, iMouseY, pmInvViewRotate );
                
return TRUE;

            
case WM_LBUTTONUP:
                ReleaseCapture();
                OnEnd();
                
return TRUE;

            
case WM_CAPTURECHANGED:
                
if( (HWND)lParam != hWnd )
                {
                    ReleaseCapture();
                    OnEnd();
                }
                
return TRUE;

            
case WM_MOUSEMOVE:
                
if( MK_LBUTTON&wParam )
                {
                    OnMove( iMouseX, iMouseY, pmInvViewRotate );
                }
                
return TRUE;
        }
        
return FALSE;
    }
};


//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
ID3DXFont*                 g_pFont = NULL;         //ID3DXFont字体对象
ID3DXSprite*               g_pTextSprite = NULL;   //ID3DXSprite文本精灵对象
 
bool                       g_bShowHelp = true;     //标识是否显示简单说明文本
CDXUTDialogResourceManager g_DialogResourceManager;//对话框资源管理器
CD3DSettingsDlg            g_SettingsDlg;          //Direct3D设备设置对话框
CDXUTDialog                g_HUD;                  //对话框
CDXUTDialog                g_SampleUI;             //对话框

IDirect3DTexture9
*         g_pDefaultTex = NULL;   //默认纹理
IDirect3DCubeTexture9*     g_pEnvMapTex  = NULL;   //环境映射纹理

ID3DXEffect
*                  g_pEffect = NULL;       //效果接口
IDirect3DVertexDeclaration9  *g_pDecl = NULL;         //顶点声明
ID3DXEffectPool*              g_pEffectPool = NULL;   //效果池
DWORD                         g_dwShaderFlags = D3DXFX_NOT_CLONEABLE; //渲染器创建标志

CModelViewerCamera            g_Camera;           
//摄影机
CGrowableArray<CEffectMesh>   g_Meshes;           //网格模型列表
CGrowableArray<CMeshArcBall>  g_ArcBall;          //各个网格模型的控制球
CGrowableArray<D3DXMATRIXA16> g_amWorld;          //各个网格模型的世界矩阵

int                     g_nActiveMesh = 0;        //激活网格模型书
D3DXMATRIXA16           g_mScroll;                //滚动矩阵
float                   g_fAngleToScroll = 0.0f;  //滚动的角度
float                   g_fAngleLeftToScroll = 0.0f;


//-----------------------------------------------------------------------------
// 控件ID
//-----------------------------------------------------------------------------
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           3
#define IDC_CHANGEDEVICE        4
#define IDC_SHARE               5
#define IDC_SCROLLLEFT          6
#define IDC_SCROLLRIGHT         7
#define IDC_MESHNAME            8
#define IDC_MATCOUNT            9


//-----------------------------------------------------------------------------
// Desc: 函数声明
//-----------------------------------------------------------------------------
bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9
* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9
* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
bool* pbNoFurtherProcessing, void* pUserContext );
void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
void    CALLBACK OnLostDevice( void* pUserContext );
void    CALLBACK OnDestroyDevice( void* pUserContext );

void    InitApp();
HRESULT LoadMesh( IDirect3DDevice9
* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
void    RenderText();


//-----------------------------------------------------------------------------
// Desc: 效果网格模型创建函数
//-----------------------------------------------------------------------------
HRESULT CEffectMesh::Create( LPCWSTR wszFileName, IDirect3DDevice9 *pd3dDevice )
{
    HRESULT hr;

    WCHAR str[MAX_PATH];
    WCHAR wszMeshPath[MAX_PATH];
    ID3DXBuffer 
*pAdjacency;
    ID3DXBuffer 
*pMaterials;
    ID3DXBuffer 
*pEffectInstance;
    DWORD dwNumMaterials;

    
//保存网格文件名
    StringCchCopy( m_wszMeshFile, MAX_PATH, wszFileName );

    
//加载网格模型
    V_RETURN( DXUTFindDXSDKMediaFileCch( wszMeshPath, MAX_PATH, m_wszMeshFile ) );
    V_RETURN( D3DXLoadMeshFromX( wszMeshPath, D3DXMESH_MANAGED, pd3dDevice,
                                    
&pAdjacency, &pMaterials, &pEffectInstance,
                                    
&dwNumMaterials, &m_pMesh ) );
   
    ID3DXMesh 
*pCloneMesh;
    V_RETURN( m_pMesh
->CloneMesh( m_pMesh->GetOptions(), MESHVERTEX::Decl, pd3dDevice, &pCloneMesh ) );
    m_pMesh
->Release();
    m_pMesh 
= pCloneMesh;

    
//从路径中提取文件名
    WCHAR *pLastBSlash = wcsrchr( wszMeshPath, L'\\' );
    
if( pLastBSlash )
    {
        
*( pLastBSlash + 1 ) = L'\0';
    }
    
else
        StringCchCopyW( wszMeshPath, MAX_PATH, L
".\\" );

    
//确保网格模型顶点包含法线信息
    bool bHasNormals = ( m_pMesh->GetFVF() & D3DFVF_NORMAL ) != 0;
    
if!bHasNormals )
        D3DXComputeNormals( m_pMesh, (DWORD
*)pAdjacency->GetBufferPointer() );

    m_pMaterials 
= new CMeshMaterial[dwNumMaterials];
    
if!m_pMaterials )
        
return E_OUTOFMEMORY;

    
//提取材质
    D3DXMATERIAL *pXMats = (D3DXMATERIAL *)pMaterials->GetBufferPointer();
    D3DXEFFECTINSTANCE 
*pEI = (D3DXEFFECTINSTANCE *)pEffectInstance->GetBufferPointer();
    
for( UINT i = 0; i < dwNumMaterials; ++i )
    {
        
// Obtain the effect

        hr 
= S_OK;
       
        StringCchCopyW( str, MAX_PATH, wszMeshPath );
        MultiByteToWideChar( CP_ACP, 
0, pEI[i].pEffectFilename, -1, str + lstrlenW( str ), MAX_PATH );

        
if( pEI[i].pEffectFilename == NULL )
            hr 
= E_FAIL;

        WCHAR wszFxName[MAX_PATH];
        MultiByteToWideChar( CP_ACP, 
0, pEI[i].pEffectFilename, -1, wszFxName, MAX_PATH );

        
if( SUCCEEDED(hr) )
        {
            WCHAR szTmp[MAX_PATH];
            StringCchCopy( szTmp, MAX_PATH, L
"SharedFx\\" );
            StringCchCat( szTmp, MAX_PATH, wszFxName );
            hr 
= DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szTmp );
            
if( FAILED( hr ) )
            {
                
//从SKD目录中查找
                hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, wszFxName );
            }
        }

        
if( SUCCEEDED( hr ) )
            DXUTGetGlobalResourceCache().CreateEffectFromFile( pd3dDevice, str, NULL, NULL, g_dwShaderFlags, g_pEffectPool,
                                                               
&m_pMaterials[i].m_pEffect, NULL );
        
if!m_pMaterials[i].m_pEffect )
        {
            
// No valid effect for this material.  Use the default.
            m_pMaterials[i].m_pEffect = g_pEffect;
            m_pMaterials[i].m_pEffect
->AddRef();
        }

        
// Set the technique this material should use
        D3DXHANDLE hTech;
        m_pMaterials[i].m_pEffect
->FindNextValidTechnique( NULL, &hTech );
        m_pMaterials[i].m_pEffect
->SetTechnique( hTech );

        
// Create a parameter block to include all parameters for the effect.
        m_pMaterials[i].m_pEffect->BeginParameterBlock();
        
for( UINT param = 0; param < pEI[i].NumDefaults; ++param )
        {
            D3DXHANDLE hHandle 
= m_pMaterials[i].m_pEffect->GetParameterByName( NULL, pEI[i].pDefaults[param].pParamName );
            D3DXPARAMETER_DESC desc;
            
if( hHandle != NULL )
            {
                m_pMaterials[i].m_pEffect
->GetParameterDesc( hHandle, &desc );
                
if( desc.Type == D3DXPT_BOOL || 
                    desc.Type 
== D3DXPT_INT || 
                    desc.Type 
== D3DXPT_FLOAT || 
                    desc.Type 
== D3DXPT_STRING )
                {
                    m_pMaterials[i].m_pEffect
->SetValue( pEI[i].pDefaults[param].pParamName,
                                                        pEI[i].pDefaults[param].pValue,
                                                        pEI[i].pDefaults[param].NumBytes );
                }
            }
        }

        
//获取纹理
        hr = S_OK;

        
if( pXMats[i].pTextureFilename )
        {
            StringCchCopyW( str, MAX_PATH, wszMeshPath );
            MultiByteToWideChar( CP_ACP, 
0, pXMats[i].pTextureFilename, -1, str + lstrlenW( str ), MAX_PATH );
            
            
if( INVALID_FILE_ATTRIBUTES == ::GetFileAttributesW( str ) )
            {
                WCHAR wszTexName[MAX_PATH];
        
                MultiByteToWideChar( CP_ACP, 
0, pXMats[i].pTextureFilename, -1, wszTexName, MAX_PATH );
                hr 
= DXUTFindDXSDKMediaFileCch( str, MAX_PATH, wszTexName );
            }

            
if( SUCCEEDED( hr ) )
                DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, str, 
&m_pMaterials[i].m_pTexture );
        }

        
if!m_pMaterials[i].m_pTexture )
        {
            
//如果没有纹理, 或纹理加载失败,使用默认纹理
            m_pMaterials[i].m_pTexture = g_pDefaultTex;
            m_pMaterials[i].m_pTexture
->AddRef();
        }

        
// Include the texture in the parameter block if the effect requires one.
        D3DXHANDLE hTexture = m_pMaterials[i].m_pEffect->GetParameterByName( NULL, "g_txScene" );
        
if( hTexture )
            m_pMaterials[i].m_pEffect
->SetTexture( hTexture, m_pMaterials[i].m_pTexture );

        
// Include the environment map texture in the parameter block if the effect requires one.
        hTexture = m_pMaterials[i].m_pEffect->GetParameterByName( NULL, "g_txEnvMap" );
        
if( hTexture )
            m_pMaterials[i].m_pEffect
->SetTexture( hTexture, g_pEnvMapTex );

        
// Save the parameter block
        m_pMaterials[i].m_hParam = m_pMaterials[i].m_pEffect->EndParameterBlock();
    }

    SAFE_RELEASE( pAdjacency );
    SAFE_RELEASE( pMaterials );
    SAFE_RELEASE( pEffectInstance );
    m_dwNumMaterials 
= dwNumMaterials;
    
return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    
//为Debug配置启用运行时内存检查功能
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
| _CRTDBG_LEAK_CHECK_DF );
#endif

    
//设置回调函数
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( KeyboardProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );

    
//全屏幕模式下显示鼠标光标
    DXUTSetCursorSettings( truetrue );

    
//应用程序相关的初始化
    InitApp();

    
//初始化DXUT, 创建窗口, 创建Direct3D设备对象
    DXUTInit( truetruetrue );
    DXUTCreateWindow( L
"EffectParam" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, 
true640480, IsDeviceAcceptable, ModifyDeviceSettings );

    
//进入消息循环和场景渲染
    DXUTMainLoop();

    
//在此进行应用程序相关的清除工作

    
return DXUTGetExitCode();
}


//-----------------------------------------------------------------------------
// Desc: 应用程序相关初始化
//-----------------------------------------------------------------------------
void InitApp()
{
    
//初始化对话框
    g_SettingsDlg.Init( &g_DialogResourceManager );
    g_HUD.Init( 
&g_DialogResourceManager );
    g_SampleUI.Init( 
&g_DialogResourceManager );

    
//为g_HUD对话框设置消息处理函数,添加控件
    g_HUD.SetCallback( OnGUIEvent ); int iY = 10
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L
"Toggle full screen"35, iY, 12522 );
    g_HUD.AddButton( IDC_TOGGLEREF, L
"Toggle REF (F3)"35, iY += 2412522 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L
"Change device (F2)"35, iY += 2412522, VK_F2 );

    
//为g_SampleUI对话框设置消息处理函数,添加控件
    g_SampleUI.SetCallback( OnGUIEvent ); iY = 10;
    g_SampleUI.AddStatic( IDC_MESHNAME, L
"Mesh Name"0, iY, 16020 );
    g_SampleUI.AddStatic( IDC_MATCOUNT, L
"Number of materials: 0"0, iY += 2016020 );
    g_SampleUI.AddButton( IDC_SCROLLLEFT, L
"<<"5, iY += 247024 );
    g_SampleUI.AddButton( IDC_SCROLLRIGHT, L
">>"85, iY, 7024 );
    g_SampleUI.AddCheckBox( IDC_SHARE, L
"Enable shared parameters"0, iY += 3216024true );

    
//初始化控制球
    forint i = 0; i < sizeof(g_MeshListData)/sizeof(g_MeshListData[0]); ++i )
    {
        g_ArcBall.Add( CMeshArcBall() );
        g_ArcBall[g_ArcBall.GetSize()
-1].SetTranslationRadius( 2.0f );
    }

    
//设置摄影机
    D3DXVECTOR3 vecEye(0.0f0.0f-5.0f);
    D3DXVECTOR3 vecAt (
0.0f0.0f-3.0f);
    g_Camera.SetViewParams( 
&vecEye, &vecAt );
    g_Camera.SetButtonMasks( 
0, MOUSE_WHEEL, 0 );
    g_Camera.SetRadius( 
5.0f1.0f );
}


//-----------------------------------------------------------------------------
// Desc: 设备能力检查
//-----------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                  D3DFORMAT BackBufferFormat, 
bool bWindowed, void* pUserContext )
{
    
//检查后台缓冲区格式是否支持Alpha混合等操作(post pixel blending operations)
    IDirect3D9* pD3D = DXUTGetD3DObject(); 
    
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
        
return false;

    
//检查当前设备支持的像素渲染器版本是否低于1.1
    if( pCaps->PixelShaderVersion < D3DPS_VERSION( 11 ) )
        
return false;

    
return true;
}


//-----------------------------------------------------------------------------
// Desc: 修改Direct3D渲染设备设置
//-----------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
    
// Turn vsync off
    pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    g_SettingsDlg.GetDialogControl()
->GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL )->SetEnabled( false );

    
//如果硬件不支持, 则切换到软件顶点处理
    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
         pCaps
->VertexShaderVersion < D3DVS_VERSION(1,1) )
    {
        pDeviceSettings
->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    
//如果硬件不支持顶点混合, 则使用软件顶点处理模式
    if( pCaps->MaxVertexBlendMatrices < 2 )
        pDeviceSettings
->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;


    
//如果使用硬件顶点处理, 则改为混合顶点处理
    if( pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING )
        pDeviceSettings
->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;    

    
// Add mixed vp to the available vp choices in device settings dialog.
    bool bSvp, bHvp, bPHvp, bMvp;
    DXUTGetEnumeration()
->GetPossibleVertexProcessingList( &bSvp, &bHvp, &bPHvp, &bMvp );
    DXUTGetEnumeration()
->SetPossibleVertexProcessingList( bSvp, falsefalsetrue );

    
//调试顶点渲染器需要参考设备或软件顶点处理
#ifdef DEBUG_VS
    
if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
    {
        pDeviceSettings
->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
        pDeviceSettings
->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
        pDeviceSettings
->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }
#endif

    
//调试像素渲染器需要参考设备
#ifdef DEBUG_PS
    pDeviceSettings
->DeviceType = D3DDEVTYPE_REF;
#endif

    
//如果使用参考设备,则弹出警告对话框
    static bool s_bFirstTime = true;
    
if( s_bFirstTime )
    {
        s_bFirstTime 
= false;
        
if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
            DXUTDisplaySwitchingToREFWarning();
    }

    
return true;
}


//-----------------------------------------------------------------------------
// Desc: 在此创建管理内存资源对象
//-----------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;
    WCHAR str[MAX_PATH];

    V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
    V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );

    
// Create the effect pool object if shared param is enabled
    if( g_SampleUI.GetCheckBox( IDC_SHARE )->GetChecked() )
        V_RETURN( D3DXCreateEffectPool( 
&g_pEffectPool ) );

    
// Create the vertex decl
    V_RETURN( pd3dDevice->CreateVertexDeclaration( MESHVERTEX::Decl, &g_pDecl ) );
    pd3dDevice
->SetVertexDeclaration( g_pDecl );

    
// Create the 1x1 white default texture
    V_RETURN( pd3dDevice->CreateTexture( 1110, D3DFMT_A8R8G8B8,
                                         D3DPOOL_MANAGED, 
&g_pDefaultTex, NULL ) );
    D3DLOCKED_RECT lr;
    V_RETURN( g_pDefaultTex
->LockRect( 0&lr, NULL, 0 ) );
    
*(LPDWORD)lr.pBits = D3DCOLOR_RGBA( 255255255255 );
    V_RETURN( g_pDefaultTex
->UnlockRect( 0 ) );

    
// Create the environment map texture
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"lobby\\lobbycube.dds" ) );
    V_RETURN( D3DXCreateCubeTextureFromFile( pd3dDevice, str, 
&g_pEnvMapTex ) );

    
// Initialize the font
    V_RETURN( DXUTGetGlobalResourceCache().CreateFont( pd3dDevice, 150, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, 
                                                       OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH 
| FF_DONTCARE, 
                                                       L
"Arial"&g_pFont ) );

    
// Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
    
// shader debugger. Debugging vertex shaders requires either REF or software vertex 
    
// processing, and debugging pixel shaders requires REF.  The 
    
// D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
    
// shader debugger.  It enables source level debugging, prevents instruction 
    
// reordering, prevents dead code elimination, and forces the compiler to compile 
    
// against the next higher available software target, which ensures that the 
    
// unoptimized shaders do not exceed the shader model limitations.  Setting these 
    
// flags will cause slower rendering since the shaders will be unoptimized and 
    
// forced into software.  See the DirectX documentation for more information about 
    
// using the shader debugger.
    #ifdef DEBUG_VS
        g_dwShaderFlags 
|= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
    
#endif
    #ifdef DEBUG_PS
        g_dwShaderFlags 
|= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
    
#endif

    
// Read the D3DX effect file
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"EffectParam.fx" ) );

    
// If this fails, there should be debug output as to 
    
// they the .fx file failed to compile
    V_RETURN( DXUTGetGlobalResourceCache().CreateEffectFromFile( pd3dDevice, str, NULL, NULL, g_dwShaderFlags, 
                                                                 g_pEffectPool, 
&g_pEffect, NULL ) );

    
// Create the meshes
    forint i = 0; i < sizeof(g_MeshListData)/sizeof(g_MeshListData[0]); ++i )
    {
        CEffectMesh NewMesh;
        
if( SUCCEEDED( NewMesh.Create( g_MeshListData[i].wszFile, DXUTGetD3DDevice() ) ) )
        {
            g_Meshes.Add( NewMesh );
            D3DXMATRIXA16 mW;
            LPVOID pVerts 
= NULL;
            D3DXMatrixIdentity( 
&mW );
            
if( SUCCEEDED( NewMesh.GetMesh()->LockVertexBuffer( 0&pVerts ) ) )
            {
                D3DXVECTOR3 vCtr;
                
float fRadius;
                
if( SUCCEEDED( D3DXComputeBoundingSphere( (const D3DXVECTOR3*)pVerts,
                                                        NewMesh.GetMesh()
->GetNumVertices(),
                                                        NewMesh.GetMesh()
->GetNumBytesPerVertex(),
                                                        
&vCtr, &fRadius ) ) )
                {
                    D3DXMatrixTranslation( 
&mW, -vCtr.x, -vCtr.y, -vCtr.z );
                    D3DXMATRIXA16 m;
                    D3DXMatrixScaling( 
&m, 1.0f / fRadius,
                                            
1.0f / fRadius,
                                            
1.0f / fRadius );
                    D3DXMatrixMultiply( 
&mW, &mW, &m );
                }
                NewMesh.GetMesh()
->UnlockVertexBuffer();
            }

            g_MeshListData[i].dwNumMat 
= NewMesh.GetNumMaterials();
            g_amWorld.Add( mW );

            
// Set the arcball window size
            const D3DSURFACE_DESC* pD3DSD = DXUTGetBackBufferSurfaceDesc();
            g_ArcBall[g_ArcBall.GetSize()
-1].SetWindow( pD3DSD->Width, pD3DSD->Height );
        }
    }

    g_SampleUI.GetStatic( IDC_MESHNAME )
->SetText( g_MeshListData[g_nActiveMesh].wszName );
    WCHAR wsz[
256];
    StringCchPrintf( wsz, 
256, L"Number of materials: %u", g_MeshListData[g_nActiveMesh].dwNumMat );
    wsz[
255= L'\0';
    g_SampleUI.GetStatic( IDC_MATCOUNT )
->SetText( wsz );

    D3DXMatrixIdentity( 
&g_mScroll );

    
return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been 
// reset, which will happen after a lost device scenario. This is the best location to 
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
// the device is lost. Resources created here should be released in the OnLostDevice 
// callback. 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;

    V_RETURN( g_DialogResourceManager.OnResetDevice() );
    V_RETURN( g_SettingsDlg.OnResetDevice() );

    
if( g_pFont )
        V_RETURN( g_pFont
->OnResetDevice() );
    
if( g_pEffect )
        V_RETURN( g_pEffect
->OnResetDevice() );

    
// Create a sprite to help batch calls when drawing many lines of text
    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );

    
// Setup the camera's projection parameters
    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
    g_Camera.SetProjParams( D3DX_PI
/4, fAspectRatio, 0.1f1000.0f );
    
forint i = 0; i < g_ArcBall.GetSize(); ++i )
        g_ArcBall[i].SetWindow( pBackBufferSurfaceDesc
->Width, pBackBufferSurfaceDesc->Height );

    g_HUD.SetLocation( pBackBufferSurfaceDesc
->Width-1700 );
    g_HUD.SetSize( 
170170 );
    g_SampleUI.SetLocation( ( pBackBufferSurfaceDesc
->Width-170 ) / 2, pBackBufferSurfaceDesc->Height-120 );
    g_SampleUI.SetSize( 
170120 );

    
return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every frame. This is the
// best location for your application to handle updates to the scene, but is not 
// intended to contain actual rendering calls, which should instead be placed in the 
// OnFrameRender callback.  
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    
// Update the scroll matrix
    float fFrameAngleToScroll = g_fAngleToScroll * fElapsedTime / SCROLL_TIME;
    
if( fabs( fFrameAngleToScroll ) > fabs( g_fAngleLeftToScroll ) )
        fFrameAngleToScroll 
= g_fAngleLeftToScroll;
    g_fAngleLeftToScroll 
-= fFrameAngleToScroll;
    D3DXMATRIXA16 m;
    D3DXMatrixRotationY( 
&m, fFrameAngleToScroll );
    g_mScroll 
*= m;
    
// Update the camera's position based on user input 
    g_Camera.FrameMove( fElapsedTime );
}


//--------------------------------------------------------------------------------------
// This callback function will be called at the end of every frame to perform all the 
// rendering calls for the scene, and it will also be called if the window needs to be 
// repainted. After this function has returned, DXUT will call 
// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    
// If the settings dialog is being shown, then
    
// render it instead of rendering the app's scene
    if( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.OnRender( fElapsedTime );
        
return;
    }

    HRESULT hr;
    D3DXMATRIXA16 mWorld;
    D3DXMATRIXA16 mWorldView;
    D3DXMATRIXA16 mViewProj;
    D3DXMATRIXA16 mWorldViewProjection;

    
// Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(06675121), 1.0f0) );

    
// Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        
// Get the projection & view matrix from the camera class
        mViewProj = *g_Camera.GetViewMatrix() * *g_Camera.GetProjMatrix();

        
// Update the effect's variables.  Instead of using strings, it would 
        
// be more efficient to cache a handle to the parameter by calling 
        
// ID3DXEffect::GetParameterByName
        D3DXVECTOR4 vLightView( 0.0f0.0f-10.0f1.0f );
        V( g_pEffect
->SetVector( "g_vLight"&vLightView ) );

        
float fAngleDelta = D3DX_PI * 2.0f / g_Meshes.GetSize();
        
forint i = 0; i < g_Meshes.GetSize(); ++i )
        {
            D3DXMATRIXA16 mWorld 
= *g_ArcBall[i].GetRotationMatrix() * *g_ArcBall[i].GetTranslationMatrix();
            mWorld 
= g_amWorld[i] * mWorld;
            D3DXMATRIXA16 mRot;
            D3DXMATRIXA16 mTrans;
            D3DXMatrixTranslation( 
&mTrans, 0.0f0.0f-3.0f );
            D3DXMatrixRotationY( 
&mRot, fAngleDelta * ( i - g_nActiveMesh ) );
            mWorld 
*= mTrans * mRot * g_mScroll;
            mWorldView 
= mWorld * *g_Camera.GetViewMatrix();
            mWorldViewProjection 
= mWorld * mViewProj;
            V( g_pEffect
->SetMatrix( "g_mWorld"&mWorld ) );
            V( g_pEffect
->SetMatrix( "g_mView", g_Camera.GetViewMatrix() ) );
            V( g_pEffect
->SetMatrix( "g_mProj", g_Camera.GetProjMatrix() ) );
            g_Meshes[i].Render( pd3dDevice );
        }

        RenderText();
        V( g_HUD.OnRender( fElapsedTime ) );
        V( g_SampleUI.OnRender( fElapsedTime ) );

        V( pd3dDevice
->EndScene() );
    }

    
if( g_fAngleLeftToScroll == 0.0f )
    {
        D3DXMatrixIdentity( 
&g_mScroll );
    }
}


//--------------------------------------------------------------------------------------
// Render the help and statistics text. This function uses the ID3DXFont interface for 
// efficient text rendering.
//--------------------------------------------------------------------------------------
void RenderText()
{
    
// The helper object simply helps keep track of text position, and color
    
// and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
    
// If NULL is passed in as the sprite object, then it will work however the 
    
// pFont->DrawText() will not be batched together.  Batching calls will improves performance.
    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );

    
// Output statistics
    txtHelper.Begin();
    txtHelper.SetInsertionPos( 
55 );
    txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f1.0f0.0f1.0f ) );
    txtHelper.DrawTextLine( DXUTGetFrameStats(
true) ); // Show FPS
    txtHelper.DrawTextLine( DXUTGetDeviceStats() );

    txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f1.0f1.0f1.0f ) );
    txtHelper.DrawFormattedTextLine( L
"Number of meshes: %d\n", g_Meshes.GetSize() );

    
// Draw help
    if( g_bShowHelp )
    {
        
const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
        txtHelper.SetInsertionPos( 
10, pd3dsdBackBuffer->Height-15*6 );
        txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f0.75f0.0f1.0f ) );
        txtHelper.DrawTextLine( L
"Controls (F1 to hide):" );

        txtHelper.SetInsertionPos( 
40, pd3dsdBackBuffer->Height-15*5 );
        txtHelper.DrawTextLine( L
"Rotate Mesh: Left mouse drag\n"
                                L
"Zoom: Mouse wheel\n"
                                L
"Quit: ESC" );
    }
    
else
    {
        txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f1.0f1.0f1.0f ) );
        txtHelper.DrawTextLine( L
"Press F1 for help" );
    }

    
// Draw shared param description
    txtHelper.SetInsertionPos( 550 );
    
if( g_pEffectPool )
    {
        txtHelper.SetForegroundColor( D3DXCOLOR( 
0.0f1.0f0.0f1.0f ) );
        txtHelper.DrawTextLine( L
"Shared parameters are enabled.  When updating transformation\n"
                                L
"matrices on one effect object, all effect objects automatically\n"
                                L
"see the updated values." );
    }
    
else
    {
        txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f0.0f0.0f1.0f ) );
        txtHelper.DrawTextLine( L
"Shared parameters are disabled.  When transformation matrices\n"
                                L
"are updated on the default effect object (diffuse only), only that\n"
                                L
"effect object has the up-to-date values.  All other effect objects\n"
                                L
"do not have valid matrices for rendering." );
    }

    txtHelper.End();
}


//--------------------------------------------------------------------------------------
// Before handling window messages, DXUT passes incoming windows 
// messages to the application through this callback function. If the application sets 
// *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{
    
// Always allow dialog resource manager calls to handle global messages
    
// so GUI state is updated correctly
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
    
if*pbNoFurtherProcessing )
        
return 0;

    
if( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
        
return 0;
    }

    
// Give the dialogs a chance to handle the message first
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    
if*pbNoFurtherProcessing )
        
return 0;
    
*pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    
if*pbNoFurtherProcessing )
        
return 0;

    
// Pass all remaining windows messages to camera so it can respond to user input
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
    D3DXMATRIXA16 mViewRotate 
= *g_Camera.GetViewMatrix();
    mViewRotate._41 
= mViewRotate._42 = mViewRotate._43 = 0.0f;
    D3DXMatrixInverse( 
&mViewRotate, NULL, &mViewRotate );
    
if( g_ArcBall.GetSize() > 0 )
        g_ArcBall[g_nActiveMesh].HandleMessages( hWnd, uMsg, wParam, lParam, 
&mViewRotate );

    
return 0;
}


//--------------------------------------------------------------------------------------
// As a convenience, DXUT inspects the incoming windows messages for
// keystroke messages and decodes the message parameters to pass relevant keyboard
// messages to the application.  The framework does not remove the underlying keystroke 
// messages, which are still passed to the application's MsgProc callback.
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
{
    
if( bKeyDown )
    {
        
switch( nChar )
        {
            
case VK_F1: g_bShowHelp = !g_bShowHelp; break;
        }
    }
}


//--------------------------------------------------------------------------------------
// Handles the GUI events
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
    
switch( nControlID )
    {
        
case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
        
case IDC_TOGGLEREF:        DXUTToggleREF(); break;
        
case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;

        
case IDC_SHARE:
        {
            
// Shared param status changed. Destroy and recreate everything
            
// with or without effect pool as appropriate.
            if( DXUTGetD3DDevice() )
            {
                
// We need to call the callbacks of the resource manager or the ref
                
// count will not reach 0.

                OnLostDevice( NULL );
                DXUTGetGlobalResourceCache().OnLostDevice();
                OnDestroyDevice( NULL );
                DXUTGetGlobalResourceCache().OnDestroyDevice();
                OnCreateDevice( DXUTGetD3DDevice(), DXUTGetBackBufferSurfaceDesc(), NULL );
                DXUTGetGlobalResourceCache().OnCreateDevice( DXUTGetD3DDevice() );
                OnResetDevice( DXUTGetD3DDevice(), DXUTGetBackBufferSurfaceDesc(), NULL );
                DXUTGetGlobalResourceCache().OnResetDevice( DXUTGetD3DDevice() );
            }
            
break;
        }

        
case IDC_SCROLLLEFT:
        
case IDC_SCROLLRIGHT:
        {
            
// Only scroll if we have more than one mesh
            if( g_Meshes.GetSize() <= 1 )
                
break;

            
// Only scroll if we are not already scrolling
            if( g_fAngleLeftToScroll != 0.0f )
                
break;

            
// Compute the angle to scroll
            g_fAngleToScroll = g_fAngleLeftToScroll = nControlID == IDC_SCROLLLEFT ? -D3DX_PI * 2.0f / g_Meshes.GetSize() :
                                                                                     D3DX_PI 
* 2.0f / g_Meshes.GetSize();

            
// Initialize the scroll matrix to be reverse full-angle rotation,
            
// then gradually decrease to zero (identity).
            D3DXMatrixRotationY( &g_mScroll, -g_fAngleToScroll );
            
// Update front mesh index
            if( nControlID == IDC_SCROLLLEFT )
            {
                
++g_nActiveMesh;
                
if( g_nActiveMesh == g_Meshes.GetSize() )
                    g_nActiveMesh 
= 0;
            }
            
else
            {
                
--g_nActiveMesh;
                
if( g_nActiveMesh < 0 )
                    g_nActiveMesh 
= g_Meshes.GetSize() - 1;
            }

            
// Update mesh name and material count
            g_SampleUI.GetStatic( IDC_MESHNAME )->SetText( g_MeshListData[g_nActiveMesh].wszName );
            WCHAR wsz[
256];
            StringCchPrintf( wsz, 
256, L"Number of materials: %u", g_MeshListData[g_nActiveMesh].dwNumMat );
            wsz[
255= L'\0';
            g_SampleUI.GetStatic( IDC_MATCOUNT )
->SetText( wsz );

            
break;
        }
    }
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has 
// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
// in the OnResetDevice callback should be released here, which generally includes all 
// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
// information about lost devices.
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
    g_DialogResourceManager.OnLostDevice();
    g_SettingsDlg.OnLostDevice();
    
if( g_pFont )
        g_pFont
->OnLostDevice();
    
if( g_pEffect )
        g_pEffect
->OnLostDevice();
    SAFE_RELEASE(g_pTextSprite);
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has 
// been destroyed, which generally happens as a result of application termination or 
// windowed/full screen toggles. Resources created in the OnCreateDevice callback 
// should be released here, which generally includes all D3DPOOL_MANAGED resources. 
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
    g_DialogResourceManager.OnDestroyDevice();
    g_SettingsDlg.OnDestroyDevice();
    SAFE_RELEASE( g_pEffect );
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pDefaultTex );
    SAFE_RELEASE( g_pEffectPool );
    SAFE_RELEASE( g_pDecl );
    SAFE_RELEASE( g_pEnvMapTex );

    
forint i = 0; i < g_Meshes.GetSize(); ++i )
        g_Meshes[i].Destroy();

    g_Meshes.RemoveAll();
    g_amWorld.RemoveAll();
}








posted on 2008-04-14 15:20 七星重剑 阅读(2015) 评论(2)  编辑 收藏 引用 所属分类: Game Graphics

FeedBack:
# re: 《精通DirectX 3D》第二十章 效果 04_EffectParam 2009-03-21 15:58 tb01070
同路  回复  更多评论
  
# re: 《精通DirectX 3D》第二十章 效果 04_EffectParam 2012-05-15 12:05 工工
EffectParam.fx
怎样编译?用什么编译器?我在visual stdio 2010 中没有办法编译啊!
helloyz@qq.com
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理