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

            天行健 君子當自強而不息

            網(wǎng)格模型高級技術(shù)(5)

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

            對于程序員而言,對網(wǎng)格模型進行優(yōu)化是比較簡單的,只需調(diào)用接口ID3DXMesh的方法Optimize(),該函數(shù)的聲明如下:

            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種網(wǎng)格模型優(yōu)化方式,由枚舉常量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.

            因為調(diào)用ID3DXMesh::Optimize()函數(shù)對網(wǎng)格模型進行優(yōu)化時,需要用到網(wǎng)格模型中每個面的三個鄰接信息,該信息在加載網(wǎng)格模型時得到:

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

            接著我們以三種方式對原始網(wǎng)格模型進行了優(yōu)化:

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

            渲染優(yōu)化后的網(wǎng)格模型與未優(yōu)化的網(wǎng)格模型相比沒有任何區(qū)別:

            // 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)  編輯 收藏 引用

            公告

            導航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            欧美激情精品久久久久久| 久久久人妻精品无码一区| 日韩精品久久久久久久电影蜜臀| 久久久黄色大片| 久久久久久久人妻无码中文字幕爆 | 久久精品国产72国产精福利| 久久这里有精品视频| 亚洲AV无码久久精品狠狠爱浪潮| 久久se精品一区二区| 亚洲色欲久久久久综合网| 99久久精品午夜一区二区| 久久夜色撩人精品国产小说| 久久夜色精品国产噜噜亚洲AV| 久久国产精品视频| 国产精品对白刺激久久久| 一本久道久久综合狠狠躁AV| 久久国产精品成人免费 | 一本久久a久久精品vr综合| 2021国产成人精品久久| 国内精品伊人久久久久777| 88久久精品无码一区二区毛片 | 欧美成a人片免费看久久| 成人久久久观看免费毛片| 久久人做人爽一区二区三区| 国产激情久久久久影院老熟女免费 | 国产精品VIDEOSSEX久久发布| 久久综合狠狠综合久久 | 久久精品国产99久久久香蕉| 久久国产色AV免费看| 亚洲午夜无码AV毛片久久| 品成人欧美大片久久国产欧美| 人人狠狠综合久久88成人| 人人狠狠综合88综合久久| 国产精品免费久久久久影院| www.久久热.com| 国产日产久久高清欧美一区| 久久婷婷国产综合精品 | 久久综合色之久久综合| 国产精品久久久久一区二区三区| 国产精品久久久久久吹潮| 久久精品aⅴ无码中文字字幕重口|