设计DirectX游戏开头动画效果作者:蒋轶民
这个周末我刻苦钻研了两天加上一个晚上,终于把我的DirectX游戏开头动画效果做出来了。自己还是感到很高兴的。高兴之余,我发现我自己对纹理贴图的知识还是太匮乏了,必须要好好钻研才行。
首先请大家看看。这是我程序的最终效果。
要是我自己评价的话,只能算是差强人意。因为最终我的方案改变了。因为自己对纹理贴图的知识很匮乏。不过在以后我有的是时间来进行这方面的研究。
首先我研究怎样做这个程序的时候,遇到的问题是:怎样才能创建一个三维的物体,并且让它进行运动?这个问题也让我参考了很多的文献。包括了《DirectX游戏开发终极指南》、MSDN、GameRes.com和诸多强人的笔记。最终我在这些知识中总结了我的经验。下面以伪代码的形式展示给大家。
- 创建球体CreateSphere的步骤:
- 1、创建投影矩阵
- D3DXMatrixPerspectiveFovLH(D3DXMatrix投影矩阵的指针,FLOATy轴可见的弧度,FLOAT宽高比,FLOAT近裁面,FLOAT远裁面);
- 2、转换投影矩阵
- g_D3DDevice->SetTransform(D3DTS_PROJECTION(设置投影矩阵的参数),D3DXMatrix投影矩阵的指针);
- 3、创建图形或纹理;
- 4、定义三个视角
- D3DXVECTOR3观察者(摄影机)视角(0.0f,0.0f,-8.0f);
- D3DXVECTOR3观看的点(0.0f,varB,varA);
- D3DXVECTOR3默认向上的位置(0.0f,1.0f,0.0f);(如果是默认向下,可是设置(0.0f,-1.0f,0.0f);
- 5、建立视角矩阵
- D3DXMatrixLookAtLH(视角矩阵的指针,观察者(摄影机)视角的指针,
- 观看的点的指针,默认向上的位置的指针);
- 6、开始渲染
- g_D3DDevice->BeginScene();
- 7、应用视角
- g_D3DDevice->SetTransform(D3DTS_VIEW,&g_ViewMatrix);
- 8、改变世界矩阵(物体矩阵)模型
- D3DXMatrixTranslation(物体矩阵指针,横坐标,纵坐标,竖坐标);
- 9、设置世界矩阵(物体矩阵)模型
- g_D3DDevice->SetTransform(D3DTS_WORLD,物体矩阵指针);
- 10、绘制模型
- g_model->DrawSubset(0);
- 或者是创建纹理(图形):
- g_D3DDevice->SetStreamSource(0,g_VertexBuffer,0,sizeof(stD3DVertex));
- g_D3DDevice->SetFVF(D3DFVF_VERTEX);
- g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
- 11、结束渲染
- g_D3DDevice->EndScene();
- 12、显示场景
- g_D3DDevice->Present(NULL,NULL,NULL,NULL);
- 记住:一定要在使用后释放所有空间,不然会出现内存泄漏。
- D3DX_PI是一个宏,它约等于我们所说的π。
这里有几个我的示例,都是我在开发程序的时候对D3DXMatrixPerspectiveFovLH()这个函数的实时调整从而得到的效果。
这是我用伪代码写的函数说明:D3DXMatrixPerspectiveFovLH(D3DXMatrix 投影矩阵的指针, FLOAT y轴可见的弧度,FLOAT 宽高比,FLOAT 近裁面,FLOAT 远裁面);
远裁面、近裁面不好用程序演示,因为那时我没有研究光照,所以我就画了一个示例图,希望大家能够理解。
然后的问题是怎样才能应用光照的效果?我这次主要查了《DirectX游戏开发终极指南》,使用了最简单的顶点光,应用了一下,还不错。下面就是我自己写的关于怎样创建光照的笔记,也算是伪代码吧。
- 创建Direct3D光照的方法:
- 1、创建灯源和材质对象:
- D3DMATERIAL9g_material;//材质
- D3DLIGHT9g_light;//灯源
- 2、打开光照
- g_D3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);//开灯
- 3、建立灯源(例如)
- g_light.Type=D3DLIGHT_DIRECTIONAL;
- g_light.Direction=D3DXVECTOR3(0.0f,0.0f,1.0f);
- g_light.Diffuse.r=g_light.Diffuse.g=1;
- g_light.Diffuse.b=g_light.Diffuse.a=1;
- g_light.Specular.r=g_light.Specular.g=1;
- g_light.Specular.b=g_light.Specular.a=1;
- 4、注册灯源
- g_D3DDevice->SetLight(0,&g_light);
- g_D3DDevice->LightEnable(0,TRUE);
- 5、为材质设定参数
- ZeroMemory(&g_material,sizeof(D3DMATERIAL9));//养成好习惯,要为数据清零
- g_material.Diffuse.r=g_material.Ambient.r=0.6f;
- g_material.Diffuse.g=g_material.Ambient.g=0.6f;
- g_material.Diffuse.b=g_material.Ambient.b=0.7f;
- g_material.Specular.r=0.4f;
- g_material.Specular.g=0.4f;
- g_material.Specular.b=0.4f;
- g_material.Power=8.0f;
- 6、开始渲染
- g_D3DDevice->BeginScene();
- 7、设置对象材质
- g_D3DDevice->SetMaterial(&g_material);
- 8、显示对象
- g_teapot->DrawSubset(0);
- 或其它
- 9、停止渲染
- g_D3DDevice->EndScene();
- 注释:1、AmbientLighting(环境光,Ambient周围的),是最简单的一种平行光。它的作用相当于将具有某种材质的光进行颜色混合操作。
- 要使用更能模拟现实的光,可以使用漫反射(diffuse)和镜面反射(specular)。
- 2、在设置材质的时候,这样使用会比较好。
- g_material.Diffuse.r=1.0f;
- g_material.Diffuse.g=1.0f;
- g_material.Diffuse.b=0.72f;
- g_material.Ambient.r=0;
- g_material.Ambient.g=0;
- g_material.Ambient.b=0;
- g_material.Specular.r=0;
- g_material.Specular.g=0;
- g_material.Specular.b=0;
- g_material.Power=8.0f;
- 编程实验证明:我使用了变量对Ambient(环境光)和Specular(镜面反射)的RGB进行了替换,但是没有什么变化。而使用变量对Power进行替换,也没有什么变化。难道是我还没有发觉什么内在的东西吗?我不知道。不过我已经了解怎样使图像看起来比较好看了,就这样办吧。
下面就是我为了演示顶点光而编写的示例程序的截图(注意和上面伪代码的Ambient和Diffuse对应哦):
能显示我们的三维图形(球体)了,那么怎样才能使它运动起来呢?我又在昨天啃了下书本,这回三维物体的运动也给我解决了。下面就是我的总结。
- 动画篇:
- 要使模型进行动画,那么必须进行线性内插。这里我只进行了简单的三维抛物线的线性内插。线性内插的公式为:
- Final.x=(Dest.x-Start.x)*Scalar+Start.x
- Final.y=(Dest.y-Start.y)*Scalar+Start.y
- Final.z=(Dest.z-Start.z)*Scalar+Start.z
- 但是我让球体运动是沿着三维曲线运动的,所以我采取了其它的方法,而没有线性内插。
- 我让球体运动的曲线公式Γ为
- ┏x=-0.2*t*t+10*t
- Γ:┣y=-0.2*t*t+10*t
- ┗z=t
- 这是一个参数方程。参数是t。我们可以让t在(0,maxT)中递增,然后通过上面的公式来得到实时的坐标。我的语句是:
- if(t<maxT)//判断参数是否小于最大值
- t+=0.15f;//如果是,则递增
- //带入曲线公式,进行计算得到当前球体三维坐标
- currentPath.x=-0.2f*t*t+2.0f*t;
- currentPath.y=-0.2f*t*t+2.0f*t;
- currentPath.z=t;
下面就是我使球成功运动的一个程序截图:
然后就是比较棘手的事情了——纹理贴图。要高手做纹理贴图那肯定是非常容易的了,但是我们初学者往往会不知所措,因此我们往往会走很多弯路。为了能让几何图形和纹理共存,我又参考了很多的资料。这里属MSDN看得最多了。不过遗憾的是,我未能对纹理贴图有实际的突破。或许我对AlphaBlend知识或者是多纹理贴图的知识有着缺陷吧,我最后还是放弃了使用纹理贴图。但是我也有些了解。下面是我对D3DXCreateTextureFromFileEx()函数的理解。(翻译自MSDN DirectX9.0c)
- HRESULTD3DXCreateTextureFromFileEx(
- LPDIRECT3DDEVICE9pDevice,
- LPCTSTRpSrcFile,
- UINTWidth,
- UINTHeight,
- UINTMipLevels,
- DWORDUsage,
- D3DFORMATFormat,
- D3DPOOLPool,
- DWORDFilter,
- DWORDMipFilter,
- D3DCOLORColorKey,
- D3DXIMAGE_INFO*pSrcInfo,
- PALETTEENTRY*pPalette,
- LPDIRECT3DTEXTURE9*ppTexture
- );
- 下面说明一下参数表达的意思:
- pDevice
- [输入]指向LPDIRECT3DDEVICE9类的一个指针
- pSrcFile
- [输入]图像文件名,unicode要调整设置
- Width
- [输入]宽(以像素表示),如果该值为0或者是D3DX_DEFAULT,则从文件中载入宽。
- Height
- [输入]高(以像素表示)。如果该值为0或者是D3DX_DEFAULT,则从文件中载入高。
- MipLevels
- [输入]设置mip的等级,如果该值为0或者是D3DX_DEFAULT,将创建一个完全的mipmap链。如果该值是D3DX_FROM_FILE,大小完全取决于在文件中的值。如果与设备性能相违背的话,将调用失败。
- Usage
- [输入]0、D3DUSAGE_RENDERTARGET或D3DUSAGE_DYNAMIC。将此值设为D3DUSAGE_RENDERTARGET表明平面将被用作一个渲染的目标进行使用。如果是D3DUSAGE_RENDERTARGET或D3DUSAGE_DYNAMIC的任意值,Pool必须设为D3DPOOL_DEFAULT,而且程序必须通过使用CheckDeviceFormat()函数检测设备是否支持调用。D3DUSAGE_DYNAMIC表明平面必须动态地进行控制。查看UsingDynamicTextures文档。
- Format
- [输入]必须是D3DFORMAT枚举类型,描绘了为纹理所支持的像素格式。返回的纹理可能和Format指定纹理的格式不同。程序必须检测返回纹理的格式。如果是D3DFMT_UNKNOWN,格式将取自文件。如果是D3DFMT_FROM_FILE,格式将完全取自文件中。如果与设备性能相违背的话,将调用失败。
- Pool
- [输入]是D3DPOOL枚举类型的一个成员。描述了纹理必须被放置的memory类。
- Filter
- [输入]一个或多个D3DX_FILTER(D3DX滤波)常量(宏)控制图像是如何进行滤波的。指定D3DX_DEFAULT相当于指定D3DX_FILTER_TRIANGLE|D3DX_FILTER_DITHER。
- MipFilter
- [输入]一个或多个D3DX_FILTER常量控制图像是如何进行滤波的。指定D3DX_DEFAULT相当于指定D3DX_FILTER_BOX。另外,使用27-31比特指定跳跃mip的等级。当一个.dds格式装载时,它允许你跳跃至32等级。
- ColorKey
- [输入]D3DCOLOR类的值,用来以透明黑来替代。使用0来禁用颜色键。这常常是一个32比特的ARGB的值。独立于源图像的格式。Alpha非常重要常常设置为FF让颜色键不透明。因此让黑色不透明,值将被设置为0xFF000000。
- pSrcInfo
- [输入,输出]指向D3DXIMAGE_INFO结构体的指针以数据的描述源文件,或者是空。
- pPalette
- [输出]指向PALETTEENTRY结构的指针,代表装载256色的调色板,或者为空。
- ppTexture
- [输出]指向IDirect3DTexture9接口的双重指针,代表已创建的纹理对象。
如果载入纹理不行的话,那么只好使用DirectX的字体了。对DirectX字体的载入我还是挺了解的。不过即使了解,我也写了学习笔记,下面给大家分享一下。
- 创建字体的方法步骤:
- 1、全局变量
- LPD3DXFONTg_Font=NULL;//字体指针为空
- RECTg_FontPosition={0,0,0,0};//字体所占的矩形框
- 2、创建字体
- 调用D3DXCreateFont()函数(参见3DXCreateFont()函数的参数)
- D3DXCreateFont(g_D3DDevice,25,0,0,1,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"黑体",&g_Font);
- 注意:矩形框一定压要大,这样才能装得下字体。
- g_FontPosition.top=0;
- g_FontPosition.bottom=480;
- g_FontPosition.right=640;
- g_FontPosition.left=0;
- 3、开始渲染
- g_D3DDevice->BeginScene();
- 4、显示字体
- g_Font->DrawText(精灵图形(子图形)的指针(可设为NULL),字符串,字符串中字符的个数(-1为自动获取),&g_FontPosition,格式(左对齐、右对齐等,以DT_开头),字体颜色);
- 实例:g_Font->DrawText(NULL,"Bye!",-1,&g_FontPosition,DT_CENTER,D3DCOLOR_XRGB(255,255,255));
- 5、结束渲染
- g_D3DDevice->EndScene();
- 6、显示场景
- g_D3DDevice->Present(NULL,NULL,NULL,NULL);
- 注意:使用后一定要记得清除对象g_Font,调用release()函数。
大家知道我的字体怎么会发白光呢?其实这是一个非常简单的方法。我使用一个平行四边形,这个平行四边形在字体附近移动。因为字体是绘制在平行四边形前面的,所以我们看到的是平行四边形的白色遮住了字体。怎样?很简单吧。
好了,大家也很希望知道我的代码是怎样实现的吧,下面我把我代码所有的部分贴出来。
- *--------------------------------------------------
- 蒋轶民制作:E-mail:jiangcaiyang123@163.com
- 文件名:GameInit.cpp
- 作用:加载游戏片头动画
- ---------------------------------------------------*/
- /*--------------------------------------------------
- 这里借鉴使用了AllenSherrod的代码
- 所有权归蒋轶民和AllenSherrod所有
- 详情请见《DirectX游戏开发终极指南》
- ---------------------------------------------------*/
- #include<d3d9.h>
- #include<d3dx9.h>
- #pragmacomment(lib,"d3d9.lib")
- #pragmacomment(lib,"d3dx9.lib")
- #defineAPPCLASS"打方块游戏"
- #defineWINDOW_TITLE"打方块游戏"
- #defineWINDOW_WIDTH640
- #defineWINDOW_HEIGHT480
- //函数的原型
- boolInitializeD3D(HWNDhWnd,boolfullscreen);
- boolInitializeObjects(void);
- voidRenderScene(void);
- voidShutdown(void);
- //Direct3D对象和装置
- LPDIRECT3D9g_D3D=NULL;
- LPDIRECT3DDEVICE9g_D3DDevice=NULL;
- //顶点缓存用来保存几何图形
- LPDIRECT3DVERTEXBUFFER9g_VertexBuffer=NULL;
- //用来保存纹理图案的指针
- LPDIRECT3DTEXTURE9g_Texture=NULL;
- //矩阵类
- D3DXMATRIXg_projection;
- D3DXMATRIXg_ViewMatrix;
- D3DXMATRIXg_WorldMatrix;
- //要显示的模型
- LPD3DXMESHg_model=NULL;
- //设置灯源和材质光
- D3DMATERIAL9g_material;//材质
- D3DLIGHT9g_light;//灯源
- floatt=0.0f;//定义一个参数,用于三维曲线的参数方程
- floatmaxT=0.0f;//定义一个变量,它是参数t的最大值
- floatvarX=100.0f;//X变量坐标
- //一个三维矢量结构
- structstVector
- {
- stVector():x(0),y(0),z(0){}//默认构造函数
- floatx,y,z;
- }currentPath;//定义了起始位置、终止位置和当前位置
- //普通图形的顶点缓存
- structstD3DVertex
- {
- floatx,y,z,rhw;
- unsignedlongcolor;
- };
- LPD3DXFONTg_Font=NULL;//字体指针为空
- RECTg_FontPosition={190,330,640,480};//字体所占的矩形框
- //这两个FVF一个是应用在纹理的,另一个应用在图形上的
- #defineD3DFVF_VERTEX(D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
- //消息处理函数
- LRESULTWINAPIMsgProc(HWNDhWnd,UINTmsg,WPARAMwParam,LPARAMlParam)
- {
- switch(msg)
- {
- caseWM_DESTROY:
- PostQuitMessage(0);
- return0;
- break;
- caseWM_KEYUP:
- if(wParam==VK_ESCAPE)PostQuitMessage(0);
- break;
- }
- returnDefWindowProc(hWnd,msg,wParam,lParam);
- }
- intWINAPIWinMain(HINSTANCEhInst,HINSTANCEprevhInst,LPSTRcmd,intshow)
- {
- //注册窗口类
- WNDCLASSEXwc={sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,
- 0,0,GetModuleHandle(NULL),NULL,NULL,
- NULL,NULL,APPCLASS,NULL};
- RegisterClassEx(&wc);
- //创建窗口
- HWNDhWnd=CreateWindow(APPCLASS,WINDOW_TITLE,
- WS_OVERLAPPEDWINDOW,160,40,
- WINDOW_WIDTH,WINDOW_HEIGHT,GetDesktopWindow(),NULL,
- wc.hInstance,NULL);
- //显示窗口
- ShowWindow(hWnd,SW_SHOWDEFAULT);
- UpdateWindow(hWnd);
- //初始化Direct3D
- if(InitializeD3D(hWnd,false))
- {
- //进入消息循环
- MSGmsg;
- ZeroMemory(&msg,sizeof(msg));
- while(msg.message!=WM_QUIT)
- {
- if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {//开始渲染
- RenderScene();
- }
- }
- }
- elseMessageBox(NULL,"程序初始化出错!","程序信息",MB_OK);
- //解除注册窗口
- UnregisterClass(APPCLASS,wc.hInstance);
- return0;
- }
- //初始化D3D的函数
- boolInitializeD3D(HWNDhWnd,boolfullscreen)
- {
- D3DDISPLAYMODEdisplayMode;
- //创建D3D对象
- g_D3D=Direct3DCreate9(D3D_SDK_VERSION);
- if(g_D3D==NULL)returnfalse;
- //获取电脑的显示模式
- if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displayMode)))
- returnfalse;
- //启动一个结构体,为创建D3D设备做准备
- D3DPRESENT_PARAMETERSd3dpp;
- ZeroMemory(&d3dpp,sizeof(d3dpp));
- if(fullscreen)
- {
- d3dpp.Windowed=FALSE;
- d3dpp.BackBufferWidth=640;
- d3dpp.BackBufferHeight=480;
- }
- else
- d3dpp.Windowed=TRUE;
- d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferFormat=displayMode.Format;
- //创建D3D设备
- if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_D3DDevice)))
- {
- returnfalse;
- }
- //初始化将要显示的对象
- if(!InitializeObjects())
- {
- MessageBox(NULL,"载入初始化对象错误!","程序通知",MB_OK);
- returnfalse;
- }
- returntrue;
- }
- boolInitializeObjects(void)
- {
- //设置字体字体
- D3DXCreateFont(g_D3DDevice,40,0,0,1,true,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"ComicSansMS",&g_Font);
- //设置默认的渲染状态
- g_D3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);//开灯
- g_D3DDevice->SetRenderState(D3DRS_ZENABLE,TRUE);//开启深度缓存(z缓存)
- /*----------------------DirectX光照--------------------------------*/
- //建立灯源
- g_light.Type=D3DLIGHT_DIRECTIONAL;
- g_light.Direction=D3DXVECTOR3(0.0f,0.0f,1.0f);
- g_light.Diffuse.r=1.0f;
- g_light.Diffuse.g=1.0f;
- g_light.Diffuse.b=1.0f;
- g_light.Diffuse.a=1.0f;
- g_light.Specular.r=1.0f;
- g_light.Specular.g=1.0f;
- g_light.Specular.b=1.0f;
- g_light.Specular.a=1.0f;
- //注册灯源
- g_D3DDevice->SetLight(0,&g_light);
- g_D3DDevice->LightEnable(0,TRUE);
- //为材质设定参数
- ZeroMemory(&g_material,sizeof(D3DMATERIAL9));//养成好习惯,要为数据清零
- g_material.Diffuse.r=1.0f;
- g_material.Diffuse.g=1.0f;
- g_material.Diffuse.b=0.72f;
- g_material.Ambient.r=0;
- g_material.Ambient.g=0;
- g_material.Ambient.b=0;
- g_material.Specular.r=0;
- g_material.Specular.g=0;
- g_material.Specular.b=0;
- g_material.Power=0.8f;
- /*-------------------------------------------------------------------*/
- //设置投影矩阵
- D3DXMatrixPerspectiveFovLH(&g_projection,D3DX_PI/2,
- 1.4f,1.0f,1000.0f);
- g_D3DDevice->SetTransform(D3DTS_PROJECTION,&g_projection);
- //创建模型
- if(FAILED(D3DXCreateSphere(g_D3DDevice,1.5,25,25,&g_model,NULL)))returnfalse;
- //定义三个视角
- D3DXVECTOR3cameraPos(0.0f,0.0f,-8.0f);
- D3DXVECTOR3lookAtPos(0.0f,0.0f,0.0f);
- D3DXVECTOR3upDir(0.0f,1.0f,0.0f);
- //即从(0,0,-8.0f)点,看着(0,0,0)点,脑袋的方向是(0,1,0)
- //建立视角矩阵
- D3DXMatrixLookAtLH(&g_ViewMatrix,&cameraPos,&lookAtPos,&upDir);
- maxT=10.0f;//设置参数的最大值
- returntrue;
- }
- voidRenderScene(void)
- {
- //清除背景,并以背景颜色填充
- g_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,255,255),1.0f,0);
- if(t<maxT)//判断参数是否小于最大值
- {
- t+=0.15f;//如果是,则递增
- //带入曲线公式,进行计算得到当前球体三维坐标
- currentPath.x=-0.2f*t*t+2.0f*t;
- currentPath.y=-0.2f*t*t+2.0f*t;
- currentPath.z=t;
- //矩阵转换
- D3DXMatrixTranslation(&g_WorldMatrix,currentPath.x,currentPath.y,currentPath.z);
- g_D3DDevice->SetTransform(D3DTS_WORLD,&g_WorldMatrix);
- //应用视角
- g_D3DDevice->SetTransform(D3DTS_VIEW,&g_ViewMatrix);
- //设置对象材质
- g_D3DDevice->SetMaterial(&g_material);
- }
- else
- {
- //开始动画
- if(varX<540)
- varX+=5.0f;
- stD3DVertexobjVertex[]=
- {
- {varX,320.0f,0,1,D3DCOLOR_XRGB(255,255,255)},
- {varX+20.0f,320.0f,0,1,D3DCOLOR_XRGB(255,255,255)},
- {varX,370.0f,0,1,D3DCOLOR_XRGB(255,255,255)},
- {varX,320.0f,0,1,D3DCOLOR_XRGB(255,255,255)},
- {varX,370.0f,0,1,D3DCOLOR_XRGB(255,255,255)},
- {varX-20.0f,370.0f,0,1,D3DCOLOR_XRGB(255,255,255)}
- };
- //创建顶点缓存
- if(FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objVertex),0,D3DFVF_VERTEX,D3DPOOL_DEFAULT,&g_VertexBuffer,NULL)))return;
- //装入顶点缓存
- void*ptr;
- if(FAILED(g_VertexBuffer->Lock(0,sizeof(objVertex),(void**)&ptr,0)))return;
- memcpy(ptr,objVertex,sizeof(objVertex));
- g_VertexBuffer->Unlock();
- //开始渲染
- g_D3DDevice->BeginScene();
- //绘制字体
- g_Font->DrawText(NULL,"MarvelousWorks!",-1,&g_FontPosition,DT_LEFT,D3DCOLOR_XRGB(128,200,0));
- //绑入流,并且绘制图元
- g_D3DDevice->SetStreamSource(0,g_VertexBuffer,0,sizeof(stD3DVertex));
- g_D3DDevice->SetFVF(D3DFVF_VERTEX);
- g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);
- //结束渲染
- g_D3DDevice->EndScene();
- }
- //开始渲染
- g_D3DDevice->BeginScene();
- //创建模型
- g_model->DrawSubset(0);
- //结束渲染
- g_D3DDevice->EndScene();
- //显示场景
- g_D3DDevice->Present(NULL,NULL,NULL,NULL);
- }
- //释放所有的对象
- voidShutdown(void)
- {
- if(g_D3DDevice!=NULL)g_D3DDevice->Release();
- g_D3DDevice=NULL;
- if(g_D3D!=NULL)g_D3D->Release();
- g_D3D=NULL;
- if(g_model!=NULL)g_model->Release();
- g_model=NULL;
- if(g_VertexBuffer!=NULL)g_VertexBuffer->Release();
- g_VertexBuffer=NULL;
- if(g_Texture!=NULL)g_Texture->Release();
- g_Texture=NULL;
- }
看完代码,大家还是回味一下我的最终程序吧。
好了,这是我两天半的成果啊。如果大家有什么疑问的话,欢迎提问。今天就到这里了,我也要休息一下了,因为高强度的编程已经使我筋疲力尽了,我中午都没有睡觉,不想让自己的晚觉也被剥夺了,所以大家,晚安!