以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- 网格模型高级技术(2) (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=70613) |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:46:00 AM -- 网格模型高级技术(2) 层次细节网格模型(progress mesh)是一种特殊的网格模型,它的顶点数据以树状形式组织,可以随意增加或降低模型的复杂程度,从而比普通的网格模型具有更大的灵活性,层次细节网格模型对于层次细节场景的渲染非常理想。当模型距离观察者较远时可以降低模型的复杂程度,提高渲染速度。而当模型距离观察者较近时可以使用复杂的模型,从而提高视觉效果。Direct3D用ID3DXPMesh来表示层次细节网格模型对象,而不是ID3DXMesh。 层次细节网格模型是根据原始普通网格模型生成的,在生成层次细节网格模型之前,首先需要对原始网格模型进行相关处理,包括整理、顶点融合、检查3个步骤。 在调用函数D3DXLoadMeshFromX()生成网格模型后,调用Direct3D功能函数D3DXCleanMesh()对初始网格模型进行整理,其声明如下: Cleans a mesh, preparing it for simplification. HRESULT D3DXCleanMesh( D3DXCLEANTYPE CleanType, LPD3DXMESH pMeshIn, CONST DWORD * pAdjacencyIn, LPD3DXMESH * ppMeshOut, DWORD * pAdjacencyOut, LPD3DXBUFFER * ppErrorsAndWarnings); Remarks 枚举常量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; 在整理好网格模型后,调用函数D3DXWeldVertices()将网格模型中属性相同的重复顶点溶合到一起,从而简化网格模型,其声明如下: 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); Remarks 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 bufferLPD3DXBUFFER pD3DXMtrlBuffer = NULL; // material bufferLPD3DXMESH pMesh = NULL; // mesh objectDWORD m_dwNumMaterials; // number of materialsD3DXWELDEPSILONS Epsilons; // structure with epsilon valuesDWORD *pFaceRemap[65536]; // face remapping arrayDWORD 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 Options for welding together vertices. typedef enum D3DXWeldEpsilonsFLAGS{ D3DXWeldEpsilons_WELDALL = 1, D3DXWeldEpsilons_WELDPARTIALMATCHES = 2, D3DXWeldEpsilons_DONOTREMOVEVERTICES = 4, D3DXWeldEpsilons_DONOTSPLIT = 8,} D3DXWeldEpsilonsFLAGS, *LPD3DXWeldEpsilonsFLAGS; 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; typedef D3DXWELDEPSILONS *LPD3DXWELDEPSILONS; Validates a mesh. HRESULT D3DXValidMesh( LPD3DXMESH pMeshIn, CONST DWORD * pAdjacency, LPD3DXBUFFER * ppErrorsAndWarnings); Remarks 在上面的准备工作完成后,可以调用函数D3DXGeneratePMesh()根据初始网格模型生成层次细节网格模型,其声明如下: Generates a progressive mesh. HRESULT D3DXGeneratePMesh( LPD3DXMESH pMesh, CONST DWORD * pAdjacency, CONST D3DXATTRIBUTEWEIGHTS * pVertexAttributeWeights, CONST FLOAT * pVertexWeights, DWORD MinValue, DWORD Options, LPD3DXPMESH * ppPMesh); Remarks 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}; D3DXMESHSIMP的定义如下: Specifies simplification options for a mesh. typedef enum D3DXMESHSIMP{ D3DXMESHSIMP_VERTEX = 1, D3DXMESHSIMP_FACE = 2,} D3DXMESHSIMP, *LPD3DXMESHSIMP;
示例程序ProgressMesh的具体实现 示例程序演示了层次细节网格模型的生成和渲染,其中加载原始网格模型、简化熔合原始网格并生成层次细节网格模型的代码如下: ID3DXBuffer* material_buffer;
运行效果图: |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:47:00 AM -- 主程序: #pragma warning(disable : 4127 4995) #define IDC_TOGGLE_FULLSCREEN 1 #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) ID3DXFont* g_font; CDXUTDialogResourceManager g_dlg_resource_manager; ID3DXMesh* g_mesh; //-------------------------------------------------------------------------------------- IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, return true; static bool is_first_time = true; if(is_first_time) // if using reference device, then pop a warning message box. return true; //-------------------------------------------------------------------------------------- LPWSTR w_last_back_slash = wcsrchr(wbuf, '\\'); if(w_last_back_slash) V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice)); D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, ID3DXBuffer* material_buffer; V_RETURN(D3DXLoadMeshFromXW(L"Dwarf.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL, D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer(); for(DWORD i = 0; i < g_num_materials; i++) WCHAR wfilename[256]; g_mesh_textures[i] = NULL; if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0) V_RETURN(D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, g_mesh, adj, &cleaned_mesh, adj, NULL)); g_mesh = cleaned_mesh; D3DXWELDEPSILONS weld_epsilons; V_RETURN(D3DXValidMesh(g_mesh, adj, NULL)); DWORD min_vertices = g_progress_mesh->GetMinVertices(); g_ui_dlg.GetSlider(IDC_DETAIL)->SetRange(min_vertices, max_vertices); return S_OK; V_RETURN(g_dlg_resource_manager.OnResetDevice()); // set dialog position and size g_button_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, 0); g_ui_dlg.SetLocation(0, pBackBufferSurfaceDesc->Height - 60); // setup view matrix D3DXMATRIX mat_view; D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up); // set projection matrix pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xFFFFFFFF); return S_OK; //-------------------------------------------------------------------------------------- release_com(g_text_sprite); delete[] g_mesh_materials; if(g_mesh_textures) delete[] g_mesh_textures; release_com(g_font); //-------------------------------------------------------------------------------------- D3DXMatrixTranslation(&mat_translation, 0, -0.7f, 0); pd3dDevice->SetTransform(D3DTS_WORLD, &mat_world); //-------------------------------------------------------------------------------------- // show frame and device states // show other simple information // show helper information if(g_show_help) text_helper.End(); //-------------------------------------------------------------------------------------- if(g_settings_dlg.IsActive()) // Clear the render target and the zbuffer // Render the scene RenderText(); V( pd3dDevice->EndScene() ); if(g_settings_dlg.IsActive()) *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam); *pbNoFurtherProcessing = g_ui_dlg.MsgProc(hWnd, uMsg, wParam, lParam); return 0; //-------------------------------------------------------------------------------------- case IDC_TOGGLE_REF: case IDC_CHANGE_DEVICE: case IDC_DETAIL: //-------------------------------------------------------------------------------------- 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_ui_dlg.SetCallback(OnGUIEvent); //-------------------------------------------------------------------------------------- // Set the callback functions // Initialize DXUT and create the desired Win32 window and Direct3D device for the application // Start the render loop // TODO: Perform any application-level cleanup here return DXUTGetExitCode();
[B][URL=http://www.cppblog.com/Files/changingnow/ProgressMesh.rar]下载示例工程[/URL][/B](仅包含工程文件和源码,不包含资源文件,资源请从示例程序OptimizedMesh中提取) |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:48:00 AM -- 增强网格模型是运行镶嵌技术将原始网格模型的三角形面进行细分,形成更加精细(三角形面更多)的网格模型,这对于逐顶点进行的光照效果会更好。网格模型镶嵌技术主要用在层次细节场景中当模型距离观察者较近时,使模型的显示更精细。 增强网格模型可以通过对原始网格模型进行镶嵌细分模型得到,Direct3D提供了功能函数D3DXTessellateNPatches()来完成这一工作。该函数根据指定的参数,由显卡的镶嵌器(tessellator)对网格模型中的多边形进行细分,从而使原来的三维物体表面变得更加光滑细致。该函数声明如下: Tessellates the given mesh using the N-patch tessellation scheme. HRESULT D3DXTessellateNPatches( LPD3DXMESH pMeshIn, CONST DWORD * pAdjacencyIn, FLOAT NumSegs, BOOL QuadraticInterpNormals, LPD3DXMESH * ppMeshOut, LPD3DXBUFFER * ppAdjacencyOut); Remarks 在示例程序EnhancedMesh中,生成增强网格模型的代码如下: //--------------------------------------------------------------------------------------// Generate enhanced mesh from original mesh//--------------------------------------------------------------------------------------HRESULT GenerateEnhancedMesh(IDirect3DDevice9* device, UINT num_segs){ ID3DXMesh* enhanced_mesh; ID3DXMesh* cloned_mesh; HRESULT hr;
运行效果图: 细分前
每边细分为2
每边细分为10 |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:48:00 AM -- 主程序: #pragma warning(disable : 4127 4995) #define IDC_TOGGLE_FULLSCREEN 1 #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) ID3DXFont* g_font; CDXUTDialogResourceManager g_dlg_resource_manager; ID3DXMesh* g_mesh; //-------------------------------------------------------------------------------------- IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, return true; static bool is_first_time = true; if(is_first_time) // if using reference device, then pop a warning message box. return true; //-------------------------------------------------------------------------------------- LPWSTR w_last_back_slash = wcsrchr(wbuf, '\\'); if(w_last_back_slash) //-------------------------------------------------------------------------------------- // use 32 bit index to avoid vertex indices buffer overflow V_RETURN(D3DXTessellateNPatches(cloned_mesh, (DWORD*) g_adj_buffer->GetBufferPointer(), (float) num_segs, release_com(cloned_mesh); g_enhanced_mesh = enhanced_mesh; return S_OK; //-------------------------------------------------------------------------------------- V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice)); D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, ID3DXBuffer* material_buffer; V_RETURN(D3DXLoadMeshFromXW(L"cube.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL, D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer(); for(DWORD i = 0; i < g_num_materials; i++) WCHAR wfilename[256]; g_mesh_textures[i] = NULL; if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0) V_RETURN(GenerateEnhancedMesh(pd3dDevice, g_num_segs)); return S_OK; V_RETURN(g_dlg_resource_manager.OnResetDevice()); // set dialog position and size g_button_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, 0); g_ui_dlg.SetLocation(0, pBackBufferSurfaceDesc->Height - 60); // setup view matrix D3DXMATRIX mat_view; D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up); // set projection matrix return S_OK; //-------------------------------------------------------------------------------------- release_com(g_text_sprite); delete[] g_mesh_materials; if(g_mesh_textures) delete[] g_mesh_textures; release_com(g_font); //-------------------------------------------------------------------------------------- pd3dDevice->SetTransform(D3DTS_WORLD, &mat_world); //-------------------------------------------------------------------------------------- // show frame and device states // show other simple information // show helper information if(g_show_help) text_helper.End(); //-------------------------------------------------------------------------------------- if(g_settings_dlg.IsActive()) // Clear the render target and the zbuffer // Render the scene RenderText(); V( pd3dDevice->EndScene() ); if(g_settings_dlg.IsActive()) *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam); *pbNoFurtherProcessing = g_ui_dlg.MsgProc(hWnd, uMsg, wParam, lParam); return 0; //-------------------------------------------------------------------------------------- case IDC_TOGGLE_REF: case IDC_CHANGE_DEVICE: case IDC_SEGMENT: //-------------------------------------------------------------------------------------- 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_ui_dlg.SetCallback(OnGUIEvent); //-------------------------------------------------------------------------------------- // Set the callback functions // Initialize DXUT and create the desired Win32 window and Direct3D device for the application // Start the render loop // TODO: Perform any application-level cleanup here return DXUTGetExitCode();
[B][URL=http://www.cppblog.com/Files/changingnow/EnhancedMesh.rar]下载示例工程[/URL][/B] |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:48:00 AM -- 渐变(tweening)网格模型是Direct3D中实现模型动画最简单的方式和途径,它的原理也非常简单。例如对于场景内的某个网格模型,最初只记录t0时刻和t1时刻该网格模型的状态(即这两个时刻网格模型中所有顶点的位置),对于t0到t1这段时间内的任意时刻t_current,根据该时刻距离t0和t1时刻的远近,实时地分配给这两个网格模型不同的权重,然后按照这两个网格模型中顶点的不同位置和它们各自的权重进行插值,计算出t_current时刻整个网格模型中所有顶点的位置,从而实现动画效果。 通常将t0时刻的网格模型称为源网格模型,将t1时刻的网格模型称为目标网格模型,将最后拟合得到的网格模型称为结果网格模型。当然初始条件还可以是3个或更多时刻网格模型的状态,再根据时间的推移对这些网格模型进行插值而实时得到当前时刻网格模型的状态。 事实上,渐变网格模型就是对一系列已知的网格模型进行插值得到最终的网格模型。 首先,我们需要从.x文件加载源网格模型和目标网格模型: V_RETURN(D3DXLoadMeshFromXW(L"source.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials, &g_source_mesh)); ID3DXMesh* cloned_mesh;
目标网格模型的状态如下图所示:
最后我们根据程序当前运行时间,分别计算源网格模型和目标网格模型的权重,利用计算出的权重对源网格模型和目标网格模型的顶点坐标和法向量进行插值,得到当前时刻的结果网格模型: sVertex* source_vertices;sVertex* target_vertices;sVertex* result_vertices; // move dolphin around circle 运行效果图: |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:49:00 AM -- 主程序: #pragma warning(disable : 4127 4995) #define IDC_TOGGLE_FULLSCREEN 1 struct sVertex const DWORD CUSTOM_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL; #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) ID3DXFont* g_font; CDXUTDialogResourceManager g_dlg_resource_manager; ID3DXMesh* g_source_mesh; IDirect3DVertexBuffer9* g_source_vb; DWORD g_num_materials; IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, return true; static bool is_first_time = true; if(is_first_time) // if using reference device, then pop a warning message box. return true; //-------------------------------------------------------------------------------------- LPWSTR w_last_back_slash = wcsrchr(wbuf, '\\'); if(w_last_back_slash) //-------------------------------------------------------------------------------------- V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice)); D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, V_RETURN(D3DXLoadMeshFromXW(L"source.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials, V_RETURN(D3DXLoadMeshFromXW(L"target.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials, ID3DXMesh* cloned_mesh; // clone source mesh with specified vertex format // clone target mesh with specified vertex format // clone result mesh with specified vertex format from target mesh g_source_mesh->GetVertexBuffer(&g_source_vb); return S_OK; V_RETURN(g_dlg_resource_manager.OnResetDevice()); // set dialog position and size g_button_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, 0); // setup view matrix D3DXMATRIX mat_view; D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up); // set projection matrix // setup material D3DMATERIAL9 material; material.Diffuse.r = 0.5f; material.Ambient.r = 0.5f; pd3dDevice->SetMaterial(&material); // setup light D3DLIGHT9 light; light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 0.1f; light.Ambient.r = 0.1f; D3DXVECTOR3 light_dir = D3DXVECTOR3(-1, -1, 1); return S_OK; //-------------------------------------------------------------------------------------- release_com(g_text_sprite); release_com(g_font); release_com(g_source_mesh); release_com(g_source_vb); //-------------------------------------------------------------------------------------- g_source_vb->Lock(0, 0, (void**) &source_vertices, 0); float time_factor = (float)(timeGetTime() % 2000) / 1000.0f; for(DWORD i = 0; i < g_result_mesh->GetNumVertices(); i++) result_vertices[i].nx = source_vertices[i].nx * (1.0f - scalar) + target_vertices[i].nx * scalar; g_source_vb->Unlock(); // move dolphin around circle float kick_freq = float(2.0f * fTime); D3DXMATRIX mat_dolphin, mat_trans, mat_rot_y, mat_rot_z; D3DXMatrixScaling(&mat_dolphin, 0.01f, 0.01f, 0.01f); mat_dolphin = mat_dolphin * mat_rot_z * mat_rot_y * mat_trans;; pd3dDevice->SetTransform(D3DTS_WORLD, &mat_dolphin); //-------------------------------------------------------------------------------------- // show frame and device states // show helper information if(g_show_help) text_helper.End(); //-------------------------------------------------------------------------------------- if(g_settings_dlg.IsActive()) // Clear the render target and the zbuffer // Render the scene RenderText(); V( pd3dDevice->EndScene() ); if(g_settings_dlg.IsActive()) *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam); //-------------------------------------------------------------------------------------- case IDC_TOGGLE_REF: case IDC_CHANGE_DEVICE: //-------------------------------------------------------------------------------------- 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); //-------------------------------------------------------------------------------------- // Set the callback functions // Initialize DXUT and create the desired Win32 window and Direct3D device for the application // Start the render loop // TODO: Perform any application-level cleanup here return DXUTGetExitCode();
[B][URL=http://www.cppblog.com/Files/changingnow/Tweening.rar]下载示例工程[/URL][/B] |
-- 作者:卷积内核 -- 发布时间:12/18/2008 9:51:00 AM -- 类CDXUTMesh的详细说明请参阅DXUT源码分析 ---- 类CDXUTMesh。
使用CDXUTMesh进行网格模型的绘制 首先在OnCreate()函数中创建CDXUTMesh对象: g_dxut_mesh = new CDXUTMesh();
接着在OnFrameRender()中绘制(先绘制不透明的网格,再绘制半透明的网格): // Render the sceneif( SUCCEEDED( pd3dDevice->BeginScene() ) ){ pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 示例截图:
主程序:
#include "dxstdafx.h" #pragma warning(disable : 4127 4995) #define IDC_TOGGLE_FULLSCREEN 1 #define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0) ID3DXFont* g_font; CDXUTDialogResourceManager g_dlg_resource_manager; CDXUTMesh* g_dxut_mesh; //-------------------------------------------------------------------------------------- IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, return true; static bool is_first_time = true; if(is_first_time) // if using reference device, then pop a warning message box. return true; //-------------------------------------------------------------------------------------- LPWSTR w_last_back_slash = wcsrchr(wbuf, '\\'); if(w_last_back_slash) V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice)); D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, return S_OK; V_RETURN(g_dlg_resource_manager.OnResetDevice()); // set dialog position and size g_button_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, 0); // setup view matrix D3DXMATRIX mat_view; D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up); // set projection matrix // setup light light.Type = D3DLIGHT_DIRECTIONAL; D3DXVECTOR3 light_dir(0.0f, -1.0f, 1.0f); pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00FFFF80); return S_OK; //-------------------------------------------------------------------------------------- release_com(g_text_sprite); release_com(g_font); //-------------------------------------------------------------------------------------- D3DXMatrixRotationY(&mat_rot_y, (float)fTime); mat_world = mat_rot_y * mat_trans; //-------------------------------------------------------------------------------------- // show frame and device states // show helper information if(g_show_help) text_helper.End(); //-------------------------------------------------------------------------------------- if(g_settings_dlg.IsActive()) // Clear the render target and the zbuffer // Render the scene g_dxut_mesh->Render(pd3dDevice, true, false); pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); g_dxut_mesh->Render(pd3dDevice, false, true); // restore alpha belnd state to disabled RenderText(); V( pd3dDevice->EndScene() ); if(g_settings_dlg.IsActive()) *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam); return 0; //-------------------------------------------------------------------------------------- case IDC_TOGGLE_REF: case IDC_CHANGE_DEVICE: //-------------------------------------------------------------------------------------- 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); //-------------------------------------------------------------------------------------- // Set the callback functions // Initialize DXUT and create the desired Win32 window and Direct3D device for the application // Start the render loop // TODO: Perform any application-level cleanup here return DXUTGetExitCode(); |
-- 作者:秋十三 -- 发布时间:1/2/2009 8:01:00 PM -- 好啊 我收藏了啊 |
-- 作者:秋十三 -- 发布时间:1/2/2009 8:03:00 PM -- 好啊 我收藏了啊 |
-- 作者:dungeonsnd -- 发布时间:3/10/2009 5:29:00 PM -- 啥也不说了,眼泪哗哗的,太好了,学习的极好资料。 太详细的学习网格的资料!~~ 感谢! |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
320.313ms |