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

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

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

層次細(xì)節(jié)網(wǎng)格模型(progress mesh)是一種特殊的網(wǎng)格模型,它的頂點(diǎn)數(shù)據(jù)以樹狀形式組織,可以隨意增加或降低模型的復(fù)雜程度,從而比普通的網(wǎng)格模型具有更大的靈活性,層次細(xì)節(jié)網(wǎng)格模型對(duì)于層次細(xì)節(jié)場(chǎng)景的渲染非常理想。當(dāng)模型距離觀察者較遠(yuǎn)時(shí)可以降低模型的復(fù)雜程度,提高渲染速度。而當(dāng)模型距離觀察者較近時(shí)可以使用復(fù)雜的模型,從而提高視覺效果。Direct3D用ID3DXPMesh來表示層次細(xì)節(jié)網(wǎng)格模型對(duì)象,而不是ID3DXMesh。

層次細(xì)節(jié)網(wǎng)格模型是根據(jù)原始普通網(wǎng)格模型生成的,在生成層次細(xì)節(jié)網(wǎng)格模型之前,首先需要對(duì)原始網(wǎng)格模型進(jìn)行相關(guān)處理,包括整理、頂點(diǎn)融合、檢查3個(gè)步驟。

在調(diào)用函數(shù)D3DXLoadMeshFromX()生成網(wǎng)格模型后,調(diào)用Direct3D功能函數(shù)D3DXCleanMesh()對(duì)初始網(wǎng)格模型進(jìn)行整理,其聲明如下:

Cleans a mesh, preparing it for simplification.

HRESULT D3DXCleanMesh(
D3DXCLEANTYPE CleanType,
LPD3DXMESH pMeshIn,
CONST DWORD * pAdjacencyIn,
LPD3DXMESH * ppMeshOut,
DWORD * pAdjacencyOut,
LPD3DXBUFFER * ppErrorsAndWarnings
);

Parameters

CleanType
[in] Vertex operations to perform in preparation for mesh cleaning.
pMeshIn
[in] Pointer to an ID3DXMesh interface, representing the mesh to be cleaned.
pAdjacencyIn
[in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the mesh to be cleaned.
ppMeshOut
[out] Address of a pointer to an ID3DXMesh interface, representing the returned cleaned mesh. The same mesh is returned that was passed in if no cleaning was necessary.
pAdjacencyOut
[out] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the output mesh.
ppErrorsAndWarnings
[out] Returns a buffer containing a string of errors and warnings, which explain the problems found in the mesh.

Return Values

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

Remarks

This function cleans a mesh using the cleaning method and options specified in the CleanType parameter. See the D3DXCLEANTYPE enumeration for a description of the available options.

枚舉常量D3DXCLEANTYPE的定義如下:

Defines operations to perform on vertices in preparation for mesh cleaning.

typedef enum D3DXCLEANTYPE
{
D3DXCLEAN_BACKFACING = 1,
D3DXCLEAN_BOWTIES = 2,
D3DXCLEAN_SKINNING = D3DXCLEAN_BACKFACING,
D3DXCLEAN_OPTIMIZATION = D3DXCLEAN_BACKFACING,
D3DXCLEAN_SIMPLIFICATION = D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES,
} D3DXCLEANTYPE, *LPD3DXCLEANTYPE;

Constants

D3DXCLEAN_BACKFACING
Merge triangles that share the same vertex indices but have face normals pointing in opposite directions (back-facing triangles). Unless the triangles are not split by adding a replicated vertex, mesh adjacency data from the two triangles may conflict.
D3DXCLEAN_BOWTIES
If a vertex is the apex of two triangle fans (a bowtie) and mesh operations will affect one of the fans, then split the shared vertex into two new vertices. Bowties can cause problems for operations such as mesh simplification that remove vertices, because removing one vertex affects two distinct sets of triangles.
D3DXCLEAN_SKINNING
Use this flag to prevent infinite loops during skinning setup mesh operations.
D3DXCLEAN_OPTIMIZATION
Use this flag to prevent infinite loops during mesh optimization operations.
D3DXCLEAN_SIMPLIFICATION
Use this flag to prevent infinite loops during mesh simplification operations.

通常選擇D3DXCLEAN_SIMPLIFICATION,這樣既可以將共享相同頂點(diǎn)且面法向量不在同一方向的三角形進(jìn)行合并,同時(shí)還可以避免在簡(jiǎn)化網(wǎng)格的操作中陷入死循環(huán)。

在整理好網(wǎng)格模型后,調(diào)用函數(shù)D3DXWeldVertices()將網(wǎng)格模型中屬性相同的重復(fù)頂點(diǎn)溶合到一起,從而簡(jiǎn)化網(wǎng)格模型,其聲明如下:

Welds together replicated vertices that have equal attributes. This method uses specified epsilon values for equality comparisons.

HRESULT D3DXWeldVertices(
LPD3DXMESH pMesh,
DWORD Flags,
CONST D3DXWeldEpsilons * pEpsilons,
CONST DWORD * pAdjacencyIn,
DWORD * pAdjacencyOut,
DWORD * pFaceRemap,
LPD3DXBUFFER * ppVertexRemap
);

Parameters

pMesh
[in] Pointer to an ID3DXMesh object, the mesh from which to weld vertices.
Flags
[in] Combination of one or more flags from D3DXWeldEpsilonsFLAGS.
pEpsilons
[in] Pointer to a D3DXWeldEpsilons structure, specifying the epsilon values to be used for this method. Use NULL to initialize all structure members to a default value of 1.0e-6f.
pAdjacencyIn
[in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the source mesh. If the edge has no adjacent faces, the value is 0xffffffff. If this parameter is set to NULL, ID3DXBaseMesh::GenerateAdjacency will be called to create logical adjacency information.
pAdjacencyOut
[in, out] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the optimized mesh. If the edge has no adjacent faces, the value is 0xffffffff.
pFaceRemap
[out] An array of DWORDs, one per face, that identifies the original mesh face that corresponds to each face in the welded mesh.
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.

Return Values

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

Remarks

This function uses supplied adjacency information to determine the points that are replicated. Vertices are merged based on an epsilon comparison. Vertices with equal position must already have been calculated and represented by point-representative data.

This function combines logically-welded vertices that have similar components, such as normals or texture coordinates within pEpsilons.

The following example code calls this function with welding enabled. Vertices are compared using epsilon values for normal vector and vertex position. A pointer is returned to a face remapping array (pFaceRemap).

TCHAR            strMediaPath[512];       // X-file path 
LPD3DXBUFFER pAdjacencyBuffer = NULL; // adjacency data buffer
LPD3DXBUFFER pD3DXMtrlBuffer = NULL; // material buffer
LPD3DXMESH pMesh = NULL; // mesh object
DWORD m_dwNumMaterials; // number of materials
D3DXWELDEPSILONS Epsilons; // structure with epsilon values
DWORD *pFaceRemap[65536]; // face remapping array
DWORD i; // internal variable

// Load the mesh from the specified file
hr = D3DXLoadMeshFromX ( strMediaPath,
D3DXMESH_MANAGED,
m_pd3dDevice,
&pAdjacencyBuffer,
&pD3DXMtrlBuffer,
NULL,
&m_dwNumMaterials,
&pMesh ) )

if( FAILED( hr ) )
goto End; // Go to error handling

// Set epsilon values
Epsilons.Normal = 0.001;
Epsilons.Position = 0.1;

// Weld the vertices
for( i=0; i < 65536; i++ )
{
pFaceRemap[i] = 0;
}

hr = D3DXWeldVertices ( pMesh,
D3DXWELDEPSILONS_WELDPARTIALMATCHES,
&Epsilons,
(DWORD*)pAdjacencyBuffer->GetBufferPointer(),
(DWORD*)pAdjacencyBuffer->GetBufferPointer(),
(DWORD*)pFaceRemap,
NULL )

if( FAILED( hr ) )
goto End; // Go to error handling

D3DXWeldEpsilonsFLAGS的定義如下:

Options for welding together vertices.

typedef enum D3DXWeldEpsilonsFLAGS
{
D3DXWeldEpsilons_WELDALL = 1,
D3DXWeldEpsilons_WELDPARTIALMATCHES = 2,
D3DXWeldEpsilons_DONOTREMOVEVERTICES = 4,
D3DXWeldEpsilons_DONOTSPLIT = 8,
} D3DXWeldEpsilonsFLAGS, *LPD3DXWeldEpsilonsFLAGS;

Constants

D3DXWeldEpsilons_WELDALL
Weld together all vertices that are at the same location. Using this flag avoids an epsilon comparison between vertex components.
D3DXWeldEpsilons_WELDPARTIALMATCHES
If a given vertex component is within epsilon, modify partially matched vertices so that both components are identical. If all components are equal, remove one of the vertices.
D3DXWeldEpsilons_DONOTREMOVEVERTICES
Instructs the weld to allow only modifications to vertices and not removal. This flag is valid only if D3DXWeldEpsilons_WELDPARTIALMATCHES is set. It is useful to modify vertices to be equal, but not to allow vertices to be removed.
D3DXWeldEpsilons_DONOTSPLIT
Instructs the weld not to split vertices that are in separate attribute groups. When the ID3DXMesh::Optimize, ID3DXPMesh::Optimize, or ID3DXPMesh::OptimizeBaseLOD methods are called with the D3DXMESHOPT_ATTRSORT flag, then the D3DXMESHOPT_DONOTSPLIT flag will also be set. Setting this flag can slow down software vertex processing.

D3DXWeldEpsilons的定義如下:

Specifies tolerance values for each vertex component when comparing vertices to determine if they are similar enough to be welded together.

typedef struct D3DXWeldEpsilons {
FLOAT Position;
FLOAT BlendWeights;
FLOAT Normal;
FLOAT PSize;
FLOAT Specular;
FLOAT Diffuse;
FLOAT Texcoord[8];
FLOAT Tangent;
FLOAT Binormal;
FLOAT Tess Factor;
} D3DXWeldEpsilons, *LPD3DXWeldEpsilons;

Members

Position
Position
BlendWeights
Blend weight
Normal
Normal
PSize
Point size value
Specular
Specular lighting value
Diffuse
Diffuse lighting value
Texcoord
Eight texture coordinates
Tangent
Tangent
Binormal
Binormal
Tess Factor
Tessellation factor

Remarks

The LPD3DXWeldEpsilons type is defined as a pointer to the D3DXWeldEpsilons structure.

typedef D3DXWELDEPSILONS *LPD3DXWELDEPSILONS;

對(duì)原始網(wǎng)格模型進(jìn)行整理、簡(jiǎn)化之后,還需要檢查處理后的網(wǎng)格模型是否有效,檢查工作由函數(shù)D3DXValidMesh()完成,其聲明如下:

Validates a mesh.

HRESULT D3DXValidMesh(
LPD3DXMESH pMeshIn,
CONST DWORD * pAdjacency,
LPD3DXBUFFER * ppErrorsAndWarnings
);

Parameters

pMeshIn
[in] Pointer to an ID3DXMesh interface, representing the mesh to be tested.
pAdjacency
[in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the mesh to be tested.
ppErrorsAndWarnings
[out] Returns a buffer containing a string of errors and warnings, which explain the problems found in the mesh.

Return Values

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

Remarks

This method validates the mesh by checking for invalid indices. Error information is available from the debugger output.

在上面的準(zhǔn)備工作完成后,可以調(diào)用函數(shù)D3DXGeneratePMesh()根據(jù)初始網(wǎng)格模型生成層次細(xì)節(jié)網(wǎng)格模型,其聲明如下:

Generates a progressive mesh.

HRESULT D3DXGeneratePMesh(
LPD3DXMESH pMesh,
CONST DWORD * pAdjacency,
CONST D3DXATTRIBUTEWEIGHTS * pVertexAttributeWeights,
CONST FLOAT * pVertexWeights,
DWORD MinValue,
DWORD Options,
LPD3DXPMESH * ppPMesh
);

Parameters

pMesh
[in] Pointer to an ID3DXMesh interface, representing the source mesh.
pAdjacency
[in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the created progressive mesh.
pVertexAttributeWeights
[in] Pointer to a D3DXATTRIBUTEWEIGHTS structure, containing the weight for each vertex component. If this parameter is set to NULL, a default structure is used. See Remarks.
pVertexWeights
[in] Pointer to an array of vertex weights. If this parameter is set to NULL, all vertex weights are set to 1.0. Note that the higher the vertex weight for a given vertex, the less likely it is to be simplified away.
MinValue
[in] Number of vertices or faces, depending on the flag set in the Options parameter, by which to simplify the source mesh.
Options
[in] Specifies simplification options for the mesh. One flag from the D3DXMESHSIMP enumeration can be set.
ppPMesh
[out] Address of a pointer to an ID3DXPMesh interface, representing the created progressive mesh.

Return Values

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

Remarks

This function generates a mesh where the level of detail (LOD) can be adjusted from the current value to the MinValue.

If the simplification process cannot reduce the mesh to MinValue, the call still succeeds because MinValue is a desired minimum, not an absolute minimum.

If pVertexAttributeWeights is set to NULL, the following values are assigned to the default D3DXATTRIBUTEWEIGHTS structure.

D3DXATTRIBUTEWEIGHTS AttributeWeights;

AttributeWeights.Position = 1.0;
AttributeWeights.Boundary = 1.0;
AttributeWeights.Normal = 1.0;
AttributeWeights.Diffuse = 0.0;
AttributeWeights.Specular = 0.0;
AttributeWeights.Tex[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

This default structure is what most applications should use because it considers only geometric and normal adjustment. Only in special cases will the other member fields need to be modified.

D3DXMESHSIMP的定義如下:

Specifies simplification options for a mesh.

typedef enum D3DXMESHSIMP
{
D3DXMESHSIMP_VERTEX = 1,
D3DXMESHSIMP_FACE = 2,
} D3DXMESHSIMP, *LPD3DXMESHSIMP;

Constants

D3DXMESHSIMP_VERTEX
The mesh will be simplified by the number of vertices specified in the MinValue parameter.
D3DXMESHSIMP_FACE
The mesh will be simplified by the number of faces specified in the MinValue parameter.

參數(shù)MinValue設(shè)置的最小頂點(diǎn)數(shù)只是一個(gè)期望值,實(shí)際生成的層次細(xì)節(jié)網(wǎng)格模型的最小頂點(diǎn)數(shù)量可能大于設(shè)置的最小頂點(diǎn)數(shù)量。

 

示例程序ProgressMesh的具體實(shí)現(xiàn)

示例程序演示了層次細(xì)節(jié)網(wǎng)格模型的生成和渲染,其中加載原始網(wǎng)格模型、簡(jiǎn)化熔合原始網(wǎng)格并生成層次細(xì)節(jié)網(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();
ID3DXMesh* cleaned_mesh;
DWORD* adj = (DWORD*) g_adj_buffer->GetBufferPointer();
V_RETURN(D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, g_mesh, adj, &cleaned_mesh, adj, NULL));
release_com(g_mesh);
g_mesh = cleaned_mesh;
D3DXWELDEPSILONS weld_epsilons;
ZeroMemory(&weld_epsilons, sizeof(D3DXWELDEPSILONS));
V_RETURN(D3DXWeldVertices(g_mesh, D3DXWELDEPSILONS_WELDPARTIALMATCHES, &weld_epsilons, adj, adj, NULL, NULL));
V_RETURN(D3DXValidMesh(g_mesh, adj, NULL));
V_RETURN(D3DXGeneratePMesh(g_mesh, adj, NULL, NULL, 1, D3DXMESHSIMP_VERTEX, &g_progress_mesh));

 

運(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 IDC_DETAIL                4

#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;
CDXUTDialog                    g_ui_dlg;

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

//--------------------------------------------------------------------------------------
// 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();
    
    ID3DXMesh
* cleaned_mesh;
    DWORD
* adj = (DWORD*) g_adj_buffer->GetBufferPointer();

    V_RETURN(D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, g_mesh, adj, 
&cleaned_mesh, adj, NULL));
    release_com(g_mesh);

    g_mesh 
= cleaned_mesh;

    D3DXWELDEPSILONS weld_epsilons;
    ZeroMemory(
&weld_epsilons, sizeof(D3DXWELDEPSILONS));
    V_RETURN(D3DXWeldVertices(g_mesh, D3DXWELDEPSILONS_WELDPARTIALMATCHES, 
&weld_epsilons, adj, adj, NULL, NULL));

    V_RETURN(D3DXValidMesh(g_mesh, adj, NULL));
    V_RETURN(D3DXGeneratePMesh(g_mesh, adj, NULL, NULL, 
1, D3DXMESHSIMP_VERTEX, &g_progress_mesh));

    DWORD min_vertices 
= g_progress_mesh->GetMinVertices();
    DWORD max_vertices 
= g_progress_mesh->GetMaxVertices();

    g_ui_dlg.GetSlider(IDC_DETAIL)
->SetRange(min_vertices, max_vertices);
    g_ui_dlg.GetSlider(IDC_DETAIL)
->SetValue(max_vertices);
    g_progress_mesh
->SetNumVertices(max_vertices);

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

    g_ui_dlg.SetLocation(
0, pBackBufferSurfaceDesc->Height - 60);
    g_ui_dlg.SetSize(pBackBufferSurfaceDesc
->Width, 50);
    g_ui_dlg.GetControl(IDC_DETAIL)
->SetSize(pBackBufferSurfaceDesc->Width - 2016);

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

//--------------------------------------------------------------------------------------
// 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.DrawFormattedTextLine(L
"Vertices Range: %u ~ %u\nCurrent Vertices Number: %u\n",
                                      g_progress_mesh
->GetMinVertices(),
                                      g_progress_mesh
->GetMaxVertices(),
                                      g_progress_mesh
->GetNumVertices());

    
// 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");
    }
    
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]);
            g_progress_mesh
->DrawSubset(i);
        }        

        RenderText();
        V(g_button_dlg.OnRender(fElapsedTime));
        V(g_ui_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;

    
*pbNoFurtherProcessing = g_ui_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;
        }
    }
}

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

    
case IDC_DETAIL:
        g_progress_mesh
->SetNumVertices( ((CDXUTSlider*) control)->GetValue() );
    }
}

//--------------------------------------------------------------------------------------
// Initialize dialogs
//--------------------------------------------------------------------------------------
void InitDialogs()
{
    g_settings_dlg.Init(
&g_dlg_resource_manager);
    g_button_dlg.Init(
&g_dlg_resource_manager);
    g_ui_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);

    g_ui_dlg.SetCallback(OnGUIEvent);
    g_ui_dlg.AddSlider(IDC_DETAIL, 
103620016444);
}

//--------------------------------------------------------------------------------------
// 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"ProgressMesh" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, 
true640480, IsDeviceAcceptable, ModifyDeviceSettings );

    
// Start the render loop
    DXUTMainLoop();

    
// TODO: Perform any application-level cleanup here

    
return DXUTGetExitCode();
}

 

下載示例工程(僅包含工程文件和源碼,不包含資源文件,資源請(qǐng)從示例程序OptimizedMesh中提取)


posted on 2008-05-27 20:16 lovedday 閱讀(2130) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(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>
            久久综合999| 久久久久99| 国内成人精品2018免费看| 国产精品视频xxx| 国产精品一区二区三区久久| 国产区日韩欧美| 狠狠久久综合婷婷不卡| 亚洲国产婷婷综合在线精品| 一区二区欧美在线观看| 午夜精品影院在线观看| 久久精品系列| 亚洲精品欧美极品| 香蕉久久夜色| 欧美女人交a| 国产日韩精品一区二区| 亚洲日本成人网| 午夜欧美大尺度福利影院在线看 | 国产精品久久| 好吊视频一区二区三区四区| 亚洲国产精选| 性做久久久久久| 亚洲二区视频在线| 亚洲精品美女在线| 欧美在线视频网站| 欧美日韩国产成人| 黑人一区二区| 亚洲欧美欧美一区二区三区| 另类酷文…触手系列精品集v1小说| 亚洲国内自拍| 久久国产手机看片| 欧美日韩一区二区三区在线看| 黄色成人在线网站| 亚洲一区二区三区四区中文| 久久一区国产| 亚洲欧美美女| 欧美另类久久久品| 亚洲第一在线视频| 久久久综合免费视频| 亚洲综合国产激情另类一区| 久久久久免费视频| 国产精品久久一区主播| 亚洲三级色网| 免费在线视频一区| 久久激情视频久久| 亚洲第一成人在线| 久久av最新网址| 国产欧美日韩专区发布| 亚洲午夜伦理| 亚洲每日更新| 欧美日韩国产成人| 99精品国产福利在线观看免费| 免费一级欧美在线大片| 久久国产精品72免费观看| 国产情侣久久| 久久成人羞羞网站| 午夜精品久久久久久久男人的天堂| 欧美午夜精品久久久| 一区二区三区日韩精品视频| 亚洲日本理论电影| 欧美国产另类| 一区二区三区产品免费精品久久75 | 久久尤物电影视频在线观看| 午夜精品在线观看| 国产亚洲第一区| 久久国产一区| 久久久久高清| 亚洲肉体裸体xxxx137| 91久久综合| 欧美偷拍一区二区| 欧美一区二区在线| 久久精品一区二区国产| 亚洲精华国产欧美| 亚洲人成网站在线播| 欧美香蕉大胸在线视频观看| 性娇小13――14欧美| 欧美专区在线| 亚洲欧洲精品天堂一级| 亚洲免费av网站| 国产一区二区电影在线观看| 久久亚洲综合网| 欧美不卡激情三级在线观看| 一区二区三区视频免费在线观看| 中文欧美日韩| 一区二区三区在线视频观看| 亚洲激情av在线| 国产精品日韩电影| 欧美国产视频在线| 国产精品久久一级| 欧美韩日视频| 国产精品青草综合久久久久99| 久久综合一区| 欧美性片在线观看| 麻豆91精品91久久久的内涵| 欧美日韩国产成人精品| 久久美女性网| 欧美丝袜一区二区| 亚洲麻豆视频| 久久婷婷激情| 亚洲午夜av在线| 欧美在线综合| 亚洲视频成人| 久久久久久久成人| 在线视频你懂得一区二区三区| 欧美在线视频免费播放| 亚洲午夜激情网站| 美女黄毛**国产精品啪啪| 午夜精品一区二区三区四区| 噜噜噜躁狠狠躁狠狠精品视频 | 亚洲国产日韩欧美在线图片| 亚洲无线一线二线三线区别av| 伊人成人网在线看| 亚洲午夜精品久久久久久app| 亚洲日本成人| 久久精品夜色噜噜亚洲a∨| 亚洲字幕一区二区| 欧美激情一区在线观看| 男男成人高潮片免费网站| 国产日韩亚洲欧美| 亚洲五月六月| 亚洲专区一区| 欧美日韩高清免费| 亚洲破处大片| 亚洲精品国精品久久99热一| 欧美综合第一页| 久久av一区二区| 国产精品永久入口久久久| 99在线热播精品免费| 一本色道久久综合狠狠躁的推荐| 久久综合999| 牛牛精品成人免费视频| 狠狠综合久久av一区二区小说 | 亚洲一区二区三区777| 在线视频精品一区| 欧美视频福利| 亚洲最新视频在线播放| 亚洲色诱最新| 国产精品久久久久久久久免费樱桃| 日韩午夜视频在线观看| 中文有码久久| 国产精品成人一区二区| 99国内精品久久| 亚洲一区三区在线观看| 欧美日韩亚洲一区| 亚洲午夜电影在线观看| 性做久久久久久久免费看| 国产精品永久| 久久男人资源视频| 亚洲黄色免费网站| 亚洲美女精品久久| 欧美偷拍一区二区| 午夜伦理片一区| 久久综合给合久久狠狠狠97色69| 韩国精品在线观看| 麻豆成人在线| 日韩一级精品视频在线观看| 午夜精品久久久久久久白皮肤| 国产一区二区三区久久 | 一区二区三区自拍| 亚洲欧美中文另类| 久久亚洲精品视频| 亚洲国产天堂久久综合网| 欧美日韩dvd在线观看| 亚洲一区二区三区在线看| 久久亚洲欧美国产精品乐播| 亚洲精品之草原avav久久| 国产精品久久久久av| 久久久国产精品一区二区中文| 91久久精品一区| 欧美怡红院视频| 亚洲国产欧美在线人成| 国产精品狼人久久影院观看方式| 久久蜜桃香蕉精品一区二区三区| 亚洲区在线播放| 久久久久久午夜| 亚洲国产高清在线观看视频| 国产精品久久久久久久久果冻传媒| 久久久久久电影| 一区二区三区国产精华| 男男成人高潮片免费网站| 亚洲一区二区三区中文字幕| 曰本成人黄色| 国产美女高潮久久白浆| 欧美成人一区二区三区在线观看| 亚洲欧美日本伦理| 亚洲精选在线| 欧美黑人在线播放| 欧美一区二区三区播放老司机| 亚洲国产欧美一区| 国产在线观看精品一区二区三区| 欧美精品七区| 久久一区二区三区国产精品| 午夜精品福利一区二区三区av | 嫩草成人www欧美| 亚洲在线免费| 亚洲免费av网站| 亚洲国产综合在线看不卡| 国产一区二区三区四区五区美女| 国产精品久久久久aaaa樱花| 欧美久久电影| 欧美激情1区2区|