青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

網格模型高級技術(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 閱讀(1676) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            在线观看欧美日本| 一区二区三区久久久| 韩曰欧美视频免费观看| 欧美ed2k| 久久久久一区二区三区| 欧美主播一区二区三区美女 久久精品人 | 欧美午夜欧美| 久久综合给合| 久久精品成人一区二区三区蜜臀| 欧美+亚洲+精品+三区| 91久久精品国产91久久| 国产精品久久777777毛茸茸| 欧美精品乱人伦久久久久久| 久久天天躁狠狠躁夜夜爽蜜月| 欧美一区二区三区四区高清| 亚洲综合久久久久| 性欧美1819性猛交| 香蕉国产精品偷在线观看不卡| 亚洲自拍都市欧美小说| 亚洲男女自偷自拍图片另类| 久久九九免费视频| 欧美日韩中文| 亚洲风情亚aⅴ在线发布| 亚洲视频视频在线| 欧美成人午夜免费视在线看片| 亚洲精品视频在线观看免费| 亚洲欧美日韩在线一区| 欧美国产高清| 国产揄拍国内精品对白| 在线亚洲一区| 美女视频黄 久久| 亚洲线精品一区二区三区八戒| 久久午夜视频| 国产一区二区三区无遮挡| 一本久久综合亚洲鲁鲁| 另类欧美日韩国产在线| 亚洲天堂第二页| 欧美激情一区二区三区| 亚洲一区欧美一区| 欧美日韩精品二区| 亚洲国产精品电影在线观看| 午夜精品久久久久久久99樱桃| 欧美国产日韩亚洲一区| 亚洲性视频网站| 欧美大秀在线观看| 精品白丝av| 久久av一区| 一区二区三区欧美亚洲| 欧美国产视频一区二区| 亚洲国产另类久久精品| 久久精品视频在线| 亚洲欧美日韩在线综合| 国产精品久久99| 中文在线一区| aa国产精品| 国产精品国产三级国产普通话蜜臀| 亚洲精品一区在线观看| 亚洲国产视频一区二区| 另类成人小视频在线| 尤物在线精品| 欧美高清视频一区二区| 欧美77777| 在线一区二区日韩| 在线不卡欧美| 欧美激情精品| 欧美日产国产成人免费图片| 一区二区三区四区国产| 日韩一区二区精品在线观看| 欧美精品一区二区三区蜜桃| 亚洲一区二区三区777| 亚洲神马久久| 国产视频一区在线观看一区免费| 久久不射网站| 麻豆成人在线观看| 一本综合久久| 亚洲欧美日韩天堂| 一区在线免费| 亚洲国产片色| 国产精品入口福利| 美女精品视频一区| 欧美日韩国产色视频| 欧美一级专区| 久久久蜜桃一区二区人| 日韩亚洲欧美在线观看| 亚洲一区二区三区激情| 精品成人一区二区| 日韩视频一区二区三区在线播放| 国产精品一二三视频| 美日韩精品免费| 欧美日韩国产综合一区二区| 久久se精品一区二区| 欧美www视频在线观看| 亚洲一区在线播放| 久久久亚洲国产天美传媒修理工| 日韩视频一区二区三区在线播放免费观看| 亚洲欧洲在线观看| 国产视频一区二区在线观看| 亚洲韩国青草视频| 国产日韩欧美在线一区| 91久久精品美女高潮| 国产女人精品视频| 亚洲国产婷婷香蕉久久久久久99| 国产精品五月天| 午夜欧美大尺度福利影院在线看| 欧美日韩在线一区| 蜜乳av另类精品一区二区| 欧美日一区二区三区在线观看国产免 | 美女视频一区免费观看| 欧美日韩在线播放三区| 美女精品在线| 国产精品一区在线观看你懂的 | 性18欧美另类| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久都是精品| 亚洲欧美国产制服动漫| 欧美黄色aa电影| 噜噜噜久久亚洲精品国产品小说| 国产精品热久久久久夜色精品三区| 亚洲国产日韩美| 在线播放日韩| 欧美一级久久| 欧美呦呦网站| 国产精品三上| 亚洲一区二区三区在线| 亚洲自拍三区| 国产精品日韩精品欧美在线| 一本久道久久综合中文字幕| 9久草视频在线视频精品| 免费看黄裸体一级大秀欧美| 久久夜色撩人精品| 狠狠色狠狠色综合| 欧美在线观看视频一区二区| 亚洲欧美在线高清| 欧美午夜理伦三级在线观看| 亚洲免费电影在线观看| 亚洲日本欧美日韩高观看| 久久野战av| 欧美不卡视频一区| 亚洲国产精品v| 欧美激情亚洲自拍| 999在线观看精品免费不卡网站| 米奇777在线欧美播放| 久久漫画官网| 在线观看国产成人av片| 久久裸体艺术| 欧美 日韩 国产一区二区在线视频 | 亚洲国产精品一区二区www在线| 亚洲国产一区二区三区青草影视| 久久精品99国产精品日本| 久久夜色精品国产噜噜av| 亚洲第一天堂无码专区| 欧美不卡视频一区发布| 亚洲精品欧美日韩专区| 亚洲欧美成aⅴ人在线观看| 国产精品专区h在线观看| 午夜精品久久久久久久| 快she精品国产999| 日韩亚洲视频在线| 欧美亚州一区二区三区| 欧美亚洲午夜视频在线观看| 久久伊伊香蕉| 99精品久久免费看蜜臀剧情介绍| 欧美日韩系列| 亚洲深夜影院| 免费观看欧美在线视频的网站| 欧美激情一区二区三区在线视频 | 午夜精品福利在线| 国产亚洲综合精品| 久热综合在线亚洲精品| 亚洲免费成人av| 久久久999精品免费| 亚洲国产婷婷综合在线精品 | 欧美在线视频在线播放完整版免费观看 | 韩日视频一区| 欧美日韩国产不卡在线看| 亚洲在线观看免费| 亚洲高清中文字幕| 性欧美精品高清| 亚洲欧洲精品一区二区三区波多野1战4| 欧美精品久久99| 久久国产视频网站| 一本色道88久久加勒比精品| 另类酷文…触手系列精品集v1小说| 99在线精品视频| 激情久久久久久| 国产精品久久久久久久久久ktv | 国产一区二区观看| 欧美精品乱码久久久久久按摩| 欧美一区二区三区视频| 一区二区三区视频观看| 欧美成人免费视频| 久久久www免费人成黑人精品| 一个色综合导航| 亚洲区一区二区三区| 国外精品视频| 国产色产综合产在线视频| 欧美私人网站| 欧美精品自拍偷拍动漫精品| 麻豆精品一区二区综合av| 欧美自拍丝袜亚洲|