当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 【翻译】Managed DirectX(第五章)

ASP.NET
ASP.NET开发:简化应用程序的开发支持Web标准
asp.net XMLHttpRequest实现用户注册前的验证
asp.net 页面间传值方法小结
asp.net url重写浅谈
asp.net 验证码生成和刷新及验证
C#精髓 GridView72大绝技 学习gridview的朋友必看
实例说明asp.net中的简单角色权限控制
asp.net网站开发包wq.dll打包下载
js与ASP.NET 中文乱码问题
asp.net checkbox 动态绑定id GridView删除提示
asp.net TextBox回车触发事件 图片在img显示
asp.net 脏字典过滤问题 用正则表达式来过滤脏数据
asp.NET 脏字过滤算法
asp.NET 脏字过滤算法 修改版
asp.net sql 数据库处理函数命令
asp.net Javascript 的几种写法与提示
ASP.NET MVC学习笔记
asp.net 中国身份证号码验证代码 非正则
Asp.net中使用Sqlite数据库的方法
asp.net 中文字符串提交乱码的解决方法

ASP.NET 中的 【翻译】Managed DirectX(第五章)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 113 ::
收藏到网摘: n/a

Rendering with Meshes
翻译:[email protected]
定义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)描述了这种属性