深入Managed DirectX9(六)

[原创]Managed DirectX 基础使用教程(零) hangtao_me@yahoo.com.cn        由于下学期的毕业设计,最近开始研究起了.NET平台下的DirectX.本来是不打算用DirectX的,因为我不会DirectX - -||。但是DEMO出来后,发现用C#的GDI+绘图的效率是如此低下。最后不得不得硬着头皮上DirectX。而且是资料相对较少的Managed DirectX(托管版DX)。很多都是直接 阅读详情
更多渲染技术
在讨论过了基础渲染方法之后,我们应该把注意力放到一些能提高性能,并且让场景看起来更好的渲染技术上来:

渲染各种图元类型
至今位置,我们只渲染过一种类型的图元,称为三角形集合。实际上,我们可以绘制很多种不同类型的图元,下边的列表描述了这些图原类型:
PointList――这是一个自我描述的图元类型,它把数据作为一系列离散的点来绘制。不能使用这种类型绘制indexed primitives。
LineList——把每一对点作为单独的直线来绘制。使用时至少需要有两个顶点。
LineStrip——把顶点绘制为一条折线。至少需要两个顶点。
TrangleList——这就是我们一直在使用的类型。每三个顶点被绘制为一个单独的三角形。通过当前的剔除模式来决定如何进行背面剔除。
TrangleStrip——三角形带是一系列相连的三角形,每两个相邻的三角形共享两个顶点。剔除模式会自动翻转所有偶数个三角形(flipped on all even-numbered triangles),因为相邻的三角形共享两个顶点,他们会被翻到反方向。这也是复杂的3D对象使用的最多的图元类型。
TrangleFan——与三角形带相似,不过所有的三角形都共享一个顶点。


  可以使用同样的数据来绘制任意类型,任意数量的图元。Direct3D会根据给定的图元类型来绘图。写一点来嘛来绘制一下这几种图元吧。
修改我们创建顶点缓冲时的代码。因为不需要移动顶点,可以把SetupCamera里的world transform删除了,同样所有引用到angle成员的代码也可以删除了。添加一下代码:
private const int NumberItems = 12;

12虽然是随便挑选的数字,但也有一定的原因。太多的顶点会让屏幕太拥挤,同时,顶点的数量要同时能被2和3整除。这样无论那种图元都能都被正确的渲染。接下来修改创建顶点缓冲的代码:

vb=new VertexBuffer(typeof(CustomVertex.PositionColored), NumberItems, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format,Pool.Default);
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[NumberItems];
for(int i=0;i<NumberItems;i++)
{
    float xPos = (float)(Rnd.NextDouble()*5.0f) - (float)(Rnd.NextDouble()*5.0f);
    &#8226;&#8226;&#8226;&#8226;&#8226;&#8226;(详见源码)(编辑注:此处原文如此,有待修改)
    verts[i].SetPosition(new Vector3(xPos,yPos,zPos));
    verts[i].Color = RandomColor.ToArgb();
}

这里没有什么特别的地方,我们修改了顶点缓冲大小来保存足够多的顶点。接下来,修改了创建顶点的方法,用一种随机的方式来填充顶点。你可以在源码中找到关于Rnd和RandomColor的声明。

现在需要修改绘图方法了。不停的滚动显示几种类型的图原,可以简单的展示出他们之间的联系。我们每两秒钟显示一种类型。可以根据开机时到现在为止的相对时间(in ticks)来计时。添加一下两个成员变量的声明:

private bool needRecreate = false;
private static readonly int ImitialTickCount = System.Environment.TickCount;

第一个布尔变量控制着在每个“周期”开始的时候重新创建顶点缓冲。这样,就不必每次都显示同样的顶点。用一下代码代替简单的DrawPrimitives方法:
(见源码中带有switch的部分)

  这基本上是一段可以自我解释的代码。根据一个周期中的不同时刻,调用DrawPrimitives来绘制相应的图原。注意,由于图原类型的不同,相同数量的顶点能绘制的图原数也是不同的。运行程序,将按照PointList,Linelist,LineStrip,TragleList,TangleStrip的顺序显示图原。如果你觉得显示PointList时“点”太小看不清楚,可以通过调整render state把它稍稍放大一点:

device.RenderStare.PointSize = 3.0f;


使用索引缓冲(Index Buffer)

  还记得我们创建盒子时的带码吗,我们一共创建了36个顶点。实际上,我们只使用了8个不同的顶点而已,即正方形的8个顶点。在这样的小程序里把相同的顶点储存许多次并不会出什么大问题。但在需要储存大量数据的大得多的程序里,减少数据的重复来节约空间就显得很重要了。很幸运,Direct3D里一种成为索引缓冲的机制能让同一个图原共享他的顶点数据。

  就像他的名字暗示的那样,索引缓冲就是一块保存了顶点数据索引的缓冲。缓冲中的索引为32位或16位的整数。比如,你使用索引0,1,6来绘制一个三角形时,会通过索引映射到相应的顶点来渲染图像。使用索引来修改一下绘制盒子的代码吧,首先修改创建顶点的方法:

vb=new VertexBuffer(typeof(CustomVertex.PositionColored), 8, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format,Pool.Default);
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[8];
verts[0] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Red.ToArgb());
&#8226;&#8226;&#8226;&#8226;&#8226;(见源码OnVertexBufferCreate方法)(编辑注:此处原文如此,有待修改)

如你所见,我们戏剧性的减少了顶点的数量,仅储存正方形的8个顶点。既然已经有了顶点,那36个绘制盒子的索引应该是什么样子呢?看一下先前的程序,依照36个顶点的顺序,列出适当的索引:

private static readonly short[] indices =
{
    0,1,2, //front face
    1,3,2, //front face
    &#8226;&#8226;&#8226;&#8226;&#8226;  (编辑注:此处原文如此,有待修改)
}

为了便于阅读,索引分为3个一行,表示一个特点的三角形。第一个三角形使用顶点0,1,2第二个使用1,3,2;以此类推。仅仅有索引列表是不够的,还需要创建索引缓冲:

private IndexBuffer ib = null;

这个对象就是储存并且让Direct3D访问索引的地方。它与创建顶点缓冲的方法也很相似。接下来初始化对象,填充数据:

ib = new VertexBuffer(typeof(short),indices.Length,device,Usage.WriteOnly,Pool.Default);
ib.Created += new EventHandler(ib_Created);
OnIndexBufferCreate(ib,null);

private void ib_Created(object sender, EventArgs e)
{
    IndexBuffer buffer = (IndexBuffer)sender;
    buffer.SetData(indices,0,LockFlags.None);
}

  除了参数的约束条件以外,索引缓冲的构造器简直就是一个模子里出来的。与前面提到的一样,只能使用16位或32位的整数作为索引。我们订阅了事件处理程序,并且在程序第一次运行时手动调用他。最后为索引缓冲填充了数据。

  现在,需要修改渲染图像的代码来使用这个数据了。如果你还记得,我们以前使用了一个叫“SetStreamSource”的方法来告诉DirectX渲染的时候使用哪一快顶点缓冲。同样,对于索引缓冲来说也有这样一种机制,不过它仅仅只是一个属性而已,因为同一时间只可能使用一种类型的索引缓冲。在SetStreamSource之后,设置如下属性:

device.Indices = ib;

  这下Direct3D知道顶点缓冲的存在了,接下来修改绘图代码。目前,我们的绘图方法尝试从顶点缓冲绘制12个图原,可是这必然不会成功,因为现在顶点缓冲里只有8个顶点了。添加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);
    device.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,8,0,indices.Length /3);
}

这里,我们把DrawPrimitives改为了DrawIndexedPrimitives。来看看这个方法的原型吧:

public void DrawIndexedPrimitives(PrimitiveType primitiveType,int baseVertex ,int minVertexIndex,int numVertices, int startIndex, int primCount);

第一个参数和上一个方法的一样,表示要绘制的图原类型。参数baseVertex表示从索引缓冲起点到要使用的第一个顶点索引的偏移量。MinVertexIndex是这几个顶点中最小的顶点索引值。很显然,numVertices指的就是所要使用的顶点数量。startIndex表示从数组中的哪一个位置开始读取顶点。最后一个参数则是要绘制的图原数量。

现在通过索引缓冲中的8个顶点,就可以绘制出了构成立方体的12个图原了。接下来用DrawBox方法代替原来的DrawPrimitives方法。

DrawBox(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
(略,详见源码)

  再次运行程序,可以看到颜色非常鲜艳的盒子在旋转。我们的每一个顶点都有不同的颜色,因此,真实的反映了使用索引缓冲共享顶点的缺点。当多个图原共享顶点的时候,所有的顶点数据都是共享的,包括颜色,法线数据等等。当决定是否共享顶点时,必须确定共享数据不会带来灯光或颜色上的错误(因为灯光的计算依赖于法线)。可以看到立方体每个面的颜色都是由顶点颜色插值计算出来的。


使用深度缓冲(Using Depth Buffer)

  深度缓冲(depth buffer)(也就是通常所说的z-buffer或w-buffer)是Direct3D在渲染时储存“深度”(“depth”一般指方向为从屏幕指向观察者的z轴的窗口坐标)。深度信息用于在光栅化时决定象素之间的替代关系(注:度通常用视点到物体的距离来度量,这样带有较大深度值的象素就会被带有较小深度值的象素替代,即远处的物体被近处的物体遮挡住了)。至今为止,我们的程序都没有使用过深度缓冲,所以光栅化时没有象素被遮挡住。除此之外,我们甚至还没有会相互重叠的象素,那么,现在来绘制一些会与已有的立方体重叠的的立方体吧。

在已有的DrawBox方法调用后添加如下代码:

DrawBox(angle / (float)Math.PI,angle / (float)Math.PI*2.0f, angle / (float)Math.PI / 4.0f,0.0f,(float)Math.Cos(angle),(float)Math.Sin(angle));
&#8226;&#8226;&#8226;(略)(编辑注:此处原文如此,有待修改)

我们在添加了三个旋转的立方体到原来中间一排的立方体上。运行程序,可以看到重叠的立方体,却不能分清两个立方体重叠部分的边界,看起来不过是一块普通的斑点而已。这就需要通过深度缓冲来处理了。

添加深度缓冲实在是一个简单的任务。记得我们传递给device构造函数的presentation parameters参数吗?well,这将是我们添加深度缓冲的地方。创建一个包含深度缓冲的device,需要用到两个新的参数:

public Mircosoft.DirectX.Direct3D.DepthFormat AutoDepthStencilFormat [ get, set ]
public bool EnableAutoDepthStencil [get,set]

把EnableAutoDepthStencil设置为true就可以为device打开深度缓冲,使用DepthFormat来指定AutoDepthStencilFormat成员。DepthFormat枚举中,可使用的值列在下表中:

D16 A 16-bit z-buffer bit depth.
D32 A 32-bit z-buffer bit depth.
D16Lockable A 16-bit z-buffer bit depth that is lockable.
D32Flockable A lockable format where depth value is represented by a standard IEEE floating point number.
D15S1 A 16-bit z-buffer bit depth using 15 bits for depth channel, with the last bit used for the stencil channel (stencil channels will be discussed later).
D24S8 A 32-bit z-buffer bit depth using 24 bits for depth channel, with the remaining 8 bits used for the stencil channel.
D24X8 A 32-bit z-buffer bit depth using 24 bits for depth channel, with the remaining 8 bits ignored.
D24X4S4 A 32-bit z-buffer bit depth using 24 bits for depth channel, with 4 bits used for the stencil channel, and the remaining 4 bits ignored.
D24FS8 A non-lockable format that contains 24 points of depth (as a floating point) and 8 bits for the stencil channel.

深度缓冲越大,能储存的深度数据也越多,但这是以牺牲性能为代价的。除非你确定需要使用很大的深度缓冲,否则使用最小的值就可以了。大部分现代的图形卡都支持最小16-bit的深度缓冲,so,添加代码:

presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.SwapEffect = SwapEffect.Discard;

Perfect,现在device获得了深度缓冲。来看看有什么不同吧,运行程序。哇,结果并不是我们期盼的那样,程序被破坏了。这些立方体发生了什么?为什么加入了深度缓冲之后导致渲染被破坏了呢。呵呵,原因是深度缓冲从来没有被“cleared”,所以它一直处于一种不正确的状态。应该在clear device的同时clear深度缓冲,修改代码如下

device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);

Ok,一切正常了,休息一下来欣赏我们的作品吧^_^。

  

用Managed DirectX 9和C#实现3D地形可视化 介绍:GIS(Geographical Information System) 是一种通过计算机系统实现地图显示的系统。可以让用户进入,显示并分析地理数据。由于大多数人不了解GIS,所以经常在IT市场上有几家大企业垄断该行业比如Intergraph, Bentley, MapInfo, Autodesk 和 ESRI,如今全球IT垄断企业微软,Google 和 Oracle 正在竞争建立一个虚拟地 阅读详情

相关推荐

DirectX9 3D 快速上手(深入Managed DirectX9)

DirectXDirectX9 3D 快速上手(深入Managed DirectX9)9 3D 快速上手(深入Managed DirectX9)

【翻译】Managed DirectX(第四章)

更多渲染技术翻译:clayman     在讨论过了基础渲染方法之后,我们应该把注意力放到一些能提高性能,并且让场景看起来更好的渲染技术上来: 渲染各种图元类型     至今位置,我们只渲染过一种类型的图元,称为三角形集合。实际上,我们可以绘制很多种不同类型的图元,下边的列表描述了这些图原类型:     PointList――这是一个自我描述的图元类型,它把数据作为一系列离散的点来绘制。不能使用这

Clayman的专栏 3721

Nginx下ModSecurity模块安装详细教程

本文提供了在Nginx 1.28.0上安装ModSecurity v3的完整教程。首先需安装编译依赖,然后从源码编译安装ModSecurity库并设置优化参数。接着编译Nginx动态模块并配置加载。核心配置包括设置规则引擎、日志路径及性能优化参数。安装OWASP核心规则集后,在Nginx站点配置中启用ModSecurity。最后测试规则有效性并给出性能优化建议,如规则排除、精简规则集等。整个过程包含详细的命令和配置示例,确保安全防护功能正常运作。

深山技术宅的博客 1783

DirectX 3D灯光和材质

前面所介绍的东西都假设模型有自己的颜色,即认为模型自己发光。其实自然界的大部分物体并不发光。当光线照射到物体上,物体吸收某些颜色的光,反射另一些颜色的光,反射的光的颜色就是我们所看到的物体的颜色。这里的灯光是指光源,在Direct 3D中有4种光源:环境光、定向光源、点光源和聚光灯。反射光被分为3类:环境光、漫反射光和镜面高光。材质描述物体反射光的反射属性。可以用法线来计算光的反射,光照的反射强度

面目全非,胸有丘壑 | Json Lee 1803

PyBioMed学习

PyProtein。

weixin_63016274的博客 1401

Windows游戏玩家必看:用Process Lasso优化CPU优先级和核心绑定,告别卡顿

本文为Windows游戏玩家详细介绍了如何使用Process Lasso优化系统性能。通过设置CPU优先级和核心绑定,可以智能管理进程资源,确保游戏获得最高调度权限,有效减少因后台程序干扰或Windows调度机制不完善导致的卡顿与帧数波动,从而提升游戏流畅度与稳定性。

weixin_29299807的博客 2217

PrimitiveType 枚举

 成员名称说明 LineList将顶点呈现为一系列独立的直线段。如果顶点计数小于二或是奇数,则使用此基元类型的调用将失败。  LineStrip将顶点呈现为单个折线。如果顶点计数小于二,则使用此基元类型的调用将失败。  PointList将顶点呈现为独立的点的集合。带索引的基元不支持此值。  TriangleFan将顶点呈现为三角扇形。  TriangleList将指定顶点呈现为一系列独立的三角形。每三个顶点为一组,定义一个单独的三角形。背面剔除受当前顶点连接顺序呈现状态的影响。  TriangleStri

熊小屁的专栏 849

《uni-app 长列表优化:虚拟列表(vue-virtual-scroller)解决 1000+ 数据渲染卡顿》(附虚拟列表封装与多端适配)

本文详细介绍了虚拟列表技术在前端长列表渲染中的优化方案。针对传统v-for渲染导致的性能问题(内存占用高、渲染阻塞、滚动卡顿),提出基于vue-virtual-scroller的虚拟列表解决方案,通过可视区域渲染和DOM复用实现性能突破。文章包含核心原理、组件封装、多端适配及性能对比,并给出常见问题的解决方法。实践表明,该方案可将1000条数据的首次渲染时间从3800ms降至420ms,滚动FPS提升至55帧,显著改善用户体验。

qq_59041750的博客 2107

图形学中D3DPRIMITIVETYPE的几种类型名称

typedef enum _D3DPRIMITIVETYPE {     D3DPT_POINTLIST             = 1,     D3DPT_LINELIST              = 2,     D3DPT_LINESTRIP             = 3,     D3DPT_TRIANGLELIST          = 4,//三角形列     D3DPT_TRI...

luoshao_的博客 576

【推荐100个unity插件】动画重定向,快速在不同角色间共享动画,共用非人形Humanoid(泛型generic)动画——Retarget Pro

Retarget Pro是一款高效的Unity动画重定向工具,可快速在不同角色间共享动画。主要特点包括:1分钟快速设置,支持编辑器和运行时重定向;适用于人形、动物、武器等各类角色;提供基础重定向、IK重定向和FPS专用重定向三种功能模块;通过Rig组件和骨架资产实现骨骼链匹配,支持批量处理。插件包含示例项目和预设资源,操作简便且效果优于Unity原生Humanoid系统,特别适合处理手指等精细动画。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 546

【SMPL简介】SMPL: A Skinned Multi-Person Linear Model【源码复现】

SMPL是一种3D人体建模方法.在数字人或者人物角色三维重建领域有着广泛应用支持人体的各种形状及动作可以简单理解为通过训练获取的人物模型SMPL 输入是:姿态shape vectorβ\betaβ+ 影响动作Pose的参数θ\thetaθ输出是: 各种变化后vertex顶点的数据作者:Loper, Matthew and Mahmood, Naureen and Romero, Javier and Pons-Moll, Gerard and Black, Michael J.

zik的博客 3369

使用C# + Managed DIrectX 制作 2D 游戏使用C# + Managed DIrectX 制作 2D 游戏

主旨:虽然目前Microsoft已经发布了XNA Game Studio,让游戏编程员能够更轻松的在Windows(XB360不在本文考虑范围内)制作游戏,不过这个XNAGS有个缺点,它要求系统必须有至少能够支援Shader Model 1.1的显示卡。这表示TNT,GeForce 1, 2, 和 GeForce 3 & 4 MX 系列的显示卡,以及较早期的 integrated display

shaily读书学习 6785

UWB:FiRa Consortium UCI Generic Technical Specification v1.1.0(2)- 核心控制消息;会话管理;测距会话管理

测距是UWB最核心的应用。为了方便应用调用测距接口,FIRA统一了UCI命令格式,这样各个厂商可以互相兼容。

Ankie资深技术项目经理 1277

Managed DirectX +C# 开发(入门篇)(一)

  前      言以前是用VC 作计算机图形学的,大约在一年前,公司接到一个用C#+DirecX的项目,从那时起便开始学习Mangaged DirectX ,现将在开发过程中的一点总结发表出来,和同行们共同参考,共同学习,共同进步,前面是一些基础内容,算是入门篇吧,现在正将开发过程中所用到的一些算法整理中,算是中级篇吧。1:在整理过程中,有些内容为从网上找的资料,部分为翻译国外文章,正所

dandanCool的专栏 8816

基于GA-BP遗传算法优化神经网络的多输入多输出数据预测-Python代码实现

多输入多输出的GA-BP神经网络

2301_80449389的博客 2308

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Managed DirectX® 9 学习笔记(1)

Managed DirectX® 9学习笔记第一章       介绍1、命名空间Table 1. Managed DirectX NamespacesMicrosoft.DirectXParent namespace, holds all common code.Microsoft.DirectX.Direct3DDirect

ycl的专栏 1649

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

很好的几个Managed Directx 例子

2014/09/25 (转载自:http://www.codesampler.com/dx9src/dx9src_2.htm)

narutojzm1的博客 1429

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

深入Managed DirectX9(四)

深入Managed DirectX9(四)     选择正确的Device  The number of possible permutations when cre

屋檐滴雨 934

DirectX 9, Managed DirectX download link.

http://www.microsoft.com/downloads/details.aspx?FamilyId=FD044A42-9912-42A3-9A9E-D857199F888E&displaylang=en 转载于:https://www.cnblogs.com/runmin/archive/2004/09/07/40600.html

weixin_30776273的博客 249

使用Manged DirectX 9.0 --- Part I

1181

Managed DirectX中的DirectShow应用(简单Demo及源码)

阅读目录 介绍 准备工作 环境搭建 简单Demo 显示效果 其他 Demo下载 介绍   DirectX是Microsoft开发的基于Windows平台的一组API,它是为高速的实时动画渲染、交互式音乐和环境音效等高要求应用开发服务的。   而Managed DirectX 实质上是对DirectX进行了一个轻量级的封装,Microsoft在2003年...

223

使用Manged DirectX 9.0

 HTML Tags and JavaScript tutorialvar encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);

332

3D Terrain Visualisation in Managed DirectX 9 and C#

http://www.codeproject.com/cs/media/3D_Terrain_Visualisation.asp3D Terrain Visualisation in Managed DirectX 9 and C#By Igor Stjepanovic In this project I demonstrate how to write a simple 3D renderi

净心编程 1223
上一篇: 深入Managed DirectX9(五)
下一篇: 基础html代码大全参考
minw100
博客等级 码龄22年 6粉丝 8原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值