• 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 );
  • 相关阅读:
    Axiom3D:资源引用与加载基本流程.
    实践:C++平台迁移以及如何用C#做C++包装层
    Axiom3D:Buffer漫谈
    CSS: hover选择器的使用
    TTS 语音修复 ,缺少文件的,没注册类的
    sqlserver 查找某个字段在哪张表里
    Excel 表格查找重复数据,去重复统计
    C# HttpWebResponse WebClient 基础连接已经关闭: 发送时发生错误.
    C# 控件置于最顶层、最底层
    C# 线程 正确使用Thread.Join()停止方式
  • 原文地址:https://www.cnblogs.com/zengqh/p/2577851.html
Copyright © 2020-2023  润新知