登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 入门基础 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

深入Managed DirectX9(一)
发表日期:2007-03-28作者:[转贴] 出处:  

   Device类是DirectX里的所有绘图操作所必须的。可以把这个类假想为真实的图形卡。场景里所有其他图形对象都依赖于device。你的计算机里可以有一个到几个device,在Mnaged DirctX3D里,你可以控制任意多个device。

  Device共有三个构造函数,现在我们只讨论其中的一个,但我们会在后边的内容里讨论其他的。先来看看具有如下函数签名的构造函数
public Device(int adapter,DeviceType deviceType,Control renderWindow,CreateFlags behaviorFlags, PresentParameters[] presentationParameters);
(构造函数的第二种重载类似于上边这个,但它接受来自非托管(或者非windows form)的窗口句柄作为renderWindow。而只接受一个IntPtr参数的重载是非托管com组建指向Idirect3Ddevice9的接口。当你的代码需要和非托管的程序协作时则应用它)

  好了,这些参数是什么意思,以及我们怎样来使用呢?呵呵,参数adapter表示我们将要使用哪个物理图形卡。计算机里的所有图形卡都有一个唯一的适配器标识符(通常是0到你的图形卡数量-1),默认的显卡总是表示为0 的图形卡。

  下一个参数,DeviceType,告诉了DirectX3D你要创建那种类型的device。这里最常用的值就是 DeviceType.Hardware,表示你将创建一个硬件设备。另一个选项是DeviceType.Reference,这种设备允许你使用“参考光栅器”(reference rasterizer),所有的效果由DirectX3D运行时来实现,以很慢、很慢、很慢的速度运行^_^。应该仅在调试时或测试你的显卡所不支持的特性时使用这个选项。
(注意参考光栅器只包含在DirectX SDK里,so DirectX运行时是不能使用这个特性的。最后一个为DeviceType.Software的值允许使用用户自定义的软件光栅器(custom software rasterizer)在不确定是否有这样一个光栅器存在时,忽略这个选项吧^_^。)

  rendrWindow表示把设备绑定到的窗口。因为windows form控件类都包含了一个窗口句柄(windows handle),所以很容易把一个确定的类作为渲染窗口。可以使用form、panel或其他任意的控件作为这个参数的值。但现在,我们只用form。

  下一个参数用来描述设备创建之后的行为。大部分CreateFlags枚举的成员都能组合起来使用,使设备具有多种行为。但有一些flag是相互排斥的,我们稍后讨论。我们现在只使用SoftwareVertexProcessing标志。这个标志适合于所有定点处理都用CPU计算的情况。应此,这自然比所有点都用GPU处理要慢,因为我们不确定你的显卡是否支持所有特性。So,安全第一,假设你的CPU能完成现在的任务。

  最后一个参数,它表示你的设备把数据呈现到显示器的方式。Presentation Parameter类的外观都可以由这个类来控制。我们过后再来深入讨论它的构造函数,现在,我们只关心“Windowed”成员和“SwapEffect”成员。

  Windowed成员是一个布尔类型的值,决定设备是全屏还是窗口模式。
  SwapEffect成员用于控制缓存交换的行为。如果选择了SwapEffect.Flip,运行时会创建额外的后备缓冲(back buffer),并且在显示时拷贝front buffer。SwapEffect.Copy与Flip相似,但要求你把后备缓冲设为1。我们将要选择的SwaoEffect.Discard,如果缓冲没有准备好被显示,则会丢弃缓冲中的内容(which simply discards the contents of the buffer if it isn’t ready to be presented)。

学了这么多,现在来创建一个设备吧。回到代码上来,首先为我们的程序将创建一个device对象:
(代码略,参见DirectX sdk Tutorial 1: Create a Device)

现在让我们来重写Paint()函数:

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
        device.Present();
    }

  我们使用Clear()方法把窗口填充为实心的颜色。它的第一个参数指定了我们要填充的对象;在例子里,我们填充的即是目标窗口。稍后再来讨论 ClearFlags枚举的其它成员。第二个参数是我们所要填充的颜色。其他的两个参数先暂时忽略。在device被填充之后,我们必须更新显示: Present方法会为我们完成这个任务。这个方法也有几个重载的类型;上边使用的方法会显示device的整个区域。同样稍后再讨论。

  看到有些枯燥了吗,好吧,现在我们来真正绘制一些图形

  三维图形世界里最基本的图形就是三角形。使用足够的三角,我们可以呈现出任何东西,甚是是平滑的曲面。没有什么比画一个简单的三角和更好的了。为了使过程尽可能的简单,我们先避开“world space”以及各种变换(当然,我们马上就会提到他们),使用屏幕坐标来绘制一个简单的三角。再绘制我们迷人的三角前,我们必须做2件事。1,我们需要一些数据结构来保存三角的信息。2,我们告诉device来绘制它。

  很幸运,DirectX已经有这样的一个数据结构来保存三角了。Direct3D名称空间里叫做CustomVertex的类可以用来储存大多数Direct3D中用到的“顶点格式”数据结构(vertex format)。

  一个顶点格式结构把数据保存为一种DirectX3D认识并且可以使用的格式。我们将讨论很多这种结构,但先让我们来看看即将用来创建三角的 TransformedColored结构。这个结构告诉DirectX3D运行时我们的三角不需要进行左边变换(比如旋转或移动),因为我们已经指定了使用屏幕坐标系。它也包含了每一个点(顶点)的颜色的信息。回到重写的OnPaint方法添加如下代码:

    CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
    Verts[0].SetPosition(new Vector4(this.Width/2.0f,50.0f,0.5f,1.0f);
    Verts[0].Color = System.Drawing.Color.Aqua.ToArgb();
    Verts[1]`````````
    Verts[2]`````````
    (参见DirectX sdk Tutorial 2: Rendering Vertices)

  数组里的每一个元素表示三角的一个顶点,所以我们创建了3个元素。然后我们使用新创建的Vector4结构为每一个成员调用SetPositin方法。变换过的顶点坐标包含了在屏幕上x和y的坐标(相对于屏幕的(0,0)点而言),当然也包括z坐标和rhw成员(reciprocal of homogenous w三维齐次坐标)。先忽略后边两个参数.Vector4结构(注:Vector4其实就是(x,y,z,w)经过变换后成为(x/w,y/w,z/w))是保存这种信息最方便的方式。然后我们设置了点的颜色。注意,我们使用了标准颜色的ToArgb方法。DirectX3D假设所接受的颜色为32为的 int。

  既然我们已经有了数据就可以告诉DirectX我们需要绘制这个三角形,并且绘制它。在重写的OnPaint里添加如下代码

   
device.BeginScene();
    device.VertexFormat = CustomVertex.TransformedColored.Format;
    device. DrawUserPrimitives (PrimitiveType.TriangleList,1,verts); 注意和sdk中的示例有区别
    device.EndScene();

  好了,这几行代码是什么意思呢?其实很简单。BefinScene方法告诉DirectX3D我们即将绘制一些东西,为绘制做好准备。现在我们已经告诉了DirectX3D要绘制一些东西,接下来就必须告诉它画什么。这就是VertexFormat属性的作用。它决定了DirectX3D运行时使用哪种“确定的功能管道”(fixed function pipline)格式。在我们的例子里使用变换过的,着色过的顶点管道。

  不用担心你现在不明白确定的功能管道是什么意思,我们会很快来讨论它。

  DrawUserPrimitives函数是真正发生绘图的地方。So,他的参数是什么意思呢?第一个参数是我们要绘制的初等几何体的类型。有很多种可用的类型,but now,我们只是画一系列的三角形。所以选择了PrimitiveType.TriangleList类型。第二个参数是我们要绘制的三角形的数量。对于一个三角形的集合来说,这个值应该是你的顶点数量除以3。我们只画一个三角,所以设为1。最后一个参数则是DirectX3D用来绘图的数据。最后一个 EndSence方法通知DirectX3D我们不再绘图了。你必须再每次调用BeginSence之后都调用这个方法。

  如果现在编译运行程序的话,你会发现但移动或重置窗口大小之后,并不会更新显示。原因是当我们需要重绘整个窗口时,Windows并不会每一次都计算窗口的收缩情况。因此,你只是移除了显示过的数据,当并没有删除已经显示的内容。很幸运,有个简单的方法解决这个问题,我们可以告诉Windows窗口总是需要被整个的重绘。在OnPaint的最后加上一下代码:

    this.Invalidate();

  呵呵,现在再来试试看,哦,看起来我们破坏了程序!现在只能显示一片空白了,并且我们的三角看起来还在不停的闪烁,尤其是当你调整窗口大小的时候。我们都干了些什么呢?原来“聪明”的Windows总是尝试在Invalidate()方法后来绘制当前的窗口(即空白的这个窗口)。在我们的 OnPaint方法之外还存在其他的绘制过程!能容易的通过改变窗口的“style”属性来解决。在构造函数里加上如下代码

    this.SetStyle(ControlStyles.AllPaintingInWmPaint | ConstolStyles.Opaque, true);

  哦~,好了,终于erying works as expected。我们所做的就是告诉Windows一切绘图过程都在OnPaint里完成。

(第一部分完,下一步分我们将开始真正的3D之旅,使我们的三角形三维化)
我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 深入Managed DirectX9(一)

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00226