• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            網(wǎng)格模型高級(jí)技術(shù)(16)

            索引頂點(diǎn)混合

            Direct3D通過(guò)索引頂點(diǎn)混合,擴(kuò)展了使用多個(gè)混合矩陣對(duì)頂點(diǎn)進(jìn)行混合的支持。在索引頂點(diǎn)混合中,混合矩陣被保存在矩陣調(diào)色板(可以看成一個(gè)矩陣數(shù)組)中,使用矩陣索引來(lái)引用特定的混合矩陣。矩陣索引使用8位無(wú)符號(hào)整數(shù)表示,由每個(gè)頂點(diǎn)提供,因?yàn)镈irect3D中限定每個(gè)頂點(diǎn)最多受到4個(gè)混合矩陣的影響,所以每個(gè)頂點(diǎn)最多具有4個(gè)矩陣索引,每個(gè)頂點(diǎn)的矩陣索引被組合成一個(gè)DWORD類(lèi)型的整數(shù)存儲(chǔ)和表示。因?yàn)槊總€(gè)頂點(diǎn)最多受4個(gè)混合矩陣的影響,所以在渲染一個(gè)三角形時(shí)最多可能需要使用12個(gè)混合矩陣,在這種情況下,矩陣調(diào)色板中最少需要包含12個(gè)混合矩陣。

            下圖演示了一個(gè)頂點(diǎn)使用矩陣索引引用4個(gè)混合矩陣,圖中的頂點(diǎn)通過(guò)矩陣索引引用矩陣調(diào)色板中索引為0、2、5、6的混合矩陣:

            下圖演示了渲染一個(gè)三角形時(shí),如何通過(guò)矩陣索引引用矩陣調(diào)色板中的12個(gè)混合矩陣:

            在渲染圖形時(shí),要想啟用索引頂點(diǎn)混合,需要將渲染狀態(tài)D3DRS_INDEXEDVERTEXBLENDENABLE設(shè)置為T(mén)RUE,如果啟用了索引頂點(diǎn)混合,則在頂點(diǎn)數(shù)據(jù)中就需要包含矩陣索引數(shù)據(jù)。如果 將渲染狀態(tài)D3DRS_INDEXEDVERTEXBLENDENABLE設(shè)置為FALSE則禁用索引頂點(diǎn)混合,但是又啟用了圖形混合功能,這時(shí)在頂點(diǎn)數(shù)據(jù)中就不需要包含矩陣索引數(shù)據(jù),每個(gè)頂點(diǎn)的矩陣索引默認(rèn)為0~3。

            D3DRS_INDEXEDVERTEXBLENDENABLE
            bool value that enables or disables indexed vertex blending. The default value is FALSE. When set to TRUE, indexed vertex blending is enabled. When set to FALSE, indexed vertex blending is disabled. If this render state is enabled, the user must pass matrix indices as a packed DWORDwith every vertex. When the render state is disabled and vertex blending is enabled through the D3DRS_VERTEXBLEND state, it is equivalent to having matrix indices 0, 1, 2, 3 in every vertex.

            D3DCAPS結(jié)構(gòu)體的成員變量MaxVertexBlendMatrixIndex表示當(dāng)前設(shè)備對(duì)索引頂點(diǎn)混合的支持,如果MaxVertexBlendMatrixIndex的值為0,表示當(dāng)前硬件設(shè)備不支持索引頂點(diǎn)混合。如果MaxVertexBlendMatrixIndex的值不為0,表示混合矩陣的最大索引為MaxVertexBlendMatrixIndex,也就是當(dāng)前硬件設(shè)備支持的矩陣調(diào)色 板最大容量為MaxVertexBlendMatrixIndex+1,表示矩陣調(diào)色板最大可以容納MaxVertexBlendMatrixIndex+1個(gè)混合矩陣。如果頂點(diǎn)中包含法線信息, 則也需要對(duì)法線數(shù)據(jù)進(jìn)行混合,這時(shí)矩陣調(diào)色板中矩陣的最大數(shù)量為(MaxVertexBlendMatrixIndex+1)/ 2。如果使用軟件頂點(diǎn)處理模式,則矩陣調(diào)色板的最大容量為256,不管是否需要對(duì)法線向量進(jìn)行混合。

            MaxVertexBlendMatrixIndex
            DWORD value that specifies the maximum matrix index that can be indexed into using the per-vertex indices. The number of matrices is MaxVertexBlendMatrixIndex + 1, which is the size of the matrix palette. If normals are present in the vertex data that needs to be blended for lighting, then the number of matrices is half the number specified by this capability flag. If MaxVertexBlendMatrixIndex is set to zero, the driver does not support indexed vertex blending. If this value is not zero then the valid range of indices is zero through MaxVertexBlendMatrixIndex.

            A zero value for MaxVertexBlendMatrixIndex indicates that the driver does not support indexed matrices.

            When software vertex processing is used, 256 matrices could be used for indexed vertex blending, with or without normal blending.

            For a given physical device, this capability may vary across Direct3D devices depending on the parameters supplied to IDirect3D9::CreateDevice.

            綜合上面圖形混合和索引頂點(diǎn)混合的內(nèi)容,對(duì)頂點(diǎn)混合可以總結(jié)如下:

            (1)不管是否使用索引頂點(diǎn)混合,混合矩陣都是通過(guò)索引從矩陣調(diào)色板中引用。

            (2)如果不使用索引頂點(diǎn)混合,則混合矩陣索引最大為3,而且在頂點(diǎn)數(shù)據(jù)中不需要包含矩陣索引,矩陣索引默認(rèn)為0~3。

            (3)如果使用索引頂點(diǎn)混合,矩陣索引最大為255,而且在頂點(diǎn)數(shù)據(jù)中需要指定影響該頂點(diǎn)混合矩陣的索引。

            (4)使用圖形混合之前,首先需要檢查當(dāng)前設(shè)備支持的調(diào)色板容量是否滿足要求,因?yàn)槭褂密浖旤c(diǎn)處理模式時(shí),最大混合矩陣索引為255,肯定能滿足要求,所以如果硬件頂點(diǎn)處理模式下矩陣調(diào)色板容量不能滿足要求,只需簡(jiǎn)單轉(zhuǎn)換為使用軟件頂點(diǎn)處理模式即可。

             

            蒙皮骨骼動(dòng)畫(huà)跟單純的骨骼動(dòng)畫(huà)相比,只是使用了頂點(diǎn)混合技術(shù),解決單純的骨骼動(dòng)畫(huà)存在的問(wèn)題。

            首先我們需要定義包含頂點(diǎn)混合權(quán)重和法線向量的結(jié)構(gòu)體,還需要定義兩個(gè)混合矩陣:

            struct sBlendVertex
            {
            D3DXVECTOR3 pos;
            float blend;
            D3DXVECTOR3 normal;
            };
            #define BLEND_VERTEX_FVF (D3DFVF_XYZB1 | D3DFVF_NORMAL)
            CDXUTMesh*	g_dxut_mesh;
            D3DXMATRIX g_blend_matrix_1;
            D3DXMATRIX g_blend_matrix_2;

            因?yàn)轫旤c(diǎn)所有骨骼權(quán)重之和是1,所以如果1個(gè)頂點(diǎn)受到n塊骨骼的影響,那么為頂點(diǎn)指定n-1個(gè)權(quán)重即可,最后一個(gè)權(quán)重可以通過(guò)1減去n-1個(gè)權(quán)重之和得到。這里每個(gè)頂點(diǎn)只受兩個(gè)骨骼矩陣的影響,所以在上面的頂點(diǎn)結(jié)構(gòu)中只需提供一個(gè)頂點(diǎn)權(quán)重即可。

            接著在回調(diào)函數(shù)ModifyDeviceSetttings()中用下列語(yǔ)句檢查硬件是否支持索引頂點(diǎn)混合,如果當(dāng)前硬件不支持索引頂點(diǎn)混合,則使用軟件頂點(diǎn)處理模式:

            if(pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
            pDeviceSettings->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
            // if current device does not support vertex blending, use software device.
            if(pCaps->MaxVertexBlendMatrices < 1)
            pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

            接下來(lái)在回調(diào)函數(shù)OnCreateDevice()中從.x文件中加載網(wǎng)格模型,因?yàn)樵摼W(wǎng)格模型中并沒(méi)有包含骨骼權(quán)重信息,所以首先調(diào)用CDXUTMesh:SetFVF()設(shè)置網(wǎng)格模型的頂點(diǎn)靈活格式,然后為該網(wǎng)格模型的每個(gè)頂點(diǎn)添加權(quán)重:

            g_dxut_mesh = new CDXUTMesh();
            V_RETURN(g_dxut_mesh->Create(pd3dDevice, L"mslogo.x"));
            // add vertex blending weight and normal information
            g_dxut_mesh->SetFVF(pd3dDevice, BLEND_VERTEX_FVF);
            DWORD num_vertices = g_dxut_mesh->GetMesh()->GetNumVertices();
            IDirect3DVertexBuffer9* vertex_buffer;
            g_dxut_mesh->GetMesh()->GetVertexBuffer(&vertex_buffer);
            sBlendVertex* blend_vertices;
            vertex_buffer->Lock(0, 0, (void**)&blend_vertices, 0);
            // count min and max x coordinate of all vertices for calculating vertex blending weight
            float min_x =  1e10f;
            float max_x = -1e10f;
            for(DWORD i = 0; i < num_vertices; i++)
            {
            if(blend_vertices[i].pos.x < min_x)
            min_x = blend_vertices[i].pos.x;
            	if(blend_vertices[i].pos.x > max_x)
            max_x = blend_vertices[i].pos.x;
            }
            // calculate for all vertices blending weight
            for(DWORD i = 0; i < num_vertices; i++)
            {
            float scale = (blend_vertices[i].pos.x - min_x) / (max_x - min_x);
            blend_vertices[i].blend = 1.0f - sinf(scale * D3DX_PI);
            }
            vertex_buffer->Unlock();
            vertex_buffer->Release();

            接下來(lái)在回調(diào)函數(shù)中OnFrameMove()中實(shí)時(shí)構(gòu)造并設(shè)置骨骼變換矩陣:

            float scale = (float) fTime;
            // calculate blend matrix
            D3DXVECTOR3 axis(2 + sinf(scale * 3.1f), 2 + sinf(scale * 3.3f), sinf(scale * 3.5f));
            D3DXMatrixIdentity(&g_blend_matrix_1);
            D3DXMatrixRotationAxis(&g_blend_matrix_2, &axis, sinf(3 * scale));
            // set vertex blend method and blend matrix
            pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS);
            pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(0), &g_blend_matrix_1);
            pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(1), &g_blend_matrix_2);

            上面代碼中的最后三行是相互對(duì)應(yīng)的,缺一不可。首先將渲染狀態(tài)D3DRS_VERTEXBLEND設(shè)置為D3DVBF_1WEIGHTS,渲染狀態(tài)D3DRS_VERTEXBLEND用來(lái)指定進(jìn)行頂點(diǎn)混合時(shí)所使用的矩陣的數(shù)目,這里將它設(shè)置為D3DVBF_1WEIGHTS,表示用宏D3DTS_WORLDMATRIX(index)設(shè)置兩個(gè)骨骼矩陣進(jìn)行頂點(diǎn)混合,而且這兩個(gè)骨骼矩陣的索引號(hào)分別是0和1。

            因?yàn)橐M(jìn)行頂點(diǎn)混合,所以函數(shù)SetTransform()將要設(shè)置的不再是普通的世界坐標(biāo)變換矩陣,而是骨骼變換矩陣,所以它的第一個(gè)參數(shù)應(yīng)該采用宏D3DTS_WORLDMATRIX(index)的格式,而不像以前一樣使用標(biāo)識(shí)符D3DTS_WORLD。宏D3DTS_WORLDMATRIX(index)的定義如下:

            #define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)

            該宏負(fù)責(zé)將索引號(hào)index映射到相應(yīng)的變換狀態(tài)下。

            在設(shè)置好各個(gè)骨骼矩陣之后,在回調(diào)函數(shù)OnFrameRender()中渲染網(wǎng)格模型:

            g_dxut_mesh->Render(pd3dDevice);

             

            運(yùn)行截圖:

             

            主程序:

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

            #pragma warning(disable : 
            4127 4995)

            struct sBlendVertex
            {
                D3DXVECTOR3 pos;
                
            float        blend;
                D3DXVECTOR3 normal;
            };

            #define BLEND_VERTEX_FVF (D3DFVF_XYZB1 | D3DFVF_NORMAL)

            #define IDC_TOGGLE_FULLSCREEN    1
            #define IDC_TOGGLE_REF            2
            #define IDC_CHANGE_DEVICE        3

            #define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

            ID3DXFont
            *                    g_font;
            ID3DXSprite
            *                g_text_sprite;
            bool                        g_show_help;

            CDXUTDialogResourceManager    g_dlg_resource_manager;
            CD3DSettingsDlg                g_settings_dlg;
            CDXUTDialog                    g_button_dlg;

            CDXUTMesh
            *                    g_dxut_mesh;
            D3DXMATRIX                    g_blend_matrix_1;
            D3DXMATRIX                    g_blend_matrix_2;

            //--------------------------------------------------------------------------------------
            // Rejects any devices that aren't acceptable by returning false
            //--------------------------------------------------------------------------------------
            bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                              D3DFORMAT BackBufferFormat, 
            bool bWindowed, void* pUserContext )
            {
                
            // Typically want to skip backbuffer formats that don't support alpha blending

                IDirect3D9
            * pD3D = DXUTGetD3DObject(); 

                
            if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, 
                                D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
                    
            return false;

                
            return true;
            }


            //--------------------------------------------------------------------------------------
            // Before a device is created, modify the device settings as needed.
            //--------------------------------------------------------------------------------------
            bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
            {
                
            // If video card does not support hardware vertex processing, then uses sofaware vertex processing.
                if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

                
            static bool is_first_time = true;

                
            if(is_first_time)
                {
                    is_first_time 
            = false;

                    
            // if using reference device, then pop a warning message box.
                    if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
                        DXUTDisplaySwitchingToREFWarning();
                }

                
            if(pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;

                
            // if current device does not support vertex blending, use software device.
                if(pCaps->MaxVertexBlendMatrices < 1)
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

                
            return true;
            }

            //--------------------------------------------------------------------------------------
            // Remove path from fullname, and convert filename from multibyte to wchar.
            //--------------------------------------------------------------------------------------
            void RemovePathFromFileName(LPSTR fullname, LPWSTR wfilename)
            {
                WCHAR wbuf[MAX_PATH]  
            = {0};
                MultiByteToWideChar(CP_ACP, 
            0, fullname, -1, wbuf, MAX_PATH);

                LPWSTR w_last_back_slash 
            = wcsrchr(wbuf, '\\');

                
            if(w_last_back_slash)
                    lstrcpy(wfilename, 
            ++w_last_back_slash);
                
            else
                    lstrcpy(wfilename, wbuf);
            }


            //--------------------------------------------------------------------------------------
            // Create any D3DPOOL_MANAGED resources here 
            //--------------------------------------------------------------------------------------
            HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, 
                                             
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                             
            void* pUserContext )
            {
                HRESULT    hr;

                V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice));
                V_RETURN(g_settings_dlg.OnCreateDevice(pd3dDevice));

                D3DXCreateFont(pd3dDevice, 
            180, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                               DEFAULT_PITCH 
            | FF_DONTCARE, L"Arial"&g_font);
                
                g_dxut_mesh 
            = new CDXUTMesh();
                V_RETURN(g_dxut_mesh
            ->Create(pd3dDevice, L"mslogo.x"));

                
            // add vertex blending weight and normal information
                g_dxut_mesh->SetFVF(pd3dDevice, BLEND_VERTEX_FVF);
                
                IDirect3DVertexBuffer9
            * vertex_buffer;
                g_dxut_mesh
            ->GetMesh()->GetVertexBuffer(&vertex_buffer);

                sBlendVertex
            * blend_vertices;
                vertex_buffer
            ->Lock(00, (void**)&blend_vertices, 0);

                
            // count min and max x coordinate of all vertices for calculating vertex blending weight

                DWORD num_vertices 
            = g_dxut_mesh->GetMesh()->GetNumVertices();

                
            float min_x =  1e10f;
                
            float max_x = -1e10f;    

                
            for(DWORD i = 0; i < num_vertices; i++)
                {
                    
            if(blend_vertices[i].pos.x < min_x)
                        min_x 
            = blend_vertices[i].pos.x;

                    
            if(blend_vertices[i].pos.x > max_x)
                        max_x 
            = blend_vertices[i].pos.x;
                }

                
            // calculate for all vertices blending weight
                for(DWORD i = 0; i < num_vertices; i++)
                {
                    
            float scale = (blend_vertices[i].pos.x - min_x) / (max_x - min_x);
                    blend_vertices[i].blend 
            = 1.0f - sinf(scale * D3DX_PI);
                }

                vertex_buffer
            ->Unlock();
                vertex_buffer
            ->Release();        

                
            return S_OK;
            }


            //--------------------------------------------------------------------------------------
            // Create any D3DPOOL_DEFAULT resources here 
            //--------------------------------------------------------------------------------------
            HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                            
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                            
            void* pUserContext )
            {
                HRESULT hr;

                V_RETURN(g_dlg_resource_manager.OnResetDevice());
                V_RETURN(g_settings_dlg.OnResetDevice());
                V_RETURN(g_font
            ->OnResetDevice());
                V_RETURN(D3DXCreateSprite(pd3dDevice, 
            &g_text_sprite));

                
            // set dialog position and size

                g_button_dlg.SetLocation(pBackBufferSurfaceDesc
            ->Width - 1700);
                g_button_dlg.SetSize(
            170170);    

                
            // setup view matrix

                D3DXMATRIX mat_view;
                D3DXVECTOR3 eye(
            0.0f0.0f,  -10.0f);
                D3DXVECTOR3  at(
            0.0f0.0f,    0.0f);
                D3DXVECTOR3  up(
            0.0f1.0f,    0.0f);

                D3DXMatrixLookAtLH(
            &mat_view, &eye, &at, &up);
                pd3dDevice
            ->SetTransform(D3DTS_VIEW, &mat_view);

                
            // set projection matrix
                D3DXMATRIX mat_proj;
                
            float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
                D3DXMatrixPerspectiveFovLH(
            &mat_proj, D3DX_PI/4, aspect, 1.0f100.0f);
                pd3dDevice
            ->SetTransform(D3DTS_PROJECTION, &mat_proj);    

                
            // set material
                D3DMATERIAL9 material;
                ZeroMemory(
            &material, sizeof(D3DMATERIAL9));

                material.Ambient.r 
            = material.Diffuse.r = 1.0f;
                material.Ambient.g 
            = material.Diffuse.g = 1.0f;
                material.Ambient.b 
            = material.Diffuse.b = 1.0f;
                material.Ambient.a 
            = material.Diffuse.a = 1.0f;

                pd3dDevice
            ->SetMaterial(&material);

                
            // setup light
                
                D3DLIGHT9 light;
                ZeroMemory(
            &light, sizeof(D3DLIGHT9));

                light.Type       
            = D3DLIGHT_DIRECTIONAL;
                light.Diffuse.r  
            = 1.5f;
                light.Diffuse.g  
            = 0.8f;
                light.Diffuse.b  
            = 1.0f;    

                D3DXVECTOR3 light_dir(
            0.0f0.0f10.0f);    
                D3DXVec3Normalize((D3DXVECTOR3
            *&light.Direction, &light_dir);
                pd3dDevice
            ->SetLight(0&light);
                pd3dDevice
            ->LightEnable(0, TRUE);
                pd3dDevice
            ->SetRenderState(D3DRS_LIGHTING, TRUE);

                pd3dDevice
            ->SetRenderState(D3DRS_AMBIENT, 0x00404040);

                
            return S_OK;
            }

            //--------------------------------------------------------------------------------------
            // Release resources created in the OnResetDevice callback here 
            //--------------------------------------------------------------------------------------
            void CALLBACK OnLostDevice( void* pUserContext )
            {
                g_dlg_resource_manager.OnLostDevice();
                g_settings_dlg.OnLostDevice();
                g_font
            ->OnLostDevice();

                release_com(g_text_sprite);
            }


            //--------------------------------------------------------------------------------------
            // Release resources created in the OnCreateDevice callback here
            //--------------------------------------------------------------------------------------
            void CALLBACK OnDestroyDevice( void* pUserContext )
            {
                g_dlg_resource_manager.OnDestroyDevice();
                g_settings_dlg.OnDestroyDevice();    

                release_com(g_font);
                SAFE_DELETE(g_dxut_mesh);
            }

            //--------------------------------------------------------------------------------------
            // Handle updates to the scene
            //--------------------------------------------------------------------------------------
            void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
            {    
                
            float scale = (float) fTime;

                
            // calculate blend matrix
                D3DXVECTOR3 axis(2 + sinf(scale * 3.1f), 2 + sinf(scale * 3.3f), sinf(scale * 3.5f));
                D3DXMatrixIdentity(
            &g_blend_matrix_1);
                D3DXMatrixRotationAxis(
            &g_blend_matrix_2, &axis, sinf(3 * scale));

                
            // set vertex blend method and blend matrix
                pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS);
                pd3dDevice
            ->SetTransform(D3DTS_WORLDMATRIX(0), &g_blend_matrix_1);
                pd3dDevice
            ->SetTransform(D3DTS_WORLDMATRIX(1), &g_blend_matrix_2);
            }

            //--------------------------------------------------------------------------------------
            // Render the helper information
            //--------------------------------------------------------------------------------------
            void RenderText()
            {
                CDXUTTextHelper text_helper(g_font, g_text_sprite, 
            20);
                
                text_helper.Begin();

                
            // show frame and device states
                text_helper.SetInsertionPos(55);
                text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f0.475f0.0f1.0f) );
                text_helper.DrawTextLine( DXUTGetFrameStats(
            true) );
                text_helper.DrawTextLine( DXUTGetDeviceStats() );

                
            // show helper information
                
                
            const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();

                
            if(g_show_help)
                {
                    text_helper.SetInsertionPos(
            10, surface_desc->Height - 15 * 6);
                    text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f0.475f0.0f1.0f) );
                    text_helper.DrawTextLine(L
            "Controls (F1 to hide):");
                    
                    text_helper.SetInsertionPos(
            40, surface_desc->Height - 15 * 4);
                    text_helper.DrawTextLine(L
            "Quit: ESC");
                }
                
            else
                {
                    text_helper.SetInsertionPos(
            10, surface_desc->Height - 15 * 4);
                    text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f1.0f1.0f1.0f) );
                    text_helper.DrawTextLine(L
            "Press F1 for help");
                }

                text_helper.End();
            }

            //--------------------------------------------------------------------------------------
            // Render the scene 
            //--------------------------------------------------------------------------------------
            void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
            {
                HRESULT hr;

                
            if(g_settings_dlg.IsActive())
                {
                    g_settings_dlg.OnRender(fElapsedTime);
                    
            return;
                }

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

                
            // Render the scene
                if( SUCCEEDED( pd3dDevice->BeginScene() ) )
                {                    
                    g_dxut_mesh
            ->Render(pd3dDevice);
                    RenderText();
                    V(g_button_dlg.OnRender(fElapsedTime));

                    V( pd3dDevice
            ->EndScene() );
                }
            }


            //--------------------------------------------------------------------------------------
            // Handle messages to the application 
            //--------------------------------------------------------------------------------------
            LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                                      
            bool* pbNoFurtherProcessing, void* pUserContext )
            {
                
            *pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
                
            if(*pbNoFurtherProcessing)
                    
            return 0;

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

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

                
            return 0;
            }


            //--------------------------------------------------------------------------------------
            // Handle keybaord event
            //--------------------------------------------------------------------------------------
            void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
            {
                
            if(is_key_down)
                {
                    
            switch(charater)
                    {
                    
            case VK_F1:
                        g_show_help 
            = !g_show_help;
                        
            break;
                    }
                }
            }

            //--------------------------------------------------------------------------------------
            // Handle events for controls
            //--------------------------------------------------------------------------------------
            void CALLBACK OnGUIEvent(UINT eventint control_id, CDXUTControl* control, void* user_context)
            {
                
            switch(control_id)
                {
                
            case IDC_TOGGLE_FULLSCREEN:
                    DXUTToggleFullScreen();
                    
            break;

                
            case IDC_TOGGLE_REF:
                    DXUTToggleREF();
                    
            break;

                
            case IDC_CHANGE_DEVICE:
                    g_settings_dlg.SetActive(
            true);
                    
            break;
                }
            }

            //--------------------------------------------------------------------------------------
            // Initialize dialogs
            //--------------------------------------------------------------------------------------
            void InitDialogs()
            {
                g_settings_dlg.Init(
            &g_dlg_resource_manager);
                g_button_dlg.Init(
            &g_dlg_resource_manager);

                g_button_dlg.SetCallback(OnGUIEvent);

                
            int x = 35, y = 10, width = 125, height = 22;

                g_button_dlg.AddButton(IDC_TOGGLE_FULLSCREEN, L
            "Toggle full screen", x, y,         width, height);
                g_button_dlg.AddButton(IDC_TOGGLE_REF,          L
            "Toggle REF (F3)",     x, y += 24, width, height);
                g_button_dlg.AddButton(IDC_CHANGE_DEVICE,      L
            "Change device (F2)", x, y += 24, width, height, VK_F2);    
            }

            //--------------------------------------------------------------------------------------
            // Initialize everything and go into a render loop
            //--------------------------------------------------------------------------------------
            INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
            {
                
            // Enable run-time memory check for debug builds.
            #if defined(DEBUG) | defined(_DEBUG)
                _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
            | _CRTDBG_LEAK_CHECK_DF );
            #endif

                
            // Set the callback functions
                DXUTSetCallbackDeviceCreated( OnCreateDevice );
                DXUTSetCallbackDeviceReset( OnResetDevice );
                DXUTSetCallbackDeviceLost( OnLostDevice );
                DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
                DXUTSetCallbackMsgProc( MsgProc );
                DXUTSetCallbackFrameRender( OnFrameRender );
                DXUTSetCallbackFrameMove( OnFrameMove );
                DXUTSetCallbackKeyboard(OnKeyboardProc);
               
                
            // TODO: Perform any application-level initialization here
                InitDialogs();

                
            // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
                DXUTInit( truetruetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
                DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
                DXUTCreateWindow( L"Vertex Blend" );
                DXUTCreateDevice( D3DADAPTER_DEFAULT, 
            true640480, IsDeviceAcceptable, ModifyDeviceSettings );

                
            // Start the render loop
                DXUTMainLoop();

                
            // TODO: Perform any application-level cleanup here

                
            return DXUTGetExitCode();
            }

             

            下載示例工程


            posted on 2008-06-12 10:17 lovedday 閱讀(2798) 評(píng)論(0)  編輯 收藏 引用

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            一本色综合久久| 久久久人妻精品无码一区| 日韩精品无码久久一区二区三| 久久精品人成免费| 中文字幕无码久久精品青草| 99久久国产综合精品网成人影院| 久久精品中文闷骚内射| 无码久久精品国产亚洲Av影片 | 精品久久人人爽天天玩人人妻| 久久午夜福利电影| 久久久久亚洲精品无码网址| 一本一道久久精品综合| 久久精品国产WWW456C0M| 人人狠狠综合久久亚洲| 欧美亚洲另类久久综合婷婷| 亚洲国产精品成人AV无码久久综合影院 | 久久久久国产亚洲AV麻豆| 久久精品成人免费观看97| 性欧美大战久久久久久久| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久精品九九亚洲精品天堂| 99久久成人18免费网站| 色8激情欧美成人久久综合电| 亚洲精品成人网久久久久久| 久久精品一区二区三区AV| 久久精品国产亚洲AV麻豆网站| 国产91久久精品一区二区| 久久99国产精品成人欧美| 中文成人无码精品久久久不卡| 久久无码高潮喷水| 久久r热这里有精品视频| 久久久久亚洲精品天堂久久久久久| 国产精品久久久久蜜芽| 好久久免费视频高清| 亚洲Av无码国产情品久久| 人妻精品久久无码专区精东影业| 99久久无码一区人妻| 久久久久亚洲精品日久生情| 伊人久久综在合线亚洲2019| 久久久久亚洲av综合波多野结衣 | 久久精品中文字幕有码|