1 / 41

Visual C++ 高级编程

Visual C++ 高级编程. 第七讲 进入 3D 世界. 什么是 DirectX SDK ?. 微软的 DirectX 软件开发工具包( SDK )提供了一套优秀的应用程序编程接口( APIs ),这个编程接口可以提供给你开发高质量、实时的应用程序所需要的各种资源。 DirectX 技术的出现将极大的有助于发展下一代多媒体应用程序和电脑游戏。. DirectX SDK 的主要组件. DirectDraw :通过直接访问显示硬件来提供高级的图象处理能力。

odette
Download Presentation

Visual C++ 高级编程

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Visual C++高级编程 第七讲 进入3D世界

  2. 什么是DirectX SDK ? • 微软的DirectX软件开发工具包(SDK)提供了一套优秀的应用程序编程接口(APIs),这个编程接口可以提供给你开发高质量、实时的应用程序所需要的各种资源。DirectX技术的出现将极大的有助于发展下一代多媒体应用程序和电脑游戏。

  3. DirectX SDK的主要组件 • DirectDraw :通过直接访问显示硬件来提供高级的图象处理能力。 • DirectSound :它提供了软硬件的低延迟声音混频(low_latency sound mixing)和回放(Playback),硬件加速,以及直接访问音频设备的能力。 • DirectPlay :它明确的提供了通用环境连接能力(generalized communication capabilities),来简化你应用程序之间的通讯服务。 • Direct3D :它为主流的桌上型计算机和Internet用户提供实时的、交互的3D技术。 • DirectInput :它简化你的应用程序访问鼠标、键盘和操纵杆设备的能力。

  4. DirectX的特色 • 直接读写内存 DDRAW可以直接读写显存,并利用“切换页”的功能提高图形显示的性能。 • 支持硬件加速 DirectX对象建立时,程序自动查询可使用的硬件。提供HAL和HEL两种模式。 • 网络联机功能 DirectPlay可以程序员更容易地开发多人联机游戏。并支持各种通讯协议。

  5. COM • COM 就是 Component Object Model( 组件对象模型)。 • COM 接口和C++的抽象类相似,COM描述了一套符号和语法而非实现过程。 • DX 就提供了一套完整的设计3D游戏的库。使用DX时,不必直接接触硬件,而由DX进行代理。 • 使用 COM 时应该注意,必须在程序结束前释放所有的 COM 对象(或接口)。而且,释放它们的顺序应该和创建它们的顺序相反。

  6. 设置DirectX开发环境 • 步骤1:安装DirectX SDK; • 步骤2:设置应用程序中的头文件目录; • 步骤3:添加所需的头文件; • 步骤4:设置项目链接时所需的库文件,方法有两种: • 1、应用程序中使用 #pragma comment(lib,“xxxx.lib”) (推荐) • 2、在项目设置中添加库文件

  7. 第一种方法

  8. 第二种方法

  9. Direct3D的特色 WIN32 Application WIN32 Application Direct3D API GDI Hal Device Device Driver Interface(DDI) Graphics Hardware

  10. 硬件抽象层 • Direct3D通过硬件抽象层(HAL)提供设备无关性。HAL是一个设备相关的接口,由设备制造商提供,HAL可以是显示驱动程序的一部分,或者是一个单独的动态链接库。 • HAL通过驱动程序开发人员定义的私有接口与显示驱动程序进行通信。应用程序则通过Direct3D API来实现显示。 • Direct3D选择HAL设备时,可以充分利用硬件的特性,如硬件加速等。

  11. 建立3D环境 • 一个标准的3D框架可以分为以下几个部分: • 创建Direct3D接口和设备接口。 • WinMain:Win32程序的入口点,代码会从这里开始执行。这是我们注册、创建、显示窗口的地方。然后,我们要初始化Direct3D并进入游戏循环(Game Loop)。 • WinProc:这是应用程序的消息处理过程。Windows发给我们的程序的消息,都要有它处理。 • InitD3D:这个函数是用来初始化Direct3D的。首先,创建IDirect3D9对象,通过这个对象我们得到了当前屏幕的显示模式。然后,根据刚刚我们获取的信息(显示模式),创建了兼容的设备。

  12. 建立3D环境 • Render:首先,我们清除了后缓冲区准备作画。然后,调用了BeginScene函数来告知DX我们要作画了。结束了绘制后我们调用EndScene来告知DX我们画完了。最后,我们调用了Present来完成关键的一步:翻动后缓冲区到前缓冲区(屏幕)。这时,用户就能看到我们画的东西了。 • CleanUp:我们在此做清洁工作:释放所有的被创建的对象 。

  13. 建立3D环境 #include <d3d9.h> LPDIRECT3D9 g_pD3D=NULL; LPDIRECT3DDEVICE9 g_pd3dDevice=NULL; 导入头文件 声明接口指针 注册窗口类 创建DIRECT3D9对象,获取显示卡 的显示模式,然后根据这些信息创建 DIRECT3D9设备。 初始化D3D设备 显示窗口 利用DIRECT3D9设备进行场景的绘制。 消息循环 释放所有对象 程序结束 建立3D环境

  14. 绘制3D几何图形 • 所有的 3D 图形都是由三角形构成的。 • 顶点:顶点就是3D空间中的一个点。在3D空间中,你可以用三个顶点来指定一个三角形。 • 灵活顶点格式:是用来描述顶点属性的一种格式,而这种格式是可以由我们自定义的 。顶点属性一般有:X,Y,Z值,以及颜色和亮度等。 • 顶点缓冲:顶点缓冲就是一块用于保存顶点的内存缓冲区。 • 颜色:在DirectX中,如果我们要指定一种颜色,我们可以用D3DCOLOR_XRGB宏。

  15. 绘制3D几何图形 • 坐标系:3D 迪卡尔坐标系统 • 背面拣选:这所有的三角形面,面向我们的面将会被渲染出来(可见),否则将不被渲染(不可见,被拣选出来了)。

  16. 绘制3D几何图形 • 3D环境:三个矩阵——世界矩阵 、视图矩阵 、投影矩阵 。 • 创建模型:即定义3D图形的所有顶点属性。 • 设备数据源:当3D模型设置好后,我们就可以绑定该顶点缓存区到设备数据源。进行3D图形的渲染。

  17. 矩阵变换 矩 阵 变 换 的 基 本 公 式 缩小或放大

  18. 矩阵变换的实现 D3DXMatrixMultiply(&mat2, & mat1, &mat0); //矩阵相乘, mat1* mat0-> mat2 D3DXMATRIX *D3DXMatrixTranslation( //矩阵平移 D3DXMATRIX* pOut, //输出 FLOAT x, FLOAT y, FLOAT z ); D3DXMATRIX *D3DXMatrixRotationX( //矩阵旋转 D3DXMATRIX* pOut, //输出 FLOAT Angle // 角度. ); D3DXMATRIX *D3DXMatrixScaling( //矩阵缩放 D3DXMATRIX* pOut, //输出 FLOAT sx, FLOAT sy, FLOAT sz ); Device->SetTransform(D3DTS_XXXX, &XXXXX);

  19. 顶点格式 • Direct3D让我们可以灵活的构造自己的顶点格式。换句话说,我们可以自己定义顶点的成员。 • 为了创建一个自定义的顶点结构,我们首先要创建一个包含能存放我们选择的顶点数据的结构 . struct ColorVertex { float _x, _y, _z; DWORD _color; }; struct NormalTexVertex { float _x, _y, _z; float _nx, _ny, _nz; float _u, _v; }; 包含了位置 和颜色信息 包含了位置 法线向量 纹理坐标

  20. #define FVF_COLOR (D3DFVF_XYZ | D3DFVF_DIFFUSE) 顶点结构表明它包含位置和颜色属性 #define FVF_NORMAL_TEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1) 顶点结构表明它包含了位置,法线向量,纹理坐标的属性 灵活顶点格式(FVF) 旋转的三角形

  21. 图元 • 图元就是设备所支持的原始的类型。它包括:点列、线列、线代、三角形列、三角形带 和 三角扇形。 Triangle Strips (三角形带)

  22. 立方体的绘制 • 三角形带: • 立方体的分割:

  23. 3D物体的绘制 g_pD3DDevice->BeginScene(); //Rendering our triangle g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CUSTOMVERTEX)); g_pD3DDevice->SetVFV(D3DFVF_CUSTOMVERTEX); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); //End the scene g_pD3DDevice->EndScene(); 设置源缓冲区 设置顶点格式 绘制图元 旋转的三角棱

  24. 索引缓冲 • 索引缓冲就是内存中的一块用于索引顶点的区域。 • 当渲染场景时,DX会对每个顶点都进行许多计算,例如灯光、变幻等等,这样,运算量会很大。但是我们总是希望让DX做最少的运算以增加程序的效率,因此,我们需要把顶点的数目减到最少。

  25. 索引缓冲例子 在上面的例子中,我们只用了4个顶点就定义 了一个正方形,实际节约了2个顶点。

  26. 索引缓冲的实现 LPDIRECT3DINDEXBUFFER9 g_pIB; //定义 WORD indices[]={0,2,1,0,3,2,0,1,3,1,2,3}; //定义数组 g_pd3dDevice->CreateIndexBuffer(sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL); //创建索引缓冲 void *pIndices; g_pIB->Lock( 0,sizeof(indices),(void**)&pIndices,0); memcpy( pIndices,indices,sizeof(indices) ); //拷贝索引值 g_pIB->Unlock(); g_pd3dDevice->SetIndices(g_pIB); //设置索引缓冲 g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0,4,0,4); //输出

  27. 灯光 • 可以模拟出真实世界中一样的光线反射效果,受计算机计算能力的限制,只能有限地进行模拟。 • 环境光(ambient)的投射 • 直射光的投射(DIRECT) • 阴影 • 在3D环境里,阴影分为:平面阴影和内插(GOURAUD)阴影 • 平面阴影: • 在每一个表而后第一个顶点上进行颜色与打光的计算。效果较差,但速度很快 • 内插阴影:在每个表面上,利用三个顶点的颜色值进行内插计算,这种效果有点像渐变的模式。但计算量较大,速度慢

  28. 灯光 • 2.光的属性: • 光的投射方式: • 漫射(DIFFUSE) • 反射(SPECULAR) • 环境光(AMBIENT) • 光的类型 • 点光源,无方向 • 聚光灯,方向性较强 • 指定光,有方向,但没位置,如太阳光等 • 3.光的色彩属性 • 扩散(Diffuse Color):当物体被光照射时,所能反射的光 • 环绕(Ambient Color) • 放射(Emissiv Color) • 反射(Specular Color)

  29. 灯光属性 • 想要不同的光可以指定不同的属性,不是所有类型的光都拥有下面的这些属性: • Position (位置)这是在3D空间中光源的位置,例如(0, 10, 0)。 • Direction (方向)这是一个向量(例如(0, 1, 0)),表示从光源发射出来的光的方向。 • Range (范围)这是光从光源发出后所能到达的最大距离,范围以外的物体将不会接受到此光源的光。 • Attenuation (衰减)在光源到它的范围之间,光会逐渐衰减,这是很正常的。如果想要,你也可以指定让光不衰减,或反而越来越亮。 • Diffuse Light (漫反射)光的漫反射颜色。漫射光是分散的,但仍然具有方向,不像环境光没有方向。 • Ambient Light (环境光)这是环境光的颜色,它是通用的背景光,它是分散的且没有方向和光源,它充满整个场景。

  30. 灯光类型 • Ambient Light (环境光)可以为场景指定通用的环境光,与其它灯光互不影响,用红、绿、蓝三个分量来设置颜色。 • Point Light (点光源)它没有方向(因为向全部方向发出),但是有颜色、范围和衰减。例如电灯. • Directional Light (直射光)直射光具有颜色,没有位置。场景里的所有对象都会从同样的方向接收到同样的光。直射光也没有范围和衰减。例如太阳光. • Spotlight (聚光灯)它具有位置、方向、范围、发光内径和发光外径属性,光照强度还会随距离而衰减。例如:手电筒.

  31. 设置灯光 • 打开光照处理: SetRenderState( D3DRS_LIGHTING, TRUE ); • 创建灯光: D3DLIGHT9 light; ::ZeroMemory( &light, sizeof(D3DLIGHT9) ); light.Type = D3DLIGHT_DIRECTIONAL; //灯光类型 light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; light.Direction = D3DXVECTOR3( -1.0f, -1.0f, 0.0f ); light.Range = 1000.0f;

  32. 材质 • 材质:用于描述对象(三角形)的反光性能,使它看起来有没有光泽和带有什么颜色。 • 下面是描述材质的一些设置: • Diffuse Reflection (漫反射)物体的漫反射颜色,能使物体看起来是什么颜色。 • Ambient Reflection (环境反射)这也是一个颜色值,用于描述对象反射环境光的数量。你甚至可以指定它根本不反射环境光,这意味着它将不可见,除非接收到其它类型的光。 • Specular Reflection and Power (镜面反射与高光强度)镜面反射的值,可以用镜面反射和高光强度设置对象,使它看起来发亮。 • Emission (放射)使物体自发光,但不会影响到场景内的其它物体。

  33. 设置材质 D3DMATERIAL9 mtrl; ::ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) ); mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f; mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f; mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f; mtrl.Specular.r =mtrl.Emissive.r= 0.0f; mtrl.Specular.g =mtrl.Emissive.g= 0.0f; mtrl.Specular.b =mtrl.Emissive.b= 0.0f; mtrl.Specular.a =mtrl.Emissive.a= 0.0f; 灯光与材质

  34. 顶点法线 • Direct3D需要知道顶点法线以便它能够确定灯光照射到物体表面的角度,并且一旦计算了每个顶点的灯光,Direct3D需要知道每个顶点的表面方向。注意顶点法线不一定和面法线相同。 • 为了描述顶点的顶点法线,我们必须更新原来的顶点结构 .(如前叙) 阴影的实现

  35. 纹理 • 纹理 :赋于某物体一定的纹理属性 • 多种贴图方式(参见:3DMAX里的材质与贴图演示) • 纹理的基本概念 • 纹理坐标:纹理坐标的作用是在纹理上指定一个点,因为纹理是2D的,所以我们仅需要两个值 • U V值:取值范围:0-1.0f • 纹理映射 :把纹理应用到对象上,这个过程就叫做“纹理映射”。在此过程中,纹理坐标会被映射到顶点上,所以,顶点将额外增加两个值:U和V。

  36. 纹理映射举例

  37. 纹理过滤 • 最近点取样: • 过滤的效果不是很真实,但它的运算速度最快 • 在匹配大小时,对材质进行同比放大,因此较为粗糙.但因为速度快,因此常准备一些较大型的材质图做为贴图用. • 线性过滤 • 将与像素点相邻的最近四个像素点之间做加权平均的运算. • 也有失真,但比最近点取样要好 • Mipmap过滤: • 采用智能贴图技术,离观者近的,给高的细节,远的,则给出较粗的细节,这样,符合人们的观察习惯,又保证了精度 • 缺点:计算时占用较多的系统资源 • 非线性过滤 • 效果最好,但也最浪费系统资源

  38. 设置纹理 Struct CUSTOMVERTEX { FLOAT x, y, z; DWORD colour; FLOAT tu, tv; //纹理坐标 }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) //顶点格式 LPDIRECT3DTEXTURE9 m_pTexture; //定义纹理 D3DXCreateTextureFromFile(g_pd3dDevice, szTextureFilePath, &m_pTexture)) //加载纹理, szTextureFilePath为纹理图片 为每个顶点设置纹理坐标

  39. 模型 • 1.构成三角形的方法 • 基础:任何3D模型(含平面模型)都是由三角形这个基本的几何图形来构成。 • 三角形清单: • 在使用三角形之前,要先进行顶点的定义。 • 特点:一个三角形由三个点决定,N个三角形则需要3*N个顶点。

  40. 三角形带: • 对于连成一片的三角形,进行重复使用 • 使用一个三角形的后两个顶点与新的顶点构成新的三角形。 • 三角形扇: • 以一个顶点为基准,以基他顶点来构成多个三角形。 两个三角形构成一个四边形,但只有4个顶点。

  41. 2 加载 .X 文件 • 方法: • 调用D3D的D3DXLoadMeshFromX 函数将 .X文件中的顶点数据读入到顶点缓冲区。 • 加载必要的材质。 • D3DXLoadMeshFromX函数原型 • HRESULT WINAPI D3DXLoadMeshFromX(       LPCTSTR pFilename,      • DWORD Options,      • LPDIRECT3DDEVICE9 pD3DDevice,      • LPD3DXBUFFER *ppAdjacency,      • LPD3DXBUFFER *ppMaterials,      • LPD3DXBUFFER *ppEffectInstances,      • DWORD *pNumMaterials,      • LPD3DXMESH *ppMesh ); 绘制模型文件

More Related