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

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

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

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

對(duì)于程序員而言,對(duì)網(wǎng)格模型進(jìn)行優(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.

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

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

接著我們以三種方式對(duì)原始網(wǎng)格模型進(jìn)行了優(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() );
}

運(yùn)行效果圖:

 

主程序:

#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 閱讀(1679) 評(píng)論(0)  編輯 收藏 引用


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


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

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

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久一区二区精品| 国产精品99久久久久久宅男 | 欧美激情视频在线免费观看 欧美视频免费一 | 欧美一级久久久| 亚洲日本欧美| 精品999网站| 国产日韩欧美在线观看| 欧美日韩中文字幕日韩欧美| 欧美成人午夜剧场免费观看| 久久久久一区二区三区| 午夜精品久久久久久| 一本综合久久| aa级大片欧美三级| 亚洲三级电影全部在线观看高清| 美女视频一区免费观看| 久久频这里精品99香蕉| 久久不射中文字幕| 性欧美8khd高清极品| 亚洲在线观看免费| 亚洲一区二区三区乱码aⅴ| 99re热精品| av成人免费观看| 亚洲精选成人| 亚洲伦理在线免费看| 亚洲三级性片| 日韩视频在线免费| 日韩写真视频在线观看| 亚洲久久一区二区| 日韩一二三在线视频播| 99人久久精品视频最新地址| 亚洲精品亚洲人成人网| 亚洲美女毛片| 一区二区三区欧美成人| 亚洲一区二区三区乱码aⅴ蜜桃女| aa级大片欧美三级| 亚洲视频中文字幕| 亚洲欧美日韩在线播放| 先锋影音国产精品| 久久大逼视频| 免费av成人在线| 欧美黄色日本| 亚洲精品一区中文| 亚洲图色在线| 午夜久久久久| 玖玖精品视频| 欧美日韩国产综合网| 国产精品爱啪在线线免费观看| 国产精品久久午夜夜伦鲁鲁| 国产日韩欧美在线播放不卡| 在线观看国产成人av片| 亚洲美女毛片| 亚洲欧美制服另类日韩| 久久久久9999亚洲精品| 欧美v国产在线一区二区三区| 亚洲国产高清aⅴ视频| 一本色道**综合亚洲精品蜜桃冫 | 久久狠狠亚洲综合| 久久久天天操| 亚洲国产裸拍裸体视频在线观看乱了| 99v久久综合狠狠综合久久| 亚洲欧美日韩国产综合| 久久久久久欧美| 欧美屁股在线| 国产伪娘ts一区| 亚洲精品乱码久久久久久久久| 中文久久乱码一区二区| 久久久久久穴| 日韩亚洲欧美成人一区| 欧美在线不卡视频| 欧美日韩国产一级片| 国产色综合天天综合网| 亚洲伦伦在线| 久久久久久97三级| 亚洲日本中文字幕区| 午夜久久久久久久久久一区二区| 欧美.com| 国产一区二区丝袜高跟鞋图片 | 亚洲精品国久久99热| 午夜欧美大片免费观看| 免费观看国产成人| 一区二区三区 在线观看视频| 久久精品日产第一区二区三区| 欧美日韩精品免费| 在线精品福利| 久久www免费人成看片高清| 亚洲黄色在线视频| 欧美一区亚洲| 国产精品成人av性教育| 亚洲激情不卡| 久久久久久久一区二区| 一本到12不卡视频在线dvd| 老**午夜毛片一区二区三区| 国产精品一二| 一区二区三区不卡视频在线观看| 另类天堂视频在线观看| 亚洲欧美一区二区三区极速播放 | 女人香蕉久久**毛片精品| 国产欧美一区二区三区另类精品| 99成人在线| 免费在线观看一区二区| 午夜宅男久久久| 国产精品扒开腿做爽爽爽视频 | 亚洲欧洲99久久| 欧美日韩情趣电影| 91久久国产综合久久| 狼人社综合社区| 亚洲欧美激情在线视频| 欧美视频在线观看免费| 99ri日韩精品视频| 亚洲国产精品成人精品| 久久理论片午夜琪琪电影网| 国产资源精品在线观看| 久久av一区二区三区| 亚洲一区二区三区777| 欧美视频精品在线观看| 一区二区三区av| 日韩视频免费观看| 欧美精品成人一区二区在线观看 | 日韩图片一区| 亚洲第一在线综合网站| 美女主播视频一区| 亚洲国产精品一区二区尤物区| 久久午夜影视| 久久久久久尹人网香蕉| 精品成人国产| 欧美大学生性色视频| 蜜桃精品一区二区三区 | 久久精品视频播放| 午夜视频一区在线观看| 国产欧美1区2区3区| 久久激情视频免费观看| 香蕉国产精品偷在线观看不卡 | 亚洲国产欧美久久| 欧美成人精品一区| 日韩网站免费观看| 一区二区欧美日韩| 国产精品v亚洲精品v日韩精品| 亚洲欧美中文日韩在线| 亚洲欧美日韩高清| 国语自产精品视频在线看8查询8| 久久在线免费| 模特精品在线| 亚洲视频在线视频| 亚洲一区在线直播| 韩国久久久久| 亚洲韩国日本中文字幕| 欧美三级乱码| 久久精品国产77777蜜臀| 久久久亚洲国产天美传媒修理工| 亚洲国产三级网| 99国产精品久久久| 国产视频久久网| 欧美韩日高清| 欧美三级视频在线| 久久精品观看| 欧美国产日本| 欧美一级一区| 久久噜噜噜精品国产亚洲综合| 日韩午夜av| 欧美一区二区日韩| 亚洲激情亚洲| 亚洲一区二区不卡免费| 尹人成人综合网| 一区二区av| 亚洲成色777777女色窝| 99精品视频一区二区三区| 国内精品久久久久影院色| 亚洲欧洲精品一区二区精品久久久 | 免费av成人在线| 欧美天天影院| 噜噜噜久久亚洲精品国产品小说| 欧美精品自拍| 久久久久成人精品| 欧美破处大片在线视频| 久久国内精品视频| 欧美精品网站| 久久亚洲美女| 国产精品久久久久9999高清| 牛人盗摄一区二区三区视频| 国产精品久久久久婷婷| 欧美风情在线观看| 国产日韩一区二区三区在线| 亚洲国产一区二区精品专区| 国产一级久久| 一本一本a久久| 亚洲精品国精品久久99热一| 欧美一区二区三区日韩| 亚洲手机在线| 欧美91视频| 久久全球大尺度高清视频| 欧美日韩亚洲一区二区三区四区| 免费av成人在线| 国产欧美日韩三级| 艳妇臀荡乳欲伦亚洲一区| 91久久精品国产91久久| 欧美在线播放一区| 亚洲欧美精品在线观看| 欧美日韩国产成人在线免费| 欧美高潮视频| 激情综合激情|