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

天行健 君子當自強而不息

網(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 閱讀(1676) 評論(0)  編輯 收藏 引用


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


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(178)

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

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久尤物视频| 免费观看一级特黄欧美大片| 久久激五月天综合精品| 亚洲欧美999| 欧美另类综合| 欧美片在线播放| 欧美精选一区| 国产精品久久久久久久久久ktv| 欧美a级在线| 欧美精品在线免费| 国产精品毛片a∨一区二区三区|国| 国产精品国产自产拍高清av| 国产视频综合在线| 一区二区三区在线免费观看| 亚洲国产欧美一区二区三区丁香婷| 亚洲国产精品99久久久久久久久| 日韩一二三在线视频播| 欧美一区二区高清| 欧美黄色大片网站| 中文日韩电影网站| 老色鬼精品视频在线观看播放| 欧美插天视频在线播放| 欧美手机在线| 一区二区亚洲精品| 亚洲私人影院| 亚洲第一狼人社区| 99re6这里只有精品视频在线观看| 性欧美大战久久久久久久久| 欧美成人精品一区二区三区| 国产精品免费看| 亚洲黄色一区二区三区| 亚洲免费视频成人| 欧美国产精品一区| 欧美在线亚洲一区| 欧美三日本三级三级在线播放| 国产一区二区三区高清| 亚洲视频二区| 亚洲国产中文字幕在线观看| 久久久久久电影| 国产欧美日韩在线| 亚洲欧美日韩视频一区| 亚洲国产精品成人综合| 久久精品视频在线看| 欧美香蕉大胸在线视频观看| 亚洲黄色三级| 欧美不卡视频一区发布| 亚洲欧美在线另类| 国产精品乱码妇女bbbb| 亚洲视频电影图片偷拍一区| 亚洲精品小视频| 欧美大片在线观看一区| 亚洲电影视频在线| 女生裸体视频一区二区三区| 久久超碰97中文字幕| 国产精品视频一| 亚洲永久免费| 在线亚洲伦理| 国产精品成人免费视频| 亚洲视频高清| 亚洲午夜一区二区三区| 欧美视频二区36p| 亚洲一区二区三区在线播放| 亚洲精品日韩精品| 在线视频一区观看| 欧美日韩一区二区在线播放| 99精品免费视频| 99re6热在线精品视频播放速度| 欧美精品亚洲精品| 亚洲天堂av电影| 亚洲一区二区三区欧美| 国产精品日韩二区| 久久久777| 老司机精品视频网站| 91久久久久久国产精品| 欧美大色视频| 欧美屁股在线| 午夜视频久久久久久| 午夜激情综合网| 激情偷拍久久| 亚洲欧洲日本国产| 欧美视频在线观看免费| 欧美一级二级三级蜜桃| 久久精品国产免费| 亚洲精品欧美日韩专区| 日韩亚洲欧美成人| 国产欧美一区二区精品秋霞影院| 久久一区二区三区国产精品| 欧美日韩国产大片| 久久久91精品国产一区二区精品| 久久蜜臀精品av| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲视频在线播放| 国产亚洲精品自拍| 亚洲成色www8888| 久久免费视频网站| 亚洲国产一区二区三区在线播| 亚洲精品乱码久久久久久日本蜜臀 | 99v久久综合狠狠综合久久| 亚洲乱码精品一二三四区日韩在线| 欧美三区免费完整视频在线观看| 久久精精品视频| 欧美乱大交xxxxx| 久久精品国产69国产精品亚洲| 久久久久91| 亚洲欧美日韩国产综合在线| 久久香蕉精品| 欧美一区二区高清在线观看| 欧美国产另类| 久久一区二区视频| 国产精品视屏| 亚洲精品视频一区| 精品99一区二区| 亚洲午夜精品一区二区| 亚洲欧洲一区二区天堂久久 | 亚洲美女黄色| 美日韩精品视频| 国产精品久久久久久影院8一贰佰| 久久免费视频一区| 国产精品久久久久久五月尺| 91久久精品国产91久久| 在线成人h网| 午夜精品一区二区三区在线播放| 亚洲乱码国产乱码精品精98午夜| 欧美自拍偷拍午夜视频| 亚洲专区欧美专区| 欧美日韩三区| 亚洲日本va午夜在线电影| 亚洲国产一区二区三区在线播| 欧美一区国产二区| 午夜久久一区| 欧美系列精品| 在线视频精品一区| 亚洲最新在线| 欧美精品久久久久久久久老牛影院| 蜜臀va亚洲va欧美va天堂| 国产丝袜美腿一区二区三区| 一本久道综合久久精品| 在线视频欧美一区| 欧美午夜精品久久久久久浪潮| 亚洲精品色婷婷福利天堂| 99国产麻豆精品| 欧美日韩免费视频| 一本久道久久久| 亚洲尤物精选| 国产女优一区| 久久国产精品亚洲va麻豆| 久久久久久久久综合| 韩日欧美一区二区| 蜜乳av另类精品一区二区| 亚洲经典自拍| 午夜精品国产更新| 国产婷婷精品| 美女日韩欧美| 日韩亚洲欧美综合| 亚洲永久精品国产| 国产在线成人| 欧美大片18| 亚洲私人影吧| 狂野欧美激情性xxxx| 亚洲精品久久久久久久久| 欧美日韩一区综合| 小处雏高清一区二区三区| 久久全国免费视频| 亚洲日本电影在线| 国产精品va在线播放| 久久成人羞羞网站| 欧美国产视频在线观看| 妖精视频成人观看www| 国产精品久久久久久久久借妻| 欧美在线观看视频一区二区三区| 你懂的网址国产 欧美| 亚洲毛片在线看| 国产欧美一区二区精品性| 久久综合久久综合九色| 在线视频欧美精品| 美女主播一区| 亚洲欧美日韩一区在线| 一区免费在线| 国产精品国产三级国产专区53| 欧美激情按摩在线| 亚洲女性裸体视频| 亚洲国产欧美一区| 国产欧美日韩免费| 欧美国产日本在线| 欧美一区二区三区精品| 最近看过的日韩成人| 国产婷婷成人久久av免费高清 | 欧美日韩国产区一| 欧美一区二区三区免费在线看| 亚洲人成欧美中文字幕| 久久精品国产2020观看福利| 一区二区三区国产在线观看| 狠狠色伊人亚洲综合网站色| 欧美午夜精品| 欧美精品在线一区二区三区| 久久久亚洲一区| 亚洲欧美中文字幕| 日韩午夜视频在线观看| 欧美激情亚洲另类| 欧美成人免费全部|