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

            天行健 君子當自強而不息

            網格模型高級技術(5)

            Direct3D對加載到內存中的網格模型提供了優化功能,通過網格模型優化可以明顯提高三維模型的渲染速度,這對渲染速度要求較高的三維圖形程序和游戲具有非常重要的現實意義。

            對于程序員而言,對網格模型進行優化是比較簡單的,只需調用接口ID3DXMesh的方法Optimize(),該函數的聲明如下:

            Generates a new mesh with reordered faces and vertices to optimize drawing performance.

            HRESULT Optimize(
            DWORD Flags,
            CONST DWORD * pAdjacencyIn,
            DWORD * pAdjacencyOut,
            DWORD * pFaceRemap,
            LPD3DXBUFFER * ppVertexRemap,
            LPD3DXMESH * ppOptMesh
            );

            Parameters

            Flags
            [in] Specifies the type of optimization to perform. This parameter can be set to a combination of one or more flags from D3DXMESHOPT and D3DXMESH (except D3DXMESH_32BIT, D3DXMESH_IB_WRITEONLY, and D3DXMESH_WRITEONLY).
            pAdjacencyIn
            [in] Pointer to an array of three DWORDs per face that specifies the three neighbors for each face in the source mesh. If the edge has no adjacent faces, the value is 0xffffffff. See Remarks.
            pAdjacencyOut
            [in, out] Pointer to an array of three DWORDs per face that specifies the three neighbors for each face in the optimized mesh. If the edge has no adjacent faces, the value is 0xffffffff.
            pFaceRemap
            [in, out] An array of DWORDs, one per face, that identifies the original mesh face that corresponds to each face in the optimized mesh. If the value supplied for this argument is NULL, face remap data is not returned.
            ppVertexRemap
            [out] Address of a pointer to an ID3DXBuffer interface, which contains a DWORD for each vertex that specifies how the new vertices map to the old vertices. This remap is useful if you need to alter external data based on the new vertex mapping.
            ppOptMesh
            [out] Address of a pointer to an ID3DXMesh interface, representing the optimized mesh.

            Return Values

            If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

            Remarks

            This method generates a new mesh. Before running Optimize, an application must generate an adjacency buffer by calling ID3DXBaseMesh::GenerateAdjacency. The adjacency buffer contains adjacency data, such as a list of edges and the faces that are adjacent to each other.

            This method is very similar to the ID3DXBaseMesh::CloneMesh method, except that it can perform optimization while generating the new clone of the mesh. The output mesh inherits all of the creation parameters of the input mesh.

            Direct3D提供了7種網格模型優化方式,由枚舉常量D3DXMESHOPT定義:

            Specifies the type of mesh optimization to be performed.

            typedef enum D3DXMESHOPT
            {
            D3DXMESHOPT_COMPACT = 0x01000000,
            D3DXMESHOPT_ATTRSORT = 0x02000000,
            D3DXMESHOPT_VERTEXCACHE = 0x04000000,
            D3DXMESHOPT_STRIPREORDER = 0x08000000,
            D3DXMESHOPT_IGNOREVERTS = 0x10000000,
            D3DXMESHOPT_DONOTSPLIT = 0x20000000,
            D3DXMESHOPT_DEVICEINDEPENDENT = 0x40000000,
            } D3DXMESHOPT, *LPD3DXMESHOPT;

            Constants

            D3DXMESHOPT_COMPACT
            Reorders faces to remove unused vertices and faces.
            D3DXMESHOPT_ATTRSORT
            Reorders faces to optimize for fewer attribute bundle state changes and enhanced ID3DXBaseMesh::DrawSubset performance.
            D3DXMESHOPT_VERTEXCACHE
            Reorders faces to increase the cache hit rate of vertex caches.
            D3DXMESHOPT_STRIPREORDER
            Reorders faces to maximize length of adjacent triangles.
            D3DXMESHOPT_IGNOREVERTS
            Optimize the faces only; do not optimize the vertices.
            D3DXMESHOPT_DONOTSPLIT
            While attribute sorting, do not split vertices that are shared between attribute groups.
            D3DXMESHOPT_DEVICEINDEPENDENT
            Affects the vertex cache size. Using this flag specifies a default vertex cache size that works well on legacy hardware.

            Remarks

            The D3DXMESHOPT_STRIPREORDER and D3DXMESHOPT_VERTEXCACHE optimization flags are mutually exclusive.

            The D3DXMESHOPT_SHAREVB flag has been removed from this enumeration. Use D3DXMESH_VB_SHARE instead, in D3DXMESH.

            D3DXMESH

            Flags used to specify creation options for a mesh.

            typedef enum D3DXMESH
            {
            D3DXMESH_32BIT = 0x001,
            D3DXMESH_DONOTCLIP = 0x002,
            D3DXMESH_POINTS = 0x004,
            D3DXMESH_RTPATCHES = 0x008,
            D3DXMESH_NPATCHES = 0x4000,
            D3DXMESH_VB_SYSTEMMEM = 0x010,
            D3DXMESH_VB_MANAGED = 0x020,
            D3DXMESH_VB_WRITEONLY = 0x040,
            D3DXMESH_VB_DYNAMIC = 0x080,
            D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000,
            D3DXMESH_IB_SYSTEMMEM = 0x100,
            D3DXMESH_IB_MANAGED = 0x200,
            D3DXMESH_IB_WRITEONLY = 0x400,
            D3DXMESH_IB_DYNAMIC = 0x800,
            D3DXMESH_IB_SOFTWAREPROCESSING = 0x10000,
            D3DXMESH_VB_SHARE = 0x1000,
            D3DXMESH_USEHWONLY = 0x2000,
            D3DXMESH_SYSTEMMEM = 0x110,
            D3DXMESH_MANAGED = 0x220,
            D3DXMESH_WRITEONLY = 0x440,
            D3DXMESH_DYNAMIC = 0x880,
            D3DXMESH_SOFTWAREPROCESSING = 0x18000,
            } D3DXMESH, *LPD3DXMESH;

            Constants

            D3DXMESH_32BIT
            The mesh has 32-bit indices instead of 16-bit indices. See Remarks.
            D3DXMESH_DONOTCLIP
            Use the D3DUSAGE_DONOTCLIP usage flag for vertex and index buffers.
            D3DXMESH_POINTS
            Use the D3DUSAGE_POINTS usage flag for vertex and index buffers.
            D3DXMESH_RTPATCHES
            Use the D3DUSAGE_RTPATCHES usage flag for vertex and index buffers.
            D3DXMESH_NPATCHES
            Specifying this flag causes the vertex and index buffer of the mesh to be created with D3DUSAGE_NPATCHES flag. This is required if the mesh object is to be rendered using N-patch enhancement using Direct3D.
            D3DXMESH_VB_SYSTEMMEM
            Use the D3DPOOL_SYSTEMMEM usage flag for vertex buffers.
            D3DXMESH_VB_MANAGED
            Use the D3DPOOL_MANAGED usage flag for vertex buffers.
            D3DXMESH_VB_WRITEONLY
            Use the D3DUSAGE_WRITEONLY usage flag for vertex buffers.
            D3DXMESH_VB_DYNAMIC
            Use the D3DUSAGE_DYNAMIC usage flag for vertex buffers.
            D3DXMESH_VB_SOFTWAREPROCESSING
            Use the D3DUSAGE_SOFTWAREPROCESSING usage flag for vertex buffers.
            D3DXMESH_IB_SYSTEMMEM
            Use the D3DPOOL_SYSTEMMEM usage flag for index buffers.
            D3DXMESH_IB_MANAGED
            Use the D3DPOOL_MANAGED usage flag for index buffers.
            D3DXMESH_IB_WRITEONLY
            Use the D3DUSAGE_WRITEONLY usage flag for index buffers.
            D3DXMESH_IB_DYNAMIC
            Use the D3DUSAGE_DYNAMIC usage flag for index buffers.
            D3DXMESH_IB_SOFTWAREPROCESSING
            Use the D3DUSAGE_SOFTWAREPROCESSING usage flag for index buffers.
            D3DXMESH_VB_SHARE
            Forces the cloned meshes to share vertex buffers.
            D3DXMESH_USEHWONLY
            Use hardware processing only. For mixed-mode device, this flag will cause the system to use hardware (if supported in hardware) or will default to software processing.
            D3DXMESH_SYSTEMMEM
            Equivalent to specifying both D3DXMESH_VB_SYSTEMMEM and D3DXMESH_IB_SYSTEMMEM.
            D3DXMESH_MANAGED
            Equivalent to specifying both D3DXMESH_VB_MANAGED and D3DXMESH_IB_MANAGED.
            D3DXMESH_WRITEONLY
            Equivalent to specifying both D3DXMESH_VB_WRITEONLY and D3DXMESH_IB_WRITEONLY.
            D3DXMESH_DYNAMIC
            Equivalent to specifying both D3DXMESH_VB_DYNAMIC and D3DXMESH_IB_DYNAMIC.
            D3DXMESH_SOFTWAREPROCESSING
            Equivalent to specifying both D3DXMESH_VB_SOFTWAREPROCESSING and D3DXMESH_IB_SOFTWAREPROCESSING.

            Remarks

            A 32-bit mesh (D3DXMESH_32BIT) can theoretically support (2^32)-1 faces and vertices. However, allocating memory for a mesh that large on a 32-bit operating system is not practical.

            因為調用ID3DXMesh::Optimize()函數對網格模型進行優化時,需要用到網格模型中每個面的三個鄰接信息,該信息在加載網格模型時得到:

            ID3DXBuffer* material_buffer;
            V_RETURN(D3DXLoadMeshFromXW(L"Dwarf.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL,
            &g_num_materials, &g_mesh));
            D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();
            g_mesh_materials = new D3DMATERIAL9[g_num_materials];
            g_mesh_textures = new IDirect3DTexture9*[g_num_materials];
            for(DWORD i = 0; i < g_num_materials; i++)
            {
            g_mesh_materials[i] = xmaterials[i].MatD3D;
            g_mesh_materials[i].Ambient = g_mesh_materials[i].Diffuse;
            	WCHAR wfilename[256];
            RemovePathFromFileName(xmaterials[i].pTextureFilename, wfilename);
            	g_mesh_textures[i] = NULL;
            	if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0)
            {
            V_RETURN(D3DXCreateTextureFromFileW(pd3dDevice, wfilename, &g_mesh_textures[i]));
            }
            }
            material_buffer->Release();

            接著我們以三種方式對原始網格模型進行了優化:

            DWORD* adj_in = (DWORD*) g_adj_buffer->GetBufferPointer();
            V_RETURN(g_mesh->Optimize(D3DXMESHOPT_ATTRSORT | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
            &g_mesh_attr_sort));
            V_RETURN(g_mesh->Optimize(D3DXMESHOPT_STRIPREORDER | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
            &g_mesh_strip_reorder));
            V_RETURN(g_mesh->Optimize(D3DXMESHOPT_VERTEXCACHE | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
            &g_mesh_vertex_cache));

            渲染優化后的網格模型與未優化的網格模型相比沒有任何區別:

            // Clear the render target and the zbuffer 
            V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );
            // Render the scene
            if( SUCCEEDED( pd3dDevice->BeginScene() ) )
            {
            for(DWORD i = 0; i < g_num_materials; i++)
            {
            pd3dDevice->SetMaterial(&g_mesh_materials[i]);
            pd3dDevice->SetTexture(0, g_mesh_textures[i]);
            		switch(g_render_flag)
            {
            case OPT_NONE:
            g_mesh->DrawSubset(i);
            break;
            		case OPT_ATTR_SORT:
            g_mesh_attr_sort->DrawSubset(i);
            break;
            		case OPT_STRIP_REORDER:
            g_mesh_strip_reorder->DrawSubset(i);
            break;
            		case OPT_VERTEX_CACHE:
            g_mesh_vertex_cache->DrawSubset(i);
            break;
            }
            }
            	RenderText();
            	V(g_button_dlg.OnRender(fElapsedTime));
                V( pd3dDevice->EndScene() );
            }

            運行效果圖:

             

            主程序:

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

            #pragma warning(disable : 
            4127 4995)

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

            #define OPT_NONE                0
            #define OPT_ATTR_SORT            1
            #define OPT_STRIP_REORDER        2
            #define OPT_VERTEX_CACHE        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 = true;

            CDXUTDialogResourceManager    g_dlg_resource_manager;
            CD3DSettingsDlg                g_settings_dlg;
            CDXUTDialog                    g_button_dlg;

            ID3DXMesh
            *                    g_mesh;
            D3DMATERIAL9
            *                g_mesh_materials;
            IDirect3DTexture9
            **            g_mesh_textures;
            DWORD                        g_num_materials;
            ID3DXBuffer
            *                g_adj_buffer;

            ID3DXMesh
            *                    g_mesh_attr_sort;
            ID3DXMesh
            *                    g_mesh_strip_reorder;
            ID3DXMesh
            *                    g_mesh_vertex_cache;
            WCHAR                        g_opt_info[
            256];
            int                            g_render_flag = OPT_NONE;

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

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

                ID3DXBuffer
            * material_buffer;

                V_RETURN(D3DXLoadMeshFromXW(L
            "Dwarf.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL,
                                            
            &g_num_materials, &g_mesh));

                D3DXMATERIAL
            * xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();
                g_mesh_materials 
            = new D3DMATERIAL9[g_num_materials];
                g_mesh_textures  
            = new IDirect3DTexture9*[g_num_materials];

                
            for(DWORD i = 0; i < g_num_materials; i++)
                {
                    g_mesh_materials[i] 
            = xmaterials[i].MatD3D;
                    g_mesh_materials[i].Ambient 
            = g_mesh_materials[i].Diffuse;

                    WCHAR wfilename[
            256];
                    RemovePathFromFileName(xmaterials[i].pTextureFilename, wfilename);

                    g_mesh_textures[i] 
            = NULL;

                    
            if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0)
                    {
                        V_RETURN(D3DXCreateTextureFromFileW(pd3dDevice, wfilename, 
            &g_mesh_textures[i]));
                    }
                }
                
                material_buffer
            ->Release();

                lstrcpy(g_opt_info, L
            "optimize method: none");

                DWORD
            * adj_in = (DWORD*) g_adj_buffer->GetBufferPointer();

                V_RETURN(g_mesh
            ->Optimize(D3DXMESHOPT_ATTRSORT | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
                                 
            &g_mesh_attr_sort));

                V_RETURN(g_mesh
            ->Optimize(D3DXMESHOPT_STRIPREORDER | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
                                 
            &g_mesh_strip_reorder));
                    
                V_RETURN(g_mesh
            ->Optimize(D3DXMESHOPT_VERTEXCACHE | D3DXMESH_MANAGED, adj_in, NULL, NULL, NULL,
                                 
            &g_mesh_vertex_cache));

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

                pd3dDevice
            ->SetRenderState(D3DRS_AMBIENT, 0xFFFFFFFF);

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

                delete[] g_mesh_materials;
                g_mesh_materials 
            = NULL;

                
            if(g_mesh_textures)
                {
                    
            for(DWORD i = 0; i < g_num_materials; i++)
                        release_com(g_mesh_textures[i]);

                    delete[] g_mesh_textures;
                    g_mesh_textures 
            = NULL;
                }

                release_com(g_font);
                release_com(g_adj_buffer);
                release_com(g_mesh);
                release_com(g_mesh_attr_sort);
                release_com(g_mesh_strip_reorder);
                release_com(g_mesh_vertex_cache);
            }

            //--------------------------------------------------------------------------------------
            // Handle updates to the scene
            //--------------------------------------------------------------------------------------
            void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
            {
                D3DXMATRIX mat_world, mat_translation, mat_rotation;

                D3DXMatrixTranslation(
            &mat_translation, 0-0.7f0);
                D3DXMatrixRotationY(
            &mat_rotation, timeGetTime() / 1000.0f);
                mat_world 
            = mat_translation * mat_rotation;

                pd3dDevice
            ->SetTransform(D3DTS_WORLD, &mat_world);
            }

            //--------------------------------------------------------------------------------------
            // 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 other simple information
                text_helper.SetForegroundColor( D3DXCOLOR(1.0f1.0f1.0f1.0f) );
                text_helper.DrawTextLine(g_opt_info);

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

                    text_helper.SetInsertionPos(
            40, surface_desc->Height - 15 * 3);
                    text_helper.DrawTextLine(L
            "0, 1, 2, 3: switch optimize method");
                }
                
            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() ) )
                {
                    
            for(DWORD i = 0; i < g_num_materials; i++)
                    {
                        pd3dDevice
            ->SetMaterial(&g_mesh_materials[i]);
                        pd3dDevice
            ->SetTexture(0, g_mesh_textures[i]);

                        
            switch(g_render_flag)
                        {
                        
            case OPT_NONE:
                            g_mesh
            ->DrawSubset(i);
                            
            break;

                        
            case OPT_ATTR_SORT:
                            g_mesh_attr_sort
            ->DrawSubset(i);
                            
            break;

                        
            case OPT_STRIP_REORDER:
                            g_mesh_strip_reorder
            ->DrawSubset(i);
                            
            break;

                        
            case OPT_VERTEX_CACHE:
                            g_mesh_vertex_cache
            ->DrawSubset(i);
                            
            break;
                        }
                    }        

                    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;

                    
            case 48:    // press key "0"
                        g_render_flag = OPT_NONE;
                        lstrcpy(g_opt_info, L
            "optimize method: none");
                        
            break;

                    
            case 49:    // press key "1"
                        g_render_flag = OPT_ATTR_SORT;
                        lstrcpy(g_opt_info, L
            "optimize method: D3DXMESHOPT_ATTRSORT");
                        
            break;

                    
            case 50:    // press key "2"
                        g_render_flag = OPT_STRIP_REORDER;
                        lstrcpy(g_opt_info, L
            "optimize method: D3DXMESHOPT_STRIPREORDER");
                        
            break;

                    
            case 51:    // press key "3"
                        g_render_flag = OPT_VERTEX_CACHE;
                        lstrcpy(g_opt_info, L
            "optimize method: D3DXMESHOPT_VERTEXCACHE");
                        
            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"OptimizedMesh" );
                DXUTCreateDevice( D3DADAPTER_DEFAULT, 
            true640480, IsDeviceAcceptable, ModifyDeviceSettings );

                
            // Start the render loop
                DXUTMainLoop();

                
            // TODO: Perform any application-level cleanup here

                
            return DXUTGetExitCode();
            }

             

            下載示例工程


            posted on 2008-05-27 16:55 lovedday 閱讀(1668) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            香蕉久久久久久狠狠色| 久久精品成人一区二区三区| 精品久久久久久国产牛牛app| 欧美喷潮久久久XXXXx| 精品综合久久久久久97| 久久一区二区三区99| 欧美亚洲日本久久精品| 久久精品国产一区二区三区| 国産精品久久久久久久| 久久性生大片免费观看性| 亚洲国产成人久久综合野外| 久久免费视频一区| 国产精品久久久香蕉| 久久人妻少妇嫩草AV蜜桃| 国产成人精品三上悠亚久久| 性欧美大战久久久久久久久| 久久天堂AV综合合色蜜桃网| 久久精品国产秦先生| 99久久国产主播综合精品| 欧美久久天天综合香蕉伊| 国产精品久久久久蜜芽| 久久久久亚洲精品日久生情| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久天堂AV综合合色蜜桃网| 久久综合国产乱子伦精品免费| 国产成人久久AV免费| 狠狠精品久久久无码中文字幕 | 久久这里只有精品视频99| 久久久久人妻一区精品| 色综合久久久久久久久五月| 91久久精品91久久性色| 久久性精品| 国产亚洲精品自在久久| 欧美国产精品久久高清| 久久久无码一区二区三区| 久久精品中文字幕第23页| 久久人与动人物a级毛片| 久久精品国产久精国产| 中文字幕久久精品无码| 国产精品热久久无码av| 久久99精品久久久久久久久久|