第四章 入门程序
一、创建设备
本节介绍的示例为DirectX SDK自带的示例,在这里将其解释一下,本示例什么也不做,只是显示一个空白窗体。
现在先看程序运行的主函数:
static void Main()
         {
//建立一个窗体实例;
            using (CreateDevice frm = new CreateDevice())
            {
//如果窗体实例创建成功,那么对Direct3D进行初始化
               if (!frm.InitializeGraphics())
                {
//如果未能进行初始化,则显示一个错误消息,并返回退出程序;
                    MessageBox.Show("Could not initialize Direct3D. This tutorial will exit.");
                    return;
                }
//如果成功进行初始化,则显示窗体;
                frm.Show();
// 如果窗体处于运行状态,则一直执行frm.Render();
 while(frm.Created)
                {
                    frm.Render();
                    Application.DoEvents();
                }
            }
         }
因为这个程序主要是为创建一个界面,因此主要的函数为frm.InitializeGraphics(),下面看它的代码:
public bool InitializeGraphics()
         {
              try
              {
                   PresentParameters presentParams = new PresentParameters();
                   presentParams.Windowed=true;
                   presentParams.SwapEffect = SwapEffect.Discard;
                   device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
                   return true;
              }
              catch (DirectXException)
            {
                return false;
            }
         }
注意,程序事先已定义了一个全局变量device,它是在DirectX里的Device类,是所有绘图操作所必须的,相当于我们机器里的图形卡,图形对象都依赖于所定义的这个类,其实,可以设置多个device。
代码
PresentParameters presentParams = new PresentParameters();
是一组参数,用来设置设备把数据呈现在显示器的方式。比如,接下来的下面语句的设置
presentParams.Windowed=true;表示我们的程序是全屏显示还是窗口显示。
下面的参数设置用于控制缓存交换的行为。在这里选取的这个选项表示,如果缓冲没能准备好显示,那么就丢弃缓冲区中的数据;另外一外有用的选项是SwapEffect.Flip,如果选择了这个选项,那么在运行时会创建一个额外的缓冲区,并且在显示把缓冲区的内容拷贝到前景中。
presentParams.SwapEffect = SwapEffect.Discard;
接下来的代码是构造device:
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
构造函数的第一个参数表示将使用哪个物理图形卡,通常个人机器内只装有一个图形卡,但对于专业人员则就不一定了。这样如果机器内有两块图形卡,就可以用0或1来区分开是用哪块图形卡,默认的显卡表示为0的图形卡;
第二个参数,为设备的类型,现在选用的是创建一个硬件设备,但如果有时我们的显卡不支持某种功能时,可以选择DeviceType.Reference;
第三个参数是表示把设备绑定到哪个对象上,可以是整个窗体,或者是窗体上的一个控件,在这里选择是整个窗体。
第四个参数描述的是创建之后的行为。这些枚举成员可以组合起来使用,使设备具有多种行为。在本程序中使用的适合于所有顶点处理都用CPU计算。显然,比所有顶点都用GPU计算要慢一些。
第五个参数表示把数据显示出来的方式,前面已经说过了。
至此,图形的初始化工作完成,接下来当程序运行时,当界面发生变化时,会执行OnPaint()函数。
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
         {
              this.Render();
         }
在这里面,执行this.Render();现在再来看看这个函数都做了哪些工作。
private void Render()
         {
//如果设备没有创建成功,则返回
              if (device == null)
                   return;
         //使用兰色填充背景
              device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
              //开始绘图。
              device.BeginScene();
              //以后我们的绘图工作都在这里完成;
              device.EndScene();
              device.Present();
         }
二、创建一个三角形
接下来,我们往场景是添加一个三角形,此示例的完整代码也可以在SDK中找到。
绘一个三角形很简单,只需三个点就可以了,为什么是三角形而不是四边形、五边形的原因是,大家都知道,“不在同一直线上的三点决定一个平面”,因此利用大量三角形可以组合成3D世界里的芸芸众生。当然也可以使用四边形来做,但处理的工作量显然加大了。
为了保存点数据,在这里使用Direct3D名称空间的CustomVertex类,来存储顶点坐标,
代码是:
CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0].X=150;verts[0].Y=50;verts[0].Z=0.5f; verts[0].Rhw=1; verts[0].Color = System.Drawing.Color.Aqua.ToArgb();
verts[1].X=250;verts[1].Y=250;verts[1].Z=0.5f; verts[1].Rhw=1; verts[1].Color = System.Drawing.Color.Brown.ToArgb();
verts[2].X=50;verts[2].Y=250;verts[2].Z=0.5f; verts[2].Rhw=1; verts[2].Color = System.Drawing.Color.LightPink.ToArgb();
在这里定义了一个含有三个元素的数组,CustomVertex.TransformedColored[],这种顶点类型为带有颜色无变换的顶点类型,带有颜色很好理解,无变换后面会介绍到它。
程序另外一部分代码是创建顶点缓冲区,后面会介绍到它。
在Render()函数中:
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
表示我们会绘制一系列三角形,顶点为顶点缓冲区中从0开始,第三个参数1表示只绘制一个三角形;
三、创建其它图形
在绘三角形时,使用的是device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
如果给出6个顶点,可以绘2个三角形,分别用顶点(0,1,2),(3,4,5);
绘一个三角形,其实还可以绘制其它各种图形;
首先将程序中顶点个数设置为4个,
CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[4];
verts[0].X=150;verts[0].Y=50;verts[0].Z=0.5f; verts[0].Rhw=1; verts[0].Color = System.Drawing.Color.Aqua.ToArgb();
verts[1].X=250;verts[1].Y=250;verts[1].Z=0.5f; verts[1].Rhw=1; verts[1].Color = System.Drawing.Color.Brown.ToArgb();
verts[2].X=50;verts[2].Y=250;verts[2].Z=0.5f; verts[2].Rhw=1; verts[2].Color = System.Drawing.Color.LightPink.ToArgb();
verts[3].X=10;verts[3].Y=200;verts[3].Z=0.5f; verts[3].Rhw=1; verts[3].Color = System.Drawing.Color.Aqua.ToArgb();
stm.Write(verts);
同时顶点缓冲区也更改为4:
vertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedColored), 4, dev, 0, CustomVertex.TransformedColored.Format, Pool.Default);
将绘制图元的代码更改为:
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0,2);
三角形带是一系列相连的三角形,每两个相邻的三角形共享两个顶点。剔除模式会自动翻转所有偶数个三角形,因为相邻的三角形共享两个顶点,它们会被翻到反方向。这也是复杂的3D对象使用的最多的图元类型。
执行结果为:
也就是说,如果给定一系列点,绘制三角形采用的顶点是(0,1,2)、(1,2,3)……
注意:在初始化图形函数中加入以下代码:
device.RenderState.CullMode = Cull.None;
如果代码是:
device.DrawPrimitives(PrimitiveType.TriangleFan, 0,2);
执行结果为:
这种方法三角形共用一个顶点,也就是说,如果给定一系列点,绘制三角形采用的顶点是(0,1,2)、(0,2,3)、(0,3,4)……
如果代码是:
device.DrawPrimitives(PrimitiveType.LineList, 0,2);
执行结果是:
把每一对点作为单独的直线来绘制。使用时至少需要有两个顶点。
转自: dandancool http://blog.csdn.net/dandanCool/archive/2007/06/26/1666558.aspx

(转)Managed DirectX +C# 开发(入门篇)(四)相关推荐

  1. 《Managed DirectX +C# 开发(入门篇)》系列文章

    写在最前: 1.本系列文章版权归tongabcd所有,转载自dandanCool(并非原创作者),此处只作收藏与分享之用. 2.此系列文章如有再转,需按如下方式于文章醒目位置显示标明原创作者极其联系方 ...

  2. 【区块链开发入门】(四) Truffle详解篇2

    由于本篇篇幅较长,因此转为两篇文章.Truffle详解篇篇1请见:link 目录导航页 [区块链开发入门](一) 以太坊的搭建与运行 [区块链开发入门](二) 以太坊的编程接口 [区块链开发入门](三 ...

  3. 【微信小程序】开发入门篇(一)

    前言 ❤️ 你可能认为一个人无法改变世界,但我想让你知道,这个世界也无法改变像我这样的人 ❤️ [微信小程序]开发入门篇(一) 一.小程序简介 (1)小程序与普通网页开发的区别 二.第一个小程序 (1 ...

  4. 游戏开发入门(四)逻辑与脚本开发

    视频链接:游戏开发入门(四)逻辑与脚本开发(8节课 时常:约2小时30分钟 第4节看不了) 笔记与总结(请先学习视频内容): 1.逻辑系统目的 实现策划的设计文档 构建游戏玩法 实现程序与玩家交互 2 ...

  5. Hololens开发入门篇-郑洪智-专题视频课程

    Hololens开发入门篇-572人已学习 课程介绍         本课程使用Hololens模拟器,基于Unity2017.2及Visual Studio 2017开发 课程收益     学会Ho ...

  6. FPGA基础入门篇(四) 边沿检测电路

    FPGA基础入门篇(四)--边沿检测电路 一.边沿检测 边沿检测,就是检测输入信号,或者FPGA内部逻辑信号的跳变,即上升沿或者下降沿的检测.在检测到所需要的边沿后产生一个高电平的脉冲.这在FPGA电 ...

  7. cesium 页面截图_Cesium开发入门篇 | 02Cesium开发环境搭建及第一个示例

    01 开发环境准备 利用Cesium API进行二次开发属于Web前端开发范畴,目前比较火的Web三剑客包括React.Vue.AngularJS,每个js库的详细介绍可转至官网查看,在此不做详细介绍 ...

  8. 海思软件开发入门篇 (一)

    标题 海思软件开发入门篇 (一)   (第一次写博客,有错别字与写的不好的地方敬请谅解.)   加过很多群,也逛过很多论坛,很多人在问,第一次接触海思不知道从而入手,的确,现在一个SDK动不动上G,还 ...

  9. 【微信小程序】开发入门篇(二)

    前言 ❤️ 所谓信仰,可能就是在人们一无所剩的时候仅有的那种东西 ❤️ [微信小程序]开发入门篇(二) 一.小程序的宿主环境 (1)宿主环境简介 1.1 什么是宿主环境 1.2 小程序的宿主环境 (2 ...

  10. 后悔没早点看这篇直播系统定制开发入门篇

    直播想必大家都不陌生了,在互联网的风口下,以及5G技术的推动,流量带宽的提高,使得直播在我们生活中扮演着越来越重要的角色.本文先来讲一下入门直播需要了解的一些基本概念,搜集整理了直播入门需要了解的一些 ...

最新文章

  1. 张孝祥javascript学习笔记1---HTMLCSS
  2. 第二十一课.粒子滤波器
  3. C#中有关数组和string引用类型或值类型的判断
  4. MariaDB 求和,最大值,最小值,平均数
  5. day04-视图/配置文件/静态文件的基本使用
  6. 采购订单中的容差项目解释
  7. Visual SVN Server 远程管理
  8. 深入理解Kafka(1)
  9. HarmonyOS硬件创新合作伙伴,【HarmonyOS】HarmonyOS智能硬件开发学习指南 - HDC2020
  10. 深度学习《CNN架构》
  11. RHEL 6.3的yum不小心被删除了。如何恢复?
  12. JAVA生成pdf文件
  13. 武汉ISO27001认证的完整步骤
  14. 基于JavaSpringMvc+mybatis实现学生信息管理系统
  15. 【持续更新】一些常用的网站分享(智能教育装备、智能机器人行业)
  16. Windows下DOS操作系统(cmd)详解
  17. flutter 漂亮聊天UI界面实现 flutter-chatUI-again (11)
  18. 【Spring boot 常见问题】
  19. 推荐一个基于 SpringCloud 设计精良的网上商城
  20. 文章还需自己写,论文抄袭误国家

热门文章

  1. 列表标签(HTML)
  2. HTML/CSS 面试总结
  3. html选择器 并列,CSS 中的选择器 (二)- 组合选择器
  4. hibernate里的实体类中不能重写toString
  5. 【Computer Organization笔记25】I/O:程序直接控制,程序中断方式,直接存储访问(DMA),通道控制方式
  6. 「项目已被 macOS 使用,不能打开」的处理办法
  7. codewars028: Persistent Bugger
  8. java ftc 68是什么意思_机器人比赛;FTC项目介绍与院校简介
  9. 怎么删除w7桌面计算机图标,w7桌面图标箭头怎么去掉?w7桌面图标箭头去掉方法...
  10. python改变日期的输出格式,关于python:解析日期字符串并更改格式