DirectX 3D_实践之DirectX3D中通过XFile文件来创建网格
来源:互联网 发布:欧洲有4g网络吗 编辑:程序博客网 时间:2024/05/17 05:03
成熟程序员,什么样的程序员是一个成熟的程序员了,技术高手,不是,我想说成熟的程序员是,可以很快完成需求,但是不炫耀,说话的语速不快不慢,跟平常说话一样。别人再急,我们都不能急,因为我们是程序员,很多东西,都需要考虑清楚,头脑不清晰,是程序员最最忌讳的。心态很平和,不以物喜,不以己悲,不因为别人跳槽而羡慕,不因为有的人被辞退而幸灾乐祸,可以永远以自己的速度去处理所有的事情,工作仅仅是工作,不工作的时候,完全不工作。
今天,我们看一下,如果使用3D建模工具生成的3D模型。我们知道,如果单单只用顶点,三角形,来完成3D图形,以及游戏的显示是非常困难的。我们必须借助于一些第三方的建模工具,进行专业模型,图像的绘制,再由DIRECTX框架来进行模型的操作。正好,Direct3D提供了这样的功能。我们可以通过3D MAX或者MAYA建好模型,由DirectX来进行显示。
我们先来看DirectX3D.h的代码:
#ifndef __DirectX3DH__#define __DirectX3DH__#include <d3dx9.h>#include <string>namespace d3d{bool InitD3D(HINSTANCE hInstance, // [in] Application instance.int width, int height, // [in] Backbuffer dimensions.bool windowed, // [in] Windowed (true)or full screen (false).D3DDEVTYPE deviceType, // [in] HAL or REFIDirect3DDevice9** device);// [out]The created device.int EnterMsgLoop( bool (*ptr_display)(float timeDelta));LRESULT CALLBACK WndProc(HWND hwnd,UINT msg, WPARAM wParam,LPARAM lParam);template<class T> void Release(T t){if( t ){t->Release();t = 0;}}template<class T> void Delete(T t){if( t ){delete t;t = 0;}}const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) );const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) );const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) );const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) );const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) );//// Lights//D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);//// Materials//D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);}#endif
再来看DirectX3D.cpp的代码:
#include "DirectX3D.h"bool d3d::InitD3D(HINSTANCE hInstance,int width, int height,bool windowed,D3DDEVTYPE deviceType,IDirect3DDevice9** device){//// Create the main application window.//WNDCLASS wc;wc.style = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc = (WNDPROC)d3d::WndProc; wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(0, IDI_APPLICATION);wc.hCursor = LoadCursor(0, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName = 0;wc.lpszClassName = "Direct3D9App";if( !RegisterClass(&wc) ) {::MessageBox(0, "RegisterClass() - FAILED", 0, 0);return false;}HWND hwnd = 0;hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", WS_EX_TOPMOST,0, 0, width, height,0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); if( !hwnd ){::MessageBox(0, "CreateWindow() - FAILED", 0, 0);return false;}::ShowWindow(hwnd, SW_SHOW);::UpdateWindow(hwnd);//// Init D3D: // //第一步 //要初始化IDirect3D 首先必须获取IDirect3D9的指针,使用一个专门的Direct3D函数就可以很容易做到 IDirect3D9 * _d3d9; //这个对象的主要有两个用途:设备枚举以及创建IDirect3DDevice9类型的对象。设备枚举是指获取系统中可用的的每块图形卡的 //性能,显示模型,格式以及其他信息。这个函数调用失败会返回一个NULL指针。 if(NULL == (_d3d9 = Direct3DCreate9(D3D_SDK_VERSION))){ return FALSE; } //第二步 //创建一个代表主显卡的IDirect3DDevice9类型对象时,必须指定使用该对象进行顶点运算的类型。如果可以,我们希望使用硬件顶点运算 //但是由于并非所有的显卡都支持硬件顶点运算,我们必须首先检查图形卡是否支持该类型的运算。 //要进行检查,必须先根据主显卡的性能参数初始化一个IDirect3DDevice9类型的对象。我们使用如下方法来完成初始化: /* HRESULT IDirect3D9:GetDeviceCaps( UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 * pCaps; ) Adapter : 指定物理显卡的序号。 DeviceType:指定设备类(例如硬件设备(D3DDEVTYPE_HAL)或软件设备(D3DDEVTYPE_REF)); pCaps 返回已初始化的设备性能结构实例。 */ D3DCAPS9 caps; int vp = 0; //代表顶点如何操作 _d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){ vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } //第三步是填充D3DPRESENT_PARAMETER结构 //该结构用于指定所要创建的IDirect3DDevice9类型对象的一些特性,该结构定义如下: /* typedef struct _D3DPRESENT_PARAMETERS_{ UINT BackBufferWidth; UINT BackBufferHeight; UINT BackBufferFormat; UINT BackBufferCount; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BOOL Windowed; BOOL EnableAutoDepthStencil; D3DFORMAT AutoDepthStencilFormat; DWORD Flags; UINT FullScreen_RefreshRateInHz; UINT PresentationInterval; }; */ /* BackBufferWidth: 后台缓存中表面的宽度,单位为像素。 BackBufferHeight:后台缓存中表面的高度,单位为像素。 BackBufferFormat:后台缓存的像素格式(如32位像素格式:D3DFMT_A8R8G8B8); BackBufferCount: 所需使用的后台缓存的个数,通常指定为1,表明我们仅需要一个后台缓存。 MultiSampleType: 后台缓存所使用的多重采样类型。 MultiSampleQuality:多重采样的质量水平。 SwapEffect:D3DSWAPEFFECT 枚举类型的一个成员。该枚举类型指定了交换链中的缓存的页面置换方式。指定D3DSWAPEFFECT_DISCARD时效率最高。 hDeviceWindow:与设备相关的窗口句柄。指定了所要进行绘制的应用程序窗口。 Windowed:为true时表示窗口模式,false时为全屏模式 EnableAutoDepthStencil:设为true,则Direct3D自动创建并维护深度缓存或模板缓存。 AutoDepthStencilFormat:深度缓存或模板缓存的像素格式(例如,用24位表示深度并将8位保留供模板缓存使用,D3DFMT_D24S8). Flags:一些附加的特性。可以指定为0,表示无标记,或D3DPRESENTFLAG集合中的一个成员,其中两个成员较常用。 D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 指定为可锁定的后台缓存。注意,使用一个可锁定的后台缓存会降低性能。 D3DPRESENTFLAG_DISCARD_DEPTHBUFFER 指定当下一个后台缓存提交时,哪个深度或模块缓存将被丢弃。丢弃的意思是深度或模板缓存存储区 中的内容别丢弃或无效。这样可以提升性能。 FullScreen_RefreshRateInHz: 刷新频率,如果想使用默认的刷新频率,则可将该参数指定为D3DPRESENT_RATE_DEFAULT; PresentationInterval:D3DPRESENT集合的一个成员,其中有两个比较常用。 D3DPRESENT_INTERVAL_IMMEDIATE 立即提交。 D3DPRESENT_INTERVAL_DEFAULT 由Direct3D来选择提交频率,通常该值等于刷新频率。 */ D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferWidth = 800; d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = true; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = 0; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //第四步 创建IDirectDevice9类型的对象 /* HRESULT IDirect3D9::CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 ** ppReturnedDeviceInterface ); Adapter:指定我们希望用已创建的IDirect3DDevice9对象代表哪块物理显卡。 DeviceType:指定需要使用的设备类型()如,硬件设备用D3DDEVTYPE_HAL,或D3DDEVTYPE_REF代表软件设备。 hFocusWindow:与设备相关的窗口句柄。通常情况下是指设备所要进行绘制的目标窗口。 为了达到预期的目的,该句柄与D3DPRESENT_PARAMETER结构的数据成员hDeviceWindow应为同一个句柄。 BehaviorFlags:该参数可为D3DCREATE_HARDWARE_VERTEXPROCESSING或D3DCREATE_SOFTWARE_VERTEXPROCESSING. pPresentationParameters:一个已经完成初始化的D3DPRESENT_PARAMETERS类型的实例,该实例定义了设备的一些特性。 ppReturnedDeviceInterface:返回所创建的设备。*/ if(FAILED(_d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, vp, &d3dpp, device))) return FALSE; _d3d9->Release(); return TRUE;}int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) ){MSG msg;::ZeroMemory(&msg, sizeof(MSG));static float lastTime = (float)timeGetTime(); while(msg.message != WM_QUIT){if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){::TranslateMessage(&msg);::DispatchMessage(&msg);}else {float currTime = (float)timeGetTime();float timeDelta = (currTime - lastTime)*0.001f;ptr_display(timeDelta);lastTime = currTime; } } return msg.wParam;}D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color){D3DLIGHT9 light;::ZeroMemory(&light, sizeof(light));light.Type = D3DLIGHT_DIRECTIONAL;light.Ambient = *color * 0.4f;light.Diffuse = *color;light.Specular = *color * 0.6f;light.Direction = *direction;return light;}D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color){D3DLIGHT9 light;::ZeroMemory(&light, sizeof(light));light.Type = D3DLIGHT_POINT;light.Ambient = *color * 0.4f;light.Diffuse = *color;light.Specular = *color * 0.6f;light.Position = *position;light.Range = 1000.0f;light.Falloff = 1.0f;light.Attenuation0 = 1.0f;light.Attenuation1 = 0.0f;light.Attenuation2 = 0.0f;return light;}D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color){D3DLIGHT9 light;::ZeroMemory(&light, sizeof(light));light.Type = D3DLIGHT_SPOT;light.Ambient = *color * 0.4f;light.Diffuse = *color;light.Specular = *color * 0.6f;light.Position = *position;light.Direction = *direction;light.Range = 1000.0f;light.Falloff = 1.0f;light.Attenuation0 = 1.0f;light.Attenuation1 = 0.0f;light.Attenuation2 = 0.0f;light.Theta = 0.5f;light.Phi = 0.7f;return light;}D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p){D3DMATERIAL9 mtrl;mtrl.Ambient = a;mtrl.Diffuse = d;mtrl.Specular = s;mtrl.Emissive = e;mtrl.Power = p;return mtrl;}
最后来看一下wmain.cpp的代码:
#include "DirectX3D.h"#include <fstream>#include <vector>//// Globals//IDirect3DDevice9* Device = 0; const int Width = 640;const int Height = 480;ID3DXMesh *Mesh = 0;std::vector<D3DMATERIAL9> Mtrls(0);// 创建一个容器对象,里面的元素是材质std::vector<IDirect3DTexture9*> Textures(0);//创建一个容器对象,里面的元素是纹理。//// Classes and Structures//struct Vertex{Vertex(){}Vertex(float x, float y, float z, float nx, float ny, float nz, float u, float v){_x = x; _y = y; _z = z;_nx = nx; _ny = ny; _nz = nz;_u = u; _v = v;}float _x, _y, _z, _nx, _ny, _nz, _u, _v;static const DWORD FVF;};const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;//// Framework Functions//bool Setup(){//我们用一个ID3DMesh对象存储XFile文件中的加载的网格数据。/*现在的建模工具,比如3DS Max和Maya,都可以将网格数据(几何信息,材质,动画以及其他可能的有用数据)导出到文件中。我们可以编写一个文件读取程序来提取网格数据,并在我们的3D应用程序中使用。另外还有一种更简单的方法,有一种特殊的网格文件格式称为XFile格式(扩展名为.x),许多3D建模工具都可以将模型数据导成这个格式,而且也有许多转换程序可以将其他较流行的网格文件格式转换为.x格式,XFile之所以使用方便,主要的原因是他是DirectX定义的格式,提供相应的函数对其直接操作*/ //另外我们用两个向量分别存储该网格的材质和纹理数据。HRESULT hr = 0; ID3DXBuffer * adjBuffer = 0;ID3DXBuffer * mtrlBuffer = 0;DWORD numMtrls = 0;/* 看一下这个函数的参数说明: HRESULT D3DXLoadMeshFromX( __in LPCTSTR pFilename, __in DWORD Options, __in LPDIRECT3DDEVICE9 pD3DDevice, __out LPD3DXBUFFER *ppAdjacency, __out LPD3DXBUFFER *ppMaterials, __out LPD3DXBUFFER *ppEffectInstances, __out DWORD *pNumMaterials, __out LPD3DXMESH *ppMesh ); pFilename: 所要加载的XFile文件名。 Options:创建网格时所使用的创建标记。标记选项的完整列表可参阅SDK文档中与枚举累型D3DXMESH相关的部分。常用标记如下。 D3DXMESH_32BIT 网格将使用32位索引。 D3DXMESH_MANAGED 网格数据将被存储于托管内存池中。 D3DXMESH_WRITEONLY 指定网格数据为只读。 D3DXMESH_DYNAMIC 网格缓存将使用动态内存。 pD3DDevice:与该网格对象相关的设备指针。 ppAdjacency:返回一个ID3DXBuffer对象,该对象包含了一个描述了该网格对象的邻接信息的DWORD类型的数组。 ppMaterials:返回一个ID3DXBuffer对象,该对象包含了一个描述了该网格对象的材质数据D3DXMATERIAL类型的结构数组 ppEffectInstances:返回一个ID3DXBuffer对象,该对象包含了一个D3DXEFFECTINSTANCE结构。我们可以通过将该参数设置0将器忽略。 pNumMaterials:返回网格中的材质数目。 ppMesh:返回所创建的并一填充了XFile几何数据的ID3DXMesh对象。 XFile材质: D3DXLoadMeshFromX函数中的第7个参数返回了该网格对象所含的材质数目,第5个参数返回了一个存储了材质数据的D3DXMATRIAL类型的结构数组。 D3DXMATERIAL结构的定义如下: typedef struct D3DXMATERIAL{D3DMATERIAL9 MatD3D;LPSTR pTextureFilename;}D3DXMATERIAL;该结构较为简单,包含了一个D3DMATERIAL9结构和一个指向以NULL结尾的字符串指针,该字符串指定了与网格相关的纹理文件名。XFile中并为存储纹理数据,是包含了纹理图像文件名,该文件名是对包含了实际纹理数据的纹理对象的引用。这样,当用D3DXLoadMeshFromX函数加载一个XFile文件后,必须根据指定的纹理文件名加载纹理数据。*/ hr = D3DXLoadMeshFromX( "bigship1.x",D3DXMESH_MANAGED,Device,&adjBuffer,&mtrlBuffer,0,&numMtrls,&Mesh);if(FAILED(hr)){::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);return false;} //得到材质和纹理。 if( mtrlBuffer != 0 && numMtrls != 0 ) //如果第5个参数,材质空间不为NUL,而且材质的数目不为0{D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer(); //得到材质指针。for(int i = 0; i < numMtrls; i++){// 将环境光和镜面光设置为一样mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;// 保存材质数据到容器中Mtrls.push_back( mtrls[i].MatD3D );// 检查相应的纹理文件名if( mtrls[i].pTextureFilename != 0 ){// 如果文件名不为NULL,用这个文件名,创建相应的纹理。IDirect3DTexture9* tex = 0;D3DXCreateTextureFromFile(Device,mtrls[i].pTextureFilename,&tex);// 保存纹理数据都容器中Textures.push_back( tex );}else{// 如果纹理文件名为NULL,不保存Textures.push_back( 0 );}}} //释放材质的指针d3d::Release<ID3DXBuffer*>(mtrlBuffer); //对网格进行优化,这里我们使用到了网格的邻接信息 hr = Mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT |D3DXMESHOPT_COMPACT |D3DXMESHOPT_VERTEXCACHE,(DWORD*)adjBuffer->GetBufferPointer(),0, 0, 0); d3d::Release<ID3DXBuffer*>(adjBuffer); // 释放邻接信息的指针if(FAILED(hr)){::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);return false;} //设置纹理过滤方式,和多级渐进纹理的处理方式。Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);//设置光照 D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);Device->SetLight(0, &light);Device->LightEnable(0, true);Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);Device->SetRenderState(D3DRS_SPECULARENABLE, true); //移动摄像机的位置,进行取景变换。 D3DXVECTOR3 pos(4.0f, 4.f, -13.0f);D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);D3DXMATRIX V;D3DXMatrixLookAtLH(&V,&pos,&target,&up);Device->SetTransform(D3DTS_VIEW, &V);//进行投影变化:D3DXMATRIX proj;D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI * 0.5f, // 90 - degree(float)Width / (float)Height,1.0f,1000.0f);Device->SetTransform(D3DTS_PROJECTION, &proj);return true;}//将之前分配的内存进行清理,也就是顶点缓存和索引缓存void Cleanup(){d3d::Release<ID3DXMesh*>(Mesh);for(int i = 0; i < Textures.size(); i++)d3d::Release<IDirect3DTexture9*>( Textures[i] );}bool Display(float timeDelta){if( Device ){//// 进行旋转,不断进行世界变换//static float y = 0.0f;D3DXMATRIX yRot;D3DXMatrixRotationY(&yRot, y);y += timeDelta;if( y >= 6.28f )y = 0.0f;D3DXMATRIX World = yRot;Device->SetTransform(D3DTS_WORLD, &World);//// 清屏//Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ffff, 1.0f, 0);Device->BeginScene();for(int i = 0; i < Mtrls.size(); i++)//从容器中得到保存的材质的数目{ //纹理设置,并进行子集的绘制。Device->SetMaterial( &Mtrls[i] );Device->SetTexture(0, Textures[i]); Mesh->DrawSubset(i);/*值得一提的是,D3DXLoadMeshFromX函数载入XFile数据后,返回的D3DXMATERIAL结构数组中的第i项就与第i个子集相对应。所以我们将各子集按照0,1,2...n-1的顺序进行标记,其中n是子集和材质的总数。这样就可用一个简单的循环对全部子集进行遍历和绘制,从而完成整个网格的绘制。*/}Device->EndScene();Device->Present(0, 0, 0, 0);}return true;}//// WndProc//LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch( msg ){case WM_DESTROY:::PostQuitMessage(0);break;case WM_KEYDOWN:if( wParam == VK_ESCAPE )::DestroyWindow(hwnd);break;}return ::DefWindowProc(hwnd, msg, wParam, lParam);}//// WinMain//int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd){if(!d3d::InitD3D(hinstance,640, 480, true, D3DDEVTYPE_HAL, &Device)){::MessageBox(0, "InitD3D() - FAILED", 0, 0);return 0;}if(!Setup()){::MessageBox(0, "Setup() - FAILED", 0, 0);return 0;}d3d::EnterMsgLoop( Display );Cleanup();Device->Release();return 0;}
再来看一下程序的截图:
每日总结:
我们可用3D建模工具构建复杂的三角形网络,并将其导出或转化为XFile文件,然后,借助函数D3DXCreateMeshFromX,我们可将XFile文件中的网格数据加载到一个ID3DXMesh对象中加以使用。
- DirectX 3D_实践之DirectX3D中通过XFile文件来创建网格
- DirectX 3D_实践之DirectX3D中网格的使用
- DirectX 3D_实践之DirectX3D 网格的外接体的创建和使用
- DirectX 3D_实践之DirectX3D中渐进网格的使用
- DirectX 3D_实践之DirectX3D中颜色的表示
- DirectX 3D_实践之初始化DirectX3D
- DirectX 3D_实践之DirectX3D的基本绘制流程
- DirectX 3D_实践之DirectX3D光照的实现
- DirectX 3D_实践之DirectX3D纹理映射
- DirectX 3D_实践之DirectX3D中的融合技术
- DirectX 3D_实践之DirectX3D中的文本绘制
- DirectX 3D_实践之DirectX3D中的物体拾取技术
- DirectX 3D_实践之DirectX3D中模板缓存的使用
- DirectX 3D_实践之在DirectX3D中实现摄像机方位的动态变换
- DirectX 3D_实践之DirectX3D中高度图的使用
- DirectX 3D_实践之DirectX3D中粒子系统的使用
- DirectX 3D_基础之网格应用 XFile XFile材质 生成顶点法向量 渐进网格 生产渐进网格 顶点属性权值 ID3DXPMesh接口
- DirectX学习笔记(十二):网格进阶之(XFile文件导入、渐进网格原理及外接体的)实现
- 菜鸟看“菜鸟网络”
- C++学习:hash(unordered_map)
- 10大最适合编程的字体推荐下载,让代码看起来更美更舒服!
- 如何做好行业市场分析?
- 如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
- DirectX 3D_实践之DirectX3D中通过XFile文件来创建网格
- linux CentOS中top命令参数说明
- C++中extern;stdafx.h
- ORACLE 函数大全
- android报错:connect failed: EHOSTUNREACH (No route to host)
- fcntl设置FD_CLOEXEC标志有什么用
- html5中的画布canvas----画出简单的矩形、三角形
- EXT下拉框联动
- Cheatsheet: 2013 05.15 ~ 05.31