《精通DirectX 3D》第二十章 效果 03_BasicHLSL

《精通DirectX 3D》第二十章 效果 03_BasicHLSL

这个的难度陡然上升了许多,感觉很迷糊,不清晰了。这次读就是囫囵吞枣,大体看看有些啥东西,以后用到了的时候再细看。


《精通DirectX 3D》第二十章 效果 03_BasicHLSL_第1张图片

BasicHLSL.fx
// ==============================================================
//  Desc: 效果文件
// ==============================================================


// --------------------------------------------------------------
//  全局变量
// --------------------------------------------------------------
float4 g_MaterialAmbientColor;       // 环境光材质
float4 g_MaterialDiffuseColor;       // 漫反射光材质
int    g_nNumLights;                  // 灯光数量

float3 g_LightDir[
3 ];                // 灯光方向(世界空间)
float4 g_LightDiffuse[ 3 ];            // 灯光漫反射颜色
float4 g_LightAmbient;               // 环境光颜色

texture g_MeshTexture;              
// 纹理

float     g_fTime;                    // 程序运行的时间
float4x4 g_mWorld;                   // 世界矩阵
float4x4 g_mWorldViewProjection;     // 组合变换矩阵


// --------------------------------------------------------------
//  纹理采样器
// --------------------------------------------------------------
sampler MeshTextureSampler  =  
sampler_state
{
    Texture 
=   < g_MeshTexture > ;
    MipFilter 
=  LINEAR;
    MinFilter 
=  LINEAR;
    MagFilter 
=  LINEAR;
};


// --------------------------------------------------------------
//  顶点渲染器输出结构
// --------------------------------------------------------------
struct  VS_OUTPUT
{
    float4 Position   : POSITION;   
// 顶点位置
    float4 Diffuse    : COLOR0;      // 顶点漫反射颜色(COLOR0取值在[0,1]之间)
    float2 TextureUV  : TEXCOORD0;   // 顶点纹理坐标
};


// --------------------------------------------------------------
//  顶点渲染器
// --------------------------------------------------------------
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, 
                         float3 vNormal : NORMAL,
                         float2 vTexCoord0 : TEXCOORD0,
                         uniform 
int  nNumLights,        // 灯光数量
                         uniform  bool  bTexture,         // 是否使用纹理映射
                         uniform  bool  bAnimate )        // 是否产生动画
{
    VS_OUTPUT Output;
    float3 vNormalWorldSpace;
  
    float4 vAnimatedPos 
=  vPos;
    
    
// 根据时间改变顶点位置
     if ( bAnimate )
        vAnimatedPos 
+=  float4(vNormal,  0 *  (sin(g_fTime + 5.5 ) + 0.5 ) * 5 ;
    
    
// 将顶点位置坐标从本地空间变换到其次投影空间
    Output.Position  =  mul(vAnimatedPos, g_mWorldViewProjection);

    
// 将顶点法向量从本地空间变换到世界空间,并单位化
    vNormalWorldSpace  =  normalize(mul(vNormal, (float3x3)g_mWorld));
    
    
// 计算顶点光照颜色
    float3 vTotalLightDiffuse  =  float3( 0 , 0 , 0 );
    
for ( int  i = 0 ; i < nNumLights; i ++  )
        vTotalLightDiffuse 
+=  g_LightDiffuse[i]  *  max( 0 ,dot(vNormalWorldSpace, g_LightDir[i]));
        
    Output.Diffuse.rgb 
=  g_MaterialDiffuseColor  *  vTotalLightDiffuse  +  
                         g_MaterialAmbientColor 
*  g_LightAmbient;   
    Output.Diffuse.a 
=   1.0f ;
    
    
// 原样输出顶点纹理坐标
     if ( bTexture ) 
        Output.TextureUV 
=  vTexCoord0; 
    
else
        Output.TextureUV 
=   0
    
    
return  Output;    
}


// --------------------------------------------------------------
//  像素渲染器输出结构
// --------------------------------------------------------------
struct  PS_OUTPUT
{
    float4 RGBColor : COLOR0;  
// 像素颜色
};


// --------------------------------------------------------------
//  像素渲染器
// --------------------------------------------------------------
PS_OUTPUT RenderScenePS( VS_OUTPUT In,
                         uniform 
bool  bTexture ) 

    PS_OUTPUT Output;

    
// 计算每个像素的颜色(纹理颜色*漫反射颜色)
     if ( bTexture )
        Output.RGBColor 
=  tex2D(MeshTextureSampler, In.TextureUV)  *  In.Diffuse;
    
else
        Output.RGBColor 
=  In.Diffuse;

    
return  Output;
}


// --------------------------------------------------------------
//  技术
// --------------------------------------------------------------
technique RenderSceneWithTexture1Light
{
    pass P0
    {          
        VertexShader 
=  compile vs_2_0 RenderSceneVS(  1 true true  ); // hew: DX June 2007的话,要改成这个,否则执行程序会出错
        PixelShader  
=  compile ps_2_0 RenderScenePS(  true  );  //  trivial pixel shader (could use FF instead if desired)
    }
}

technique RenderSceneWithTexture2Light
{
    pass P0
    {          
        VertexShader 
=  compile vs_2_0 RenderSceneVS(  2 true true  );
        PixelShader  
=  compile ps_2_0 RenderScenePS(  true  );  //  trivial pixel shader (could use FF instead if desired)
    }
}

technique RenderSceneWithTexture3Light
{
    pass P0
    {          
        VertexShader 
=  compile vs_2_0 RenderSceneVS(  3 true true  );
        PixelShader  
=  compile ps_2_0 RenderScenePS(  true  );  //  trivial pixel shader (could use FF instead if desired)
    }
}

technique RenderSceneNoTexture
{
    pass P0
    {          
        VertexShader 
=  compile vs_2_0 RenderSceneVS(  1 false false  );
        PixelShader  
=  compile ps_2_0 RenderScenePS(  false  );  //  trivial pixel shader (could use FF instead if desired)
    }
}





// =============================================================================
//  Desc: 主程序源文件
// =============================================================================

#include 
" dxstdafx.h "
#include 
" resource.h "

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


// -----------------------------------------------------------------------------
//  全局变量
// -----------------------------------------------------------------------------
ID3DXFont *               g_pFont  =  NULL;          // ID3DXFont字体对象
ID3DXSprite *             g_pSprite  =  NULL;        // ID3DXSprite文本精灵对象
bool                     g_bShowHelp  =   true ;      // 标识是否显示简单说明文本

CDXUTDialogResourceManager g_DialogResourceManager; 
// 对话框资源管理器
CD3DSettingsDlg            g_SettingsDlg;            // Direct3D设备设置对话框
CDXUTDialog                g_HUD;                    // 3DUI对话框
CDXUTDialog                g_SampleUI;               // 其它控件对话框
CModelViewerCamera         g_Camera;                 // 摄影机对象

ID3DXEffect
*                g_pEffect  =  NULL;         // 效果
ID3DXMesh *                  g_pMesh  =  NULL;           // 网格模型
IDirect3DTexture9 *          g_pMeshTexture  =  NULL;    // 网格模型纹理

bool                        g_bEnablePreshader;       // 标志是否启用预编译渲染器
D3DXMATRIXA16              g_mCenterWorld;           // 调整矩阵, 将网格模型调整到窗口中心显示

#define  MAX_LIGHTS 3  // 灯光数量
CDXUTDirectionWidget       g_LightControl[MAX_LIGHTS];
float                       g_fLightScale;
int                         g_nNumActiveLights;
int                         g_nActiveLight;


// --------------------------------------------------------------------------------------
//  控件ID
// --------------------------------------------------------------------------------------
#define  IDC_TOGGLEFULLSCREEN    1
#define  IDC_TOGGLEREF           3
#define  IDC_CHANGEDEVICE        4
#define  IDC_ENABLE_PRESHADER    5
#define  IDC_NUM_LIGHTS          6
#define  IDC_NUM_LIGHTS_STATIC   7
#define  IDC_ACTIVE_LIGHT        8
#define  IDC_LIGHT_SCALE         9
#define  IDC_LIGHT_SCALE_STATIC  10


// -----------------------------------------------------------------------------
//  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(  double  fTime );


// -----------------------------------------------------------------------------
//  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(  true true  );

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

    
// 初始化DXUT, 创建窗口, 创建Direct3D设备对象
    DXUTInit(  true true true  ); 
    DXUTCreateWindow( L
" BasicHLSL "  );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, 
true 640 480
                      IsDeviceAcceptable, ModifyDeviceSettings );

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

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

    
return  DXUTGetExitCode();
}


// -----------------------------------------------------------------------------
//  Desc: 应用程序相关初始化
// -----------------------------------------------------------------------------
void  InitApp()
{
    
// 初始化全局变量
    g_bEnablePreshader  =   true ;

    
for int  i = 0 ; i < MAX_LIGHTS; i ++  )
        g_LightControl[i].SetLightDirection( D3DXVECTOR3( sinf(D3DX_PI
* 2 * i / MAX_LIGHTS - D3DX_PI / 6 ),  0 - cosf(D3DX_PI * 2 * i / MAX_LIGHTS - D3DX_PI / 6 ) ) );

    g_nActiveLight 
=   0 ;
    g_nNumActiveLights 
=   1 ;
    g_fLightScale 
=   1.0f ;

    
// 初始化对话框
    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,  125 22  );
    g_HUD.AddButton( IDC_TOGGLEREF, L
" Toggle REF (F3) " 35 , iY  +=   24 125 22  );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L
" Change device (F2) " 35 , iY  +=   24 125 22 , VK_F2 );

    
// 为g_SampleUI对话框设置消息处理函数,添加控件
    g_SampleUI.SetCallback( OnGUIEvent ); iY  =   10

    WCHAR sz[
100 ];
    iY 
+=   24 ;
    StringCchPrintf( sz, 
100 , L " # Lights: %d " , g_nNumActiveLights ); 
    g_SampleUI.AddStatic( IDC_NUM_LIGHTS_STATIC, sz, 
35 , iY  +=   24 125 22  );
    g_SampleUI.AddSlider( IDC_NUM_LIGHTS, 
50 , iY  +=   24 100 22 1 , MAX_LIGHTS, g_nNumActiveLights );

    iY 
+=   24 ;
    StringCchPrintf( sz, 
100 , L " Light scale: %0.2f " , g_fLightScale ); 
    g_SampleUI.AddStatic( IDC_LIGHT_SCALE_STATIC, sz, 
35 , iY  +=   24 125 22  );
    g_SampleUI.AddSlider( IDC_LIGHT_SCALE, 
50 , iY  +=   24 100 22 0 20 , ( int ) (g_fLightScale  *   10.0f ) );

    iY 
+=   24 ;
    g_SampleUI.AddButton( IDC_ACTIVE_LIGHT, L
" Change active light (K) " 35 , iY  +=   24 125 22 ' K '  );
    g_SampleUI.AddCheckBox( IDC_ENABLE_PRESHADER, L
" Enable preshaders " 35 , iY  +=   24 125 22 , g_bEnablePreshader );
}


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

    
// 检查设备支持的像素渲染器版本
     if ( pCaps -> PixelShaderVersion  <  D3DPS_VERSION( 1 , 1 ) )
        
return   false ;

    
return   true ;
}


// -----------------------------------------------------------------------------
//  Desc: 修改Direct3D渲染设备设置
// -----------------------------------------------------------------------------
bool  CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *  pDeviceSettings,  const  D3DCAPS9 *  pCaps,  void *  pUserContext )
{
    
// 如果硬件不支持, 则使用软件顶点处理
     if ( (pCaps -> DevCaps  &  D3DDEVCAPS_HWTRANSFORMANDLIGHT)  ==   0   ||
         pCaps
-> VertexShaderVersion  <  D3DVS_VERSION( 1 , 1 ) )
    {
        pDeviceSettings
-> BehaviorFlags  =  D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    
// 调试顶点渲染器需要参考设备或软件顶点处理 
#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;

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

    
// 创建字体
    V_RETURN( D3DXCreateFont( pd3dDevice,  15 0 , FW_BOLD,  1 , FALSE, DEFAULT_CHARSET, 
                              OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH 
|  FF_DONTCARE, 
                              L
" Arial " & g_pFont ) );

    
// 加载网格
    V_RETURN( LoadMesh( pd3dDevice, L " tiny\\tiny.x " & g_pMesh ) );

    
// 计算网格模型外包围球半径和中心点坐标
    D3DXVECTOR3 *  pData; 
    D3DXVECTOR3 vCenter;
    FLOAT fObjectRadius;
    V( g_pMesh
-> LockVertexBuffer(  0 , (LPVOID * & pData ) );
    V( D3DXComputeBoundingSphere( pData, g_pMesh
-> GetNumVertices(), D3DXGetFVFVertexSize( g_pMesh -> GetFVF() ),  & vCenter,  & fObjectRadius ) );
    V( g_pMesh
-> UnlockVertexBuffer() );

    
// 构造网格模型世界矩阵
    D3DXMatrixTranslation(  & g_mCenterWorld,  - vCenter.x,  - vCenter.y,  - vCenter.z );
    D3DXMATRIXA16 m;
    D3DXMatrixRotationY( 
& m, D3DX_PI );
    g_mCenterWorld 
*=  m;
    D3DXMatrixRotationX( 
& m, D3DX_PI  /   2.0f  );
    g_mCenterWorld 
*=  m;

    
//
    V_RETURN( CDXUTDirectionWidget::StaticOnCreateDevice( pd3dDevice ) );
    
for int  i = 0 ; i < MAX_LIGHTS; i ++  )
        g_LightControl[i].SetRadius( fObjectRadius );

    
// 设置渲染器创建标志
    DWORD dwShaderFlags  =  D3DXFX_NOT_CLONEABLE;
    #ifdef DEBUG_VS
        dwShaderFlags 
|=  D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
    
#endif
    #ifdef DEBUG_PS
        dwShaderFlags 
|=  D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
    
#endif

    
if ! g_bEnablePreshader )
        dwShaderFlags 
|=  D3DXSHADER_NO_PRESHADER;

    
// 查找效果文件
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L
" BasicHLSL.fx "  ) );

    
// 从文件创建效果
    V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, NULL,  & g_pEffect, NULL ) );

    
// 查找网格模型纹理文件
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L " tiny\\tiny_skin.dds "  ) );

    
// 创建网格模型纹理
    V_RETURN( D3DXCreateTextureFromFileEx( pd3dDevice, str, D3DX_DEFAULT, D3DX_DEFAULT, 
                                       D3DX_DEFAULT, 
0 , D3DFMT_UNKNOWN, D3DPOOL_MANAGED, 
                                       D3DX_DEFAULT, D3DX_DEFAULT, 
0
                                       NULL, NULL, 
& g_pMeshTexture ) );

    
// 设置效果参数变量
    D3DXCOLOR colorMtrlDiffuse( 1.0f 1.0f 1.0f 1.0f );
    D3DXCOLOR colorMtrlAmbient(
0.35f 0.35f 0.35f 0 );

    V_RETURN( g_pEffect
-> SetValue( " g_MaterialAmbientColor " & colorMtrlAmbient,  sizeof (D3DXCOLOR) ) );
    V_RETURN( g_pEffect
-> SetValue( " g_MaterialDiffuseColor " & colorMtrlDiffuse,  sizeof (D3DXCOLOR) ) );    
    V_RETURN( g_pEffect
-> SetTexture(  " g_MeshTexture " , g_pMeshTexture) );

    
// 设置摄影机观察参数
    D3DXVECTOR3 vecEye( 0.0f 0.0f - 15.0f );
    D3DXVECTOR3 vecAt (
0.0f 0.0f - 0.0f );
    g_Camera.SetViewParams( 
& vecEye,  & vecAt );
    g_Camera.SetRadius( fObjectRadius
* 3.0f , fObjectRadius * 0.5f , fObjectRadius * 10.0f  );

    
return  S_OK;
}

// ------------------------------------------------------------------------------
//  Desc: 辅助函数, 加载网格模型
// -----------------------------------------------------------------------------
HRESULT LoadMesh( IDirect3DDevice9 *  pd3dDevice, WCHAR *  strFileName, ID3DXMesh **  ppMesh )
{
    ID3DXMesh
*  pMesh  =  NULL;
    WCHAR str[MAX_PATH];
    HRESULT hr;

    
// 从文件加载网格模型
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
    V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, 
& pMesh) );

    DWORD 
* rgdwAdjacency  =  NULL;

    
// 确保网格模型顶点包含法线信息,以满足光照计算的需要
     if ! (pMesh -> GetFVF()  &  D3DFVF_NORMAL) )
    {
        ID3DXMesh
*  pTempMesh;
        V( pMesh
-> CloneMeshFVF( pMesh -> GetOptions(), 
                                  pMesh
-> GetFVF()  |  D3DFVF_NORMAL, 
                                  pd3dDevice, 
& pTempMesh ) );
        V( D3DXComputeNormals( pTempMesh, NULL ) );

        SAFE_RELEASE( pMesh );
        pMesh 
=  pTempMesh;
    }

    
// 对网格模型进行优化,以提高程序运行性能   
    rgdwAdjacency  =   new  DWORD[pMesh -> GetNumFaces()  *   3 ];
    
if ( rgdwAdjacency  ==  NULL )
        
return  E_OUTOFMEMORY;
    V( pMesh
-> GenerateAdjacency( 1e-6f ,rgdwAdjacency) );
    V( pMesh
-> OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
    delete []rgdwAdjacency;

    
* ppMesh  =  pMesh;

    
return  S_OK;
}


// -----------------------------------------------------------------------------
//  Desc: 在此创建默认内存类型资源对象
// -----------------------------------------------------------------------------
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() );

    
// 创建ID3DXSprite接口对象
    V_RETURN( D3DXCreateSprite( pd3dDevice,  & g_pSprite ) );

    
// 设置摄影机对象投影参数
     float  fAspectRatio  =  pBackBufferSurfaceDesc -> Width  /  (FLOAT)pBackBufferSurfaceDesc -> Height;
    g_Camera.SetProjParams( D3DX_PI
/ 4 , fAspectRatio,  2.0f 4000.0f  );
    g_Camera.SetWindow( pBackBufferSurfaceDesc
-> Width, pBackBufferSurfaceDesc -> Height );
    g_Camera.SetButtonMasks( MOUSE_LEFT_BUTTON, MOUSE_WHEEL, MOUSE_MIDDLE_BUTTON );

    
// 设置对话框位置和尺寸
    g_HUD.SetLocation( pBackBufferSurfaceDesc -> Width - 170 0  );
    g_HUD.SetSize( 
170 170  );
    g_SampleUI.SetLocation( pBackBufferSurfaceDesc
-> Width - 170 , pBackBufferSurfaceDesc -> Height - 300  );
    g_SampleUI.SetSize( 
170 300  );

    
for int  i = 0 ; i < MAX_LIGHTS; i ++  )
        g_LightControl[i].OnResetDevice( pBackBufferSurfaceDesc  );

    
// 恢复效果对象
     if ( g_pEffect )
        V_RETURN( g_pEffect
-> OnResetDevice() );

    
return  S_OK;
}


// -----------------------------------------------------------------------------
//  Desc: 更新场景
// -----------------------------------------------------------------------------
void  CALLBACK OnFrameMove( IDirect3DDevice9 *  pd3dDevice,  double  fTime,  float  fElapsedTime,  void *  pUserContext )
{
    
// 根据用户位置更新摄影机方向 
    g_Camera.FrameMove( fElapsedTime );
}


// -----------------------------------------------------------------------------
//  Desc: 渲染场景
// -----------------------------------------------------------------------------
void  CALLBACK OnFrameRender( IDirect3DDevice9 *  pd3dDevice,  double  fTime,  float  fElapsedTime,  void *  pUserContext )
{
    
// 如果正在利用Direct3D设备设置对话框进行设置, 则不渲染场景
     if ( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.OnRender( fElapsedTime );
        
return ;
    }

    
//
    HRESULT hr;
    D3DXMATRIXA16 mWorldViewProjection;
    D3DXVECTOR3 vLightDir[MAX_LIGHTS];
    D3DXCOLOR   vLightDiffuse[MAX_LIGHTS];
    D3DXMATRIXA16 mWorld;
    D3DXMATRIXA16 mView;
    D3DXMATRIXA16 mProj;
   
    
// 清除后台颜色缓冲区和深度缓冲区
    V( pd3dDevice -> Clear( 0 , NULL, D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER, D3DXCOLOR( 0.0f , 0.25f , 0.25f , 0.55f ),  1.0f 0 ) );

    
// 渲染场景
     if ( SUCCEEDED( pd3dDevice -> BeginScene() ) )
    {
        
// 通过摄影机对象获得观察矩阵和投影矩镇
        mWorld  =  g_mCenterWorld  *   * g_Camera.GetWorldMatrix();
        mProj 
=   * g_Camera.GetProjMatrix();
        mView 
=   * g_Camera.GetViewMatrix();

        mWorldViewProjection 
=  mWorld  *  mView  *  mProj;

        
// 渲染表示灯光方向的箭头, 并设置灯光方向和漫反射颜色值
         for int  i = 0 ; i < g_nNumActiveLights; i ++  )
        {
            D3DXCOLOR arrowColor 
=  ( i  ==  g_nActiveLight )  ?  D3DXCOLOR( 1 , 1 , 0 , 1 ) : D3DXCOLOR( 1 , 1 , 1 , 1 );
            V( g_LightControl[i].OnRender( arrowColor, 
& mView,  & mProj, g_Camera.GetEyePt() ) );
            vLightDir[i] 
=  g_LightControl[i].GetLightDirection();
            vLightDiffuse[i] 
=  g_fLightScale  *  D3DXCOLOR( 1 , 1 , 1 , 1 );
        }

        
// 更新效果参数变量
        V( g_pEffect -> SetValue(  " g_LightDir " , vLightDir,  sizeof (D3DXVECTOR3) * MAX_LIGHTS ) );
        V( g_pEffect
-> SetValue(  " g_LightDiffuse " , vLightDiffuse,  sizeof (D3DXVECTOR4) * MAX_LIGHTS ) );

        V( g_pEffect
-> SetMatrix(  " g_mWorldViewProjection " & mWorldViewProjection ) );
        V( g_pEffect
-> SetMatrix(  " g_mWorld " & mWorld ) );
        V( g_pEffect
-> SetFloat(  " g_fTime " , ( float )fTime ) );

        D3DXCOLOR vWhite 
=  D3DXCOLOR( 1 , 1 , 1 , 1 );
        V( g_pEffect
-> SetValue( " g_MaterialDiffuseColor " & vWhite,  sizeof (D3DXCOLOR) ) );
        V( g_pEffect
-> SetFloat(  " g_fTime " , ( float )fTime ) );      
        V( g_pEffect
-> SetInt(  " g_nNumLights " , g_nNumActiveLights ) );      

        
// 根据灯光数量, 激活适当的技术
         switch ( g_nNumActiveLights )
        {
            
case   1 : V( g_pEffect -> SetTechnique(  " RenderSceneWithTexture1Light "  ) );  break ;
            
case   2 : V( g_pEffect -> SetTechnique(  " RenderSceneWithTexture2Light "  ) );  break ;
            
case   3 : V( g_pEffect -> SetTechnique(  " RenderSceneWithTexture3Light "  ) );  break ;
        }

        
// 使用效果中的技术渲染场景
        UINT iPass, cPasses; 
        V( g_pEffect
-> Begin( & cPasses,  0 ) );
        
for  (iPass  =   0 ; iPass  <  cPasses; iPass ++ )
        {
            V( g_pEffect
-> BeginPass(iPass) );

            
// 使用技术渲染网格模型
            V( g_pMesh -> DrawSubset( 0 ) );

            V( g_pEffect
-> EndPass() );
        }
        V( g_pEffect
-> End() );

        
// 渲染对话框
        g_HUD.OnRender( fElapsedTime ); 
        g_SampleUI.OnRender( fElapsedTime );

        
// 渲染文本
        RenderText( fTime );
        
        V( pd3dDevice
-> EndScene() );
    }
}


// -----------------------------------------------------------------------------
//  Desc: 渲染文本
// -----------------------------------------------------------------------------
void  RenderText(  double  fTime )
{
    CDXUTTextHelper txtHelper( g_pFont, g_pSprite, 
15  );

    
// 显示当前Direct3D设备状态和渲染帧速率
    txtHelper.Begin();
    txtHelper.SetInsertionPos( 
2 0  );
    txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f 1.0f 0.0f 1.0f  ) );
    txtHelper.DrawTextLine( DXUTGetFrameStats(
true ) );
    txtHelper.DrawTextLine( DXUTGetDeviceStats() );
    
    
// 显示其他简要信息
    txtHelper.SetForegroundColor( D3DXCOLOR(  1.0f 1.0f 1.0f 1.0f  ) );
    txtHelper.DrawFormattedTextLine( L
" fTime: %0.1f  sin(fTime): %0.4f " , fTime, sin(fTime) );
    txtHelper.DrawFormattedTextLine( L
" 多技术效果示例程序 "  );
    
    
// 显示简单帮助文本
     if ( g_bShowHelp )
    {
        
const  D3DSURFACE_DESC *  pd3dsdBackBuffer  =  DXUTGetBackBufferSurfaceDesc();
        txtHelper.SetInsertionPos( 
2 , pd3dsdBackBuffer -> Height - 15 * 6  );
        txtHelper.SetForegroundColor( D3DXCOLOR(
1.0f 0.75f 0.0f 1.0f  ) );
        txtHelper.DrawTextLine( L
" Controls: "  );

        txtHelper.SetInsertionPos( 
20 , pd3dsdBackBuffer -> Height - 15 * 5  );
        txtHelper.DrawTextLine( L
" Rotate model: Left mouse button\n "
                                L
" Rotate light: Right mouse button\n "
                                L
" Rotate camera: Middle mouse button\n "
                                L
" Zoom camera: Mouse wheel scroll\n "  );

        txtHelper.SetInsertionPos( 
250 , pd3dsdBackBuffer -> Height - 15 * 5  );
        txtHelper.DrawTextLine( L
" Hide help: F1\n "  
                                L
" Quit: ESC\n "  );
    }
    
else
    {
        txtHelper.SetForegroundColor( D3DXCOLOR( 
1.0f 1.0f 1.0f 1.0f  ) );
        txtHelper.DrawTextLine( L
" Press F1 for help "  );
    }
    txtHelper.End();
}


// -----------------------------------------------------------------------------
//  Desc: 消息处理
// -----------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,  bool *  pbNoFurtherProcessing,  void *  pUserContext )
{
    
* 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 ;
    }

    
* pbNoFurtherProcessing  =  g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    
if * pbNoFurtherProcessing )
        
return   0 ;
    
* pbNoFurtherProcessing  =  g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    
if * pbNoFurtherProcessing )
        
return   0 ;

    g_LightControl[g_nActiveLight].HandleMessages( hWnd, uMsg, wParam, lParam );

    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );

    
return   0 ;
}


// -----------------------------------------------------------------------------
//  Desc: 键盘消息处理
// -----------------------------------------------------------------------------
void  CALLBACK KeyboardProc( UINT nChar,  bool  bKeyDown,  bool  bAltDown,  void *  pUserContext )
{
    
if ( bKeyDown )
    {
        
switch ( nChar )
        {
            
case  VK_F1: g_bShowHelp  =   ! g_bShowHelp;  break ;
        }
    }
}


// -----------------------------------------------------------------------------
//  Desc: 各种控件消息处理
// -----------------------------------------------------------------------------
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_ENABLE_PRESHADER: 
        {
            g_bEnablePreshader 
=  g_SampleUI.GetCheckBox( IDC_ENABLE_PRESHADER ) -> GetChecked(); 

            
if ( DXUTGetD3DDevice()  !=  NULL )
            {
                OnLostDevice( NULL );
                OnDestroyDevice( NULL );
                OnCreateDevice( DXUTGetD3DDevice(), DXUTGetBackBufferSurfaceDesc(), NULL );
                OnResetDevice( DXUTGetD3DDevice(), DXUTGetBackBufferSurfaceDesc(), NULL );
            }
            
break ;
        }

        
case  IDC_ACTIVE_LIGHT:
            
if ! g_LightControl[g_nActiveLight].IsBeingDragged() )
            {
                g_nActiveLight
++ ;
                g_nActiveLight 
%=  g_nNumActiveLights;
            }
            
break ;

        
case  IDC_NUM_LIGHTS:
            
if ! g_LightControl[g_nActiveLight].IsBeingDragged() )
            {
                WCHAR sz[
100 ];
                StringCchPrintf( sz, 
100 , L " # Lights: %d " , g_SampleUI.GetSlider( IDC_NUM_LIGHTS ) -> GetValue() ); 
                g_SampleUI.GetStatic( IDC_NUM_LIGHTS_STATIC )
-> SetText( sz );

                g_nNumActiveLights 
=  g_SampleUI.GetSlider( IDC_NUM_LIGHTS ) -> GetValue();
                g_nActiveLight 
%=  g_nNumActiveLights;
            }
            
break ;

        
case  IDC_LIGHT_SCALE: 
            g_fLightScale 
=  ( float ) (g_SampleUI.GetSlider( IDC_LIGHT_SCALE ) -> GetValue()  *   0.10f );

            WCHAR sz[
100 ];
            StringCchPrintf( sz, 
100 , L " Light scale: %0.2f " , g_fLightScale ); 
            g_SampleUI.GetStatic( IDC_LIGHT_SCALE_STATIC )
-> SetText( sz );
            
break ;
    }
    
}


// -----------------------------------------------------------------------------
//  Desc: 释放在OnResetDevice()中创建的资源
// -----------------------------------------------------------------------------
void  CALLBACK OnLostDevice(  void *  pUserContext )
{
    g_DialogResourceManager.OnLostDevice();
    g_SettingsDlg.OnLostDevice();
    CDXUTDirectionWidget::StaticOnLostDevice();
    
if ( g_pFont )
        g_pFont
-> OnLostDevice();
    
if ( g_pEffect )
        g_pEffect
-> OnLostDevice();
    SAFE_RELEASE(g_pSprite);
    
}


// ------------------------------------------------------------------------------
//  Desc: 释放在OnCreateDevice()中创建的资源
// ------------------------------------------------------------------------------
void  CALLBACK OnDestroyDevice(  void *  pUserContext )
{
    g_DialogResourceManager.OnDestroyDevice();
    g_SettingsDlg.OnDestroyDevice();
    CDXUTDirectionWidget::StaticOnDestroyDevice();
    SAFE_RELEASE(g_pEffect);
    SAFE_RELEASE(g_pFont);
    SAFE_RELEASE(g_pMesh);
    SAFE_RELEASE(g_pMeshTexture);
}









你可能感兴趣的:(《精通DirectX 3D》第二十章 效果 03_BasicHLSL)