bump map之normal map

关于这方面的文档网上有很多:

http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html

其中的Tangent Space(切线空间)最不好理解,参考:

http://www.terathon.com/code/tangent.html

http://blog.csdn.net/soilwork/article/details/1452437

我自己得用DX的D3DXComputeTangentFrameEx函数做的效果:

HLSL:

//--------------------------------------------------------------------------------------

// File: SimpleSample.fx

//

// The effect file for the SimpleSample sample.  

// 

// Copyright (c) Microsoft Corporation. All rights reserved.

//--------------------------------------------------------------------------------------





//--------------------------------------------------------------------------------------

// Global variables

//--------------------------------------------------------------------------------------

float4 g_MaterialAmbientColor;      // Material's ambient color

float4 g_MaterialDiffuseColor;      // Material's diffuse color

float4 g_LightAmbient;              // Light's diffuse color

float3 g_LightDir;                  // Light's direction in world space

float4 g_LightDiffuse;              // Light's diffuse color

texture g_MeshTexture;              // Color texture for mesh

texture g_NormalTexture;              // Color texture for mesh



float    g_fTime;                   // App's time in seconds

float4x4 g_mWorld;                  // World matrix for object

float4x4 g_mWorldViewProjection;    // World * View * Projection matrix







//--------------------------------------------------------------------------------------

// Texture samplers

//--------------------------------------------------------------------------------------

sampler MeshTextureSampler = 

sampler_state

{

    Texture = <g_MeshTexture>;

    MipFilter = LINEAR;

    MinFilter = LINEAR;

    MagFilter = LINEAR;

};



sampler samplerNormalTexture = 

sampler_state

{

    Texture = <g_NormalTexture>;

    MipFilter = LINEAR;

    MinFilter = LINEAR;

    MagFilter = LINEAR;

};





void RenderBumpMapVS( float4 inPositionOS : POSITION,  

                      float2 inTexCoord   : TEXCOORD0,  

                      float3 inNormalOS   : NORMAL,  

                      float3 inTangentOS  : TANGENT,  

                      float3 inBinormalOS : BINORMAL,  

                      out float4 outPosition : POSITION,  

                      out float2 outTexCoord : TEXCOORD0,  

                      out float3 outLightTS  : TEXCOORD1 )  

{  

    // 将顶点变换到相机透视空间  

    outPosition = mul( inPositionOS, g_mWorldViewProjection );  

      

    // 复制贴图坐标  

    outTexCoord = inTexCoord;  

      

    // 将模型空间中的法线变换到世界坐标,注意,仅仅是旋转变换  

    float3 vNormalWS = mul(inNormalOS, (float3x3) g_mWorld);  

    float3 vTangentWS = mul(inTangentOS, (float3x3) g_mWorld);  

    float3 vBinormalWS = mul(inBinormalOS, (float3x3) g_mWorld);  

      

    vNormalWS = normalize(vNormalWS);  

    vTangentWS = normalize(vTangentWS);  

    vBinormalWS = normalize(vBinormalWS);  

      

    // 将光源方向转换成贴图表面的Tangent坐标,注意,右手坐标系转换  

    // 注意:在vs中进行normalize是没有意义的,因为ps中的值是插值结果  

    float3x3 mWorldToTangent = float3x3(vTangentWS, vBinormalWS, vNormalWS);  

    outLightTS = mul(g_LightDir, mWorldToTangent);  

}  



void RenderBumpMapPS( float2 texCoord : TEXCOORD0,  

                      float3 lightTS  : TEXCOORD1,  

                      out float4 color : COLOR )  

{  

    // 需要对插值结果重新normalize  

    float3 vLightTS = normalize(lightTS);  

      

    // 获得法线贴图的法线,转换到[-1, 1]空间之中  

    float3 vNormalTS = normalize(tex2D(samplerNormalTexture, texCoord) * 2.0f - 1.0f);  

      

    // 获取原始贴图的颜色,这里要求原始贴图和发现贴图使用公用的uv  

    float4 cBaseColor = tex2D(MeshTextureSampler, texCoord);  

      

    // 输出颜色  

    color = cBaseColor * ((dot(vNormalTS, vLightTS)) * g_MaterialDiffuseColor) + g_MaterialAmbientColor;  

}  

//--------------------------------------------------------------------------------------

// Renders scene 

//--------------------------------------------------------------------------------------

technique RenderScene

{

    pass P0

    {          

        VertexShader = compile vs_2_0 RenderBumpMapVS();

        PixelShader  = compile ps_2_0 RenderBumpMapPS(); 

    }

}
//--------------------------------------------------------------------------------------

// File: SimpleSample.cpp

//

// Copyright (c) Microsoft Corporation. All rights reserved.

//--------------------------------------------------------------------------------------

#include "DXUT.h"

#include "DXUTgui.h"

#include "DXUTmisc.h"

#include "DXUTCamera.h"

#include "DXUTSettingsDlg.h"

#include "SDKmisc.h"

#include "SDKmesh.h"

#include "resource.h"



//#define DEBUG_VS   // Uncomment this line to debug D3D9 vertex shaders 

//#define DEBUG_PS   // Uncomment this line to debug D3D9 pixel shaders 





//--------------------------------------------------------------------------------------

// Global variables

//--------------------------------------------------------------------------------------

CModelViewerCamera          g_Camera;               // A model viewing camera

CDXUTDialogResourceManager  g_DialogResourceManager; // manager for shared resources of dialogs

CD3DSettingsDlg             g_SettingsDlg;          // Device settings dialog

CDXUTTextHelper*            g_pTxtHelper = NULL;

CDXUTDialog                 g_HUD;                  // dialog for standard controls

CDXUTDialog                 g_SampleUI;             // dialog for sample specific controls



// Direct3D 9 resources

ID3DXFont*                  g_pFont9 = NULL;

ID3DXSprite*                g_pSprite9 = NULL;

ID3DXEffect*                g_pEffect9 = NULL;

IDirect3DVertexDeclaration9*    g_pVertDecl = NULL;        // Vertex decl for the sample

CDXUTXFileMesh                  g_Room;                    // Mesh representing room (wall, floor, ceiling)

CDXUTXFileMesh                  g_Chair;                    // Mesh representing room (wall, floor, ceiling)

LPDIRECT3DTEXTURE9                g_normalTexture = NULL;



//--------------------------------------------------------------------------------------

// UI control IDs

//--------------------------------------------------------------------------------------

#define IDC_TOGGLEFULLSCREEN    1

#define IDC_TOGGLEREF           2

#define IDC_CHANGEDEVICE        3



D3DVERTEXELEMENT9 g_aVertDecl[] =

{

    { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },

    { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },

    { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

    { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },  

    { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },  

    D3DDECL_END()

};

//--------------------------------------------------------------------------------------

// Forward declarations 

//--------------------------------------------------------------------------------------

LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,

                          void* pUserContext );

void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );

void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );

void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );

bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );



bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,

                                      bool bWindowed, void* pUserContext );

HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,

                                     void* pUserContext );

HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,

                                    void* pUserContext );

void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );

void CALLBACK OnD3D9LostDevice( void* pUserContext );

void CALLBACK OnD3D9DestroyDevice( void* pUserContext );



void InitApp();

void RenderText();

HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, LPCWSTR wszName, CDXUTXFileMesh& Mesh );



//--------------------------------------------------------------------------------------

// Entry point to the program. Initializes everything and goes into a message processing 

// loop. Idle time is used to render the scene.

//--------------------------------------------------------------------------------------

int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )

{

    // Enable run-time memory check for debug builds.

#if defined(DEBUG) | defined(_DEBUG)

    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

#endif



    // DXUT will create and use the best device (either D3D9 or D3D10) 

    // that is available on the system depending on which D3D callbacks are set below



    // Set DXUT callbacks

    DXUTSetCallbackMsgProc( MsgProc );

    DXUTSetCallbackKeyboard( OnKeyboard );

    DXUTSetCallbackFrameMove( OnFrameMove );

    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );



    DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );

    DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );

    DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );

    DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );

    DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );

    DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );



    InitApp();

    DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params

    DXUTSetCursorSettings( true, true );

    DXUTCreateWindow( L"SimpleSample" );

    DXUTCreateDevice( true, 640, 480 );

    DXUTMainLoop(); // Enter into the DXUT render loop



    return DXUTGetExitCode();

}





//--------------------------------------------------------------------------------------

// Initialize the app 

//--------------------------------------------------------------------------------------

void InitApp()

{

    g_SettingsDlg.Init( &g_DialogResourceManager );

    g_HUD.Init( &g_DialogResourceManager );

    g_SampleUI.Init( &g_DialogResourceManager );



    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, VK_F3 );

    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );



    g_SampleUI.SetCallback( OnGUIEvent ); iY = 10;

}





//--------------------------------------------------------------------------------------

// Render the help and statistics text. This function uses the ID3DXFont interface for 

// efficient text rendering.

//--------------------------------------------------------------------------------------

void RenderText()

{

    g_pTxtHelper->Begin();

    g_pTxtHelper->SetInsertionPos( 5, 5 );

    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );

    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );

    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );

    g_pTxtHelper->End();

}





//--------------------------------------------------------------------------------------

// Rejects any D3D9 devices that aren't acceptable to the app by returning false

//--------------------------------------------------------------------------------------

bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,

                                      D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )

{

    // Skip backbuffer formats that don't support alpha blending

    IDirect3D9* pD3D = DXUTGetD3D9Object();

    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,

                                         AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,

                                         D3DRTYPE_TEXTURE, BackBufferFormat ) ) )

        return false;



    // No fallback defined by this app, so reject any device that 

    // doesn't support at least ps2.0

    if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )

        return false;



    return true;

}





//--------------------------------------------------------------------------------------

// Called right before creating a D3D9 or D3D10 device, allowing the app to modify the device settings as needed

//--------------------------------------------------------------------------------------

bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )

{

    if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )

    {

        IDirect3D9* pD3D = DXUTGetD3D9Object();

        D3DCAPS9 Caps;

        pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &Caps );



        // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 

        // then switch to SWVP.

        if( ( Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 ||

            Caps.VertexShaderVersion < D3DVS_VERSION( 1, 1 ) )

        {

            pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        }



        // Debugging vertex shaders requires either REF or software vertex processing 

        // and debugging pixel shaders requires REF.  

#ifdef DEBUG_VS

        if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF )

        {

            pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;

            pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE;

            pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

        }

#endif

#ifdef DEBUG_PS

        pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF;

#endif

    }



    // For the first device created if its a REF device, optionally display a warning dialog box

    static bool s_bFirstTime = true;

    if( s_bFirstTime )

    {

        s_bFirstTime = false;

        if( ( DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF ) ||

            ( DXUT_D3D10_DEVICE == pDeviceSettings->ver &&

              pDeviceSettings->d3d10.DriverType == D3D10_DRIVER_TYPE_REFERENCE ) )

            DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver );

    }



    return true;

}





//--------------------------------------------------------------------------------------

// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)

// and aren't tied to the back buffer size

//--------------------------------------------------------------------------------------

HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,

                                     void* pUserContext )

{

    HRESULT hr;



    V_RETURN( g_DialogResourceManager.OnD3D9CreateDevice( pd3dDevice ) );

    V_RETURN( g_SettingsDlg.OnD3D9CreateDevice( 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_pFont9 ) );



    // Read the D3DX effect file

    WCHAR str[MAX_PATH];

    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

#ifdef D3DXFX_LARGEADDRESS_HANDLE

    dwShaderFlags |= D3DXFX_LARGEADDRESSAWARE;

#endif



    LPD3DXBUFFER error;



    D3DXCreateBuffer(256, &error);



    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"SimpleSample.fx" ) );

    ( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags,

                                        NULL, &g_pEffect9, &error ) );



    if(error)

    {

        OutputDebugStringA((const char*)error->GetBufferPointer());

    }

    



    /* set mtrl ambient and diffuse, to test ambient, diffuse is disable */

    D3DXCOLOR colorMtrlDiffuse(0.5f, 0.5f, 0.5f, 1.0f);

    D3DXCOLOR colorMtrlAmbient(0.4f, 0.4f, 0.4f, 1.0f);



    D3DXCOLOR colorLightAmbient(1.0f, 1.0f, 1.0f, 1.0f);

    D3DXCOLOR colorLightDiffuse(1.0f, 1.0f, 1.0f, 1.0f);



    D3DXVECTOR3 lightDir(0.0f, 1.0f, 0.2f);





    V_RETURN( g_pEffect9->SetValue( "g_MaterialAmbientColor", &colorMtrlAmbient, sizeof( D3DXCOLOR ) ) );

    V_RETURN( g_pEffect9->SetValue( "g_MaterialDiffuseColor", &colorMtrlDiffuse, sizeof( D3DXCOLOR ) ) );



    V_RETURN( g_pEffect9->SetValue( "g_LightAmbient", &colorLightAmbient, sizeof( D3DXCOLOR ) ) );

    V_RETURN( g_pEffect9->SetValue( "g_LightDiffuse", &colorLightDiffuse, sizeof( D3DXCOLOR ) ) );



    V_RETURN( g_pEffect9->SetValue( "g_LightDir", &lightDir, sizeof( D3DXVECTOR3 ) ) );



    V_RETURN( D3DXCreateTextureFromFile(pd3dDevice, L"normal_map.jpg", &g_normalTexture));



    V_RETURN( g_pEffect9->SetTexture( "g_NormalTexture", g_normalTexture ) );



    V_RETURN( pd3dDevice->CreateVertexDeclaration( g_aVertDecl, &g_pVertDecl ) );



    /* load room mesh */

    if( FAILED( LoadMesh( pd3dDevice, L"ChairScene\\room.x", g_Room ) ) )

        return DXUTERR_MEDIANOTFOUND;



    if( FAILED( LoadMesh( pd3dDevice, L"ChairScene\\chair.x", g_Chair ) ) )

        return DXUTERR_MEDIANOTFOUND;



    // Setup the camera's view parameters

    D3DXVECTOR3 vecEye( 0.0f, 8.0f, -20.0f );

    D3DXVECTOR3 vecAt ( 0.0f, 0.0f, -0.0f );

    g_Camera.SetViewParams( &vecEye, &vecAt );



    return S_OK;

}





//--------------------------------------------------------------------------------------

// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT) 

// or that are tied to the back buffer size 

//--------------------------------------------------------------------------------------

HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice,

                                    const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )

{

    HRESULT hr;



    V_RETURN( g_DialogResourceManager.OnD3D9ResetDevice() );

    V_RETURN( g_SettingsDlg.OnD3D9ResetDevice() );



    if( g_pFont9 ) V_RETURN( g_pFont9->OnResetDevice() );

    if( g_pEffect9 ) V_RETURN( g_pEffect9->OnResetDevice() );

    

     g_Room.RestoreDeviceObjects( pd3dDevice );    

     g_Chair.RestoreDeviceObjects(pd3dDevice);



    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pSprite9 ) );

    g_pTxtHelper = new CDXUTTextHelper( g_pFont9, g_pSprite9, NULL, NULL, 15 );



    // Setup the camera's projection parameters

    float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;

    g_Camera.SetProjParams( D3DX_PI / 4, fAspectRatio, 0.1f, 1000.0f );

    g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );



    g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );

    g_HUD.SetSize( 170, 170 );

    g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350 );

    g_SampleUI.SetSize( 170, 300 );



    return S_OK;

}





//--------------------------------------------------------------------------------------

// Handle updates to the scene.  This is called regardless of which D3D API is used

//--------------------------------------------------------------------------------------

void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )

{

    // Update the camera's position based on user input 

    g_Camera.FrameMove( fElapsedTime );

}





//--------------------------------------------------------------------------------------

// Render the scene using the D3D9 device

//--------------------------------------------------------------------------------------

void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )

{

    HRESULT hr;

    D3DXMATRIXA16 mWorld;

    D3DXMATRIXA16 mView;

    D3DXMATRIXA16 mProj;

    D3DXMATRIXA16 mWorldViewProjection;



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

    }



    // Clear the render target and the zbuffer 

    V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );



    // Render the scene

    if( SUCCEEDED( pd3dDevice->BeginScene() ) )

    {

        // Get the projection & view matrix from the camera class

        mWorld = *g_Camera.GetWorldMatrix();

        mProj = *g_Camera.GetProjMatrix();

        mView = *g_Camera.GetViewMatrix();



        mWorldViewProjection = mWorld * mView * mProj;

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

        V( g_pEffect9->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );

        V( g_pEffect9->SetMatrix( "g_mWorld", &mWorld ) );

        V( g_pEffect9->SetFloat( "g_fTime", ( float )fTime ) );



        /* render room */

        UINT p, cPass;

        V( g_pEffect9->SetTechnique( "RenderScene" ) );

        V( g_pEffect9->Begin( &cPass, 0 ) );

        for(p = 0; p < cPass; ++p)

        {

            LPD3DXMESH pMeshObj;



            V( g_pEffect9->BeginPass(p));



            pMeshObj = g_Room.GetMesh();

            for(DWORD m = 0; m < g_Room.m_dwNumMaterials; ++m)

            {

                V( g_pEffect9->SetTexture( "g_MeshTexture", g_Room.m_pTextures[m] ) );

                V( g_pEffect9->CommitChanges() );

                V( pMeshObj->DrawSubset( m ) );

            }

        }



        V( g_pEffect9->End() );



        V( g_pEffect9->SetTechnique( "RenderScene" ) );

        V( g_pEffect9->Begin( &cPass, 0 ) );

        for(p = 0; p < cPass; ++p)

        {

            LPD3DXMESH pMeshObj;



            V( g_pEffect9->BeginPass(p));



            pMeshObj = g_Chair.GetMesh();

            for(DWORD m = 0; m < g_Chair.m_dwNumMaterials; ++m)

            {

                V( g_pEffect9->SetTexture( "g_MeshTexture", g_Room.m_pTextures[m] ) );

                V( g_pEffect9->CommitChanges() );

                V( pMeshObj->DrawSubset( m ) );

            }

        }



        V( g_pEffect9->End() );



        DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing

        RenderText();

        V( g_HUD.OnRender( fElapsedTime ) );

        V( g_SampleUI.OnRender( fElapsedTime ) );

        DXUT_EndPerfEvent();



        V( pd3dDevice->EndScene() );

    }

}





//--------------------------------------------------------------------------------------

// Handle messages to the application

//--------------------------------------------------------------------------------------

LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,

                          void* pUserContext )

{

    // Pass messages to dialog resource manager calls so GUI state is updated correctly

    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );

    if( *pbNoFurtherProcessing )

        return 0;



    // Pass messages to settings dialog if its active

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



    return 0;

}





//--------------------------------------------------------------------------------------

// Handle key presses

//--------------------------------------------------------------------------------------

void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )

{

}





//--------------------------------------------------------------------------------------

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

    }

}





//--------------------------------------------------------------------------------------

// Release D3D9 resources created in the OnD3D9ResetDevice callback 

//--------------------------------------------------------------------------------------

void CALLBACK OnD3D9LostDevice( void* pUserContext )

{

    g_DialogResourceManager.OnD3D9LostDevice();

    g_SettingsDlg.OnD3D9LostDevice();

    if( g_pFont9 ) g_pFont9->OnLostDevice();

    if( g_pEffect9 ) g_pEffect9->OnLostDevice();



    SAFE_RELEASE( g_pSprite9 );

    SAFE_DELETE( g_pTxtHelper );

    SAFE_RELEASE( g_pVertDecl );

}





//--------------------------------------------------------------------------------------

// Release D3D9 resources created in the OnD3D9CreateDevice callback 

//--------------------------------------------------------------------------------------

void CALLBACK OnD3D9DestroyDevice( void* pUserContext )

{

    g_DialogResourceManager.OnD3D9DestroyDevice();

    g_SettingsDlg.OnD3D9DestroyDevice();

    SAFE_RELEASE( g_pEffect9 );

    SAFE_RELEASE( g_pFont9 );

    SAFE_RELEASE( g_pVertDecl );



    g_Room.Destroy();

    g_Chair.Destroy();

}





HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, LPCWSTR wszName, CDXUTXFileMesh& Mesh )

{

    HRESULT hr;



    if( FAILED( hr = Mesh.Create( pd3dDevice, wszName ) ) )

        return hr;

    hr = Mesh.SetVertexDecl( pd3dDevice, g_aVertDecl );



    return hr;

}

其中修改了一下SDKMesh.cpp, line 2373

 hr = D3DXComputeTangentFrameEx( m_pMesh,

                                            D3DDECLUSAGE_TEXCOORD, 0,

                                            D3DDECLUSAGE_TANGENT, 0,

                                            D3DDECLUSAGE_BINORMAL, 0,

                                            D3DDECLUSAGE_NORMAL, 0,

                                            0, rgdwAdjacency,

                                            fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold,

                                            &pNewMesh, NULL );

 

你可能感兴趣的:(orm)