【翻译】Managed DirectX(第五章)

东北同胞们

东北同胞们

2016-01-29 13:09

【翻译】Managed DirectX(第五章),【翻译】Managed DirectX(第五章)
Rendering with Meshes
翻译:claymanclayman_joe@yahoo.com.cn
定义Mesh 虽然有很多时候,你需要手动创建顶点和索引数据,但更普遍的情况是从外部的资源加载已有的顶点数据,比如从一个文件。通常我们使用.X文件来保存这些信息。在前一章里,代码的大部分都用来创建几何体了。对于简单的三角形和立方体来说这似乎是完全可行的,但设想假如用相同的方式来创建拥有上万个顶点的物体将,所花费的时间和努力都将是很可怕的。 幸运的是,Managed DirectX里有一个可以封装并且加载顶点和索引数据的对象,这就是Mesh。Mesh可以用来储存任何类型的图形数据,但主要用来封装复杂的模型。Mesh类同样也有一些用来提高渲染物体性能的方法。所有的mesh对象都包含了一个顶点缓冲和一个索引缓存,除此之外,他还包含了一个属性缓冲(attribute buffer)我们将会在这一章的后面讨论它。 真正的mesh对象包位于Direct3D扩展库(D3DX Direct3D Extensions library)中。添加对Direct3DX.dll程序集的引用,我们将尝试着使用mesh来创建一个旋转的立方体。首先,在声明顶点缓冲和索引缓冲成员之前添加mesh成员: private Mesh mesh = null; mesh类有三个构造函数,但现在还不需要用到其中的任何一个。Mesh类有几个静态方法可以用来创建或加载不同的模型。首先需要注意的就是Box方法,就像它的名字一样,它将创建包含了一个立方体的mesh。想想看,我们立刻就能渲染这个立方体,简直完美极了^_^(注:呵呵,可以删除之前所有与顶点缓冲、索引缓冲有关的代码了)。在创建device之后添加以下代码: mesh = Mesh.Box(device,2.0f,2.0f,2.0f); 这个方法创建了一个包含顶点和索引的mesh,并且可以渲染为一个长、宽、高都为2的立方体。它和之前用顶点缓冲手动创建的立方体大小一样。我们已经把创建物体的代码减少为一行了,不能再简单了。虽然已经创建了mesh,但可以用原来的方法来渲染它吗,还是需要另辟途径?之前,在渲染时,我们需要调用SetStreamSource来告诉Direct3D从哪一块顶点缓冲读取数据,同样还必须设置索引以及顶点格式的属性。对于渲染mesh来说,这些都是不需要的。 (tips:mesh已经内置了所有顶点缓冲、索引缓冲以及顶点格式的信息。渲染时会自动设置stream source、索引和顶点格式的属性) 那么如何渲染mesh呢?Mesh会被分为一系列的子集(subsets)(依据属性缓冲的大小来分配),同时使用一个叫做DrawSubset的方法来渲染。修改DrawBox方法: private void DrawBox(float yaw,float pitch,float roll,float x,float y,float z) { angle += 0.01f; device.Transform.World = (Matrix.RotationYawPitchRoll(yaw,pitch,roll) * Matrix.Translation(x,y,z)); mesh.DrawSubset(0); } 这里把DeawIndexedPrimitives方法改为了DrawSubset。使用Mesh类创建的普通图元总是只有一个基于0的子集。好了,这就是要让程序再次运行所作的所有改动了,出乎意料的简单。运行看看吧。 Well,再次得到了九个(在源码中是12个)旋转的盒子,但是全部变为了白色对不对?观察一下mesh中顶点的顶点格式(可以通过mesh的VertexFormat属性查看),会发现只有顶点的位置和法线数据储存在mesh中。Mesh中没有关于颜色的数据,灯光也米有打开,自然一切都是白色的。 还记得第一张中提到过,只要顶点数据包含了法线的信息,就可以使用灯光吗,既然盒子有法线数据,也许我们应该吧灯光打开。默认情况下灯光是打开的,现在可以把关闭灯光的代码删了或者设置为true。 呵呵,我们成功把白色的盒子变为黑色了-.-#。 希望你已经猜到了这是因为场景中并没有光源,所以一切都是黑色的。对于指定特定的光源而言,创建一盏能照亮整个场景的灯光将会很不错。欢迎来到环境光(ambient lighting)。 环境光为场景提供了均衡(constant)的光源。场景中所有物体都按同样的方式被照亮,因为环境光并不依赖于其它几种光源需要的因素(比如位置、方向、衰减)。甚至不需要法线数据就可以使用环境光。环境光是最高效的灯光类型,但却不能创造出真实的世界。但就现在而言,他就能达到我们满意的效果。在设置RendrState的地方添加如下代码: device.RenderState.Ambient = Color.Red; 环境光完全是由ambient render state来定义的,接受一个颜色参数。这里,我们希望全局灯光是红色的,这样可以看到明显的效果。运行程序,你希望可以看到9个红色的旋转盒子,不幸的是,它们仍然为黑色。还遗漏了些什么呢? 使用材质和灯光(Using Materials and Lighting) 这里和我们以前使用灯光有什么不同呢?最大的不同点(除了使用的是mesh之外)在于顶点数珠中没有关于颜色的信息。这导致了光照失败。 为了让Direct3D正确的计算3D物体中特定点的颜色,除了灯光的颜色之外,还需要知道物体如何反射灯光的颜色。在真实的世界里,如果把红色的灯光照在淡蓝色的表面,那么它会呈献出柔和的紫色。你还需要描述我们的表面(我们的盒子)是如何反光的。 在Direct3D里,材质(materials)描述了这种属性
展开更多 50%)
分享

猜你喜欢

【翻译】Managed DirectX(第五章)

电脑网络
【翻译】Managed DirectX(第五章)

【翻译】Managed DirectX(第六章)

电脑网络
【翻译】Managed DirectX(第六章)

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

第五章 类 (2)

编程语言 网络编程
第五章 类 (2)

第五章 温馨絮语

分娩
第五章 温馨絮语

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

行尸走肉第五章攻略

电脑网络
行尸走肉第五章攻略

第五章 类 (1)

编程语言 网络编程
第五章 类 (1)

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

VB 二进制块读写类模块应用实例 包括一个文件拷贝和一个文件二进制比较的例子

VB 二进制块读写类模块应用实例 包括一个文件拷贝和一个文件二进制比较的例子

怎样在php中使用PDF文档功能

怎样在php中使用PDF文档功能
下拉加载更多内容 ↓