第四章 入门程序
一、创建设备
本节介绍的示例为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# 开发(入门篇)(四)相关推荐
- 《Managed DirectX +C# 开发(入门篇)》系列文章
写在最前: 1.本系列文章版权归tongabcd所有,转载自dandanCool(并非原创作者),此处只作收藏与分享之用. 2.此系列文章如有再转,需按如下方式于文章醒目位置显示标明原创作者极其联系方 ...
- 【区块链开发入门】(四) Truffle详解篇2
由于本篇篇幅较长,因此转为两篇文章.Truffle详解篇篇1请见:link 目录导航页 [区块链开发入门](一) 以太坊的搭建与运行 [区块链开发入门](二) 以太坊的编程接口 [区块链开发入门](三 ...
- 【微信小程序】开发入门篇(一)
前言 ❤️ 你可能认为一个人无法改变世界,但我想让你知道,这个世界也无法改变像我这样的人 ❤️ [微信小程序]开发入门篇(一) 一.小程序简介 (1)小程序与普通网页开发的区别 二.第一个小程序 (1 ...
- 游戏开发入门(四)逻辑与脚本开发
视频链接:游戏开发入门(四)逻辑与脚本开发(8节课 时常:约2小时30分钟 第4节看不了) 笔记与总结(请先学习视频内容): 1.逻辑系统目的 实现策划的设计文档 构建游戏玩法 实现程序与玩家交互 2 ...
- Hololens开发入门篇-郑洪智-专题视频课程
Hololens开发入门篇-572人已学习 课程介绍 本课程使用Hololens模拟器,基于Unity2017.2及Visual Studio 2017开发 课程收益 学会Ho ...
- FPGA基础入门篇(四) 边沿检测电路
FPGA基础入门篇(四)--边沿检测电路 一.边沿检测 边沿检测,就是检测输入信号,或者FPGA内部逻辑信号的跳变,即上升沿或者下降沿的检测.在检测到所需要的边沿后产生一个高电平的脉冲.这在FPGA电 ...
- cesium 页面截图_Cesium开发入门篇 | 02Cesium开发环境搭建及第一个示例
01 开发环境准备 利用Cesium API进行二次开发属于Web前端开发范畴,目前比较火的Web三剑客包括React.Vue.AngularJS,每个js库的详细介绍可转至官网查看,在此不做详细介绍 ...
- 海思软件开发入门篇 (一)
标题 海思软件开发入门篇 (一) (第一次写博客,有错别字与写的不好的地方敬请谅解.) 加过很多群,也逛过很多论坛,很多人在问,第一次接触海思不知道从而入手,的确,现在一个SDK动不动上G,还 ...
- 【微信小程序】开发入门篇(二)
前言 ❤️ 所谓信仰,可能就是在人们一无所剩的时候仅有的那种东西 ❤️ [微信小程序]开发入门篇(二) 一.小程序的宿主环境 (1)宿主环境简介 1.1 什么是宿主环境 1.2 小程序的宿主环境 (2 ...
- 后悔没早点看这篇直播系统定制开发入门篇
直播想必大家都不陌生了,在互联网的风口下,以及5G技术的推动,流量带宽的提高,使得直播在我们生活中扮演着越来越重要的角色.本文先来讲一下入门直播需要了解的一些基本概念,搜集整理了直播入门需要了解的一些 ...
最新文章
- 张孝祥javascript学习笔记1---HTMLCSS
- 第二十一课.粒子滤波器
- C#中有关数组和string引用类型或值类型的判断
- MariaDB 求和,最大值,最小值,平均数
- day04-视图/配置文件/静态文件的基本使用
- 采购订单中的容差项目解释
- Visual SVN Server 远程管理
- 深入理解Kafka(1)
- HarmonyOS硬件创新合作伙伴,【HarmonyOS】HarmonyOS智能硬件开发学习指南 - HDC2020
- 深度学习《CNN架构》
- RHEL 6.3的yum不小心被删除了。如何恢复?
- JAVA生成pdf文件
- 武汉ISO27001认证的完整步骤
- 基于JavaSpringMvc+mybatis实现学生信息管理系统
- 【持续更新】一些常用的网站分享(智能教育装备、智能机器人行业)
- Windows下DOS操作系统(cmd)详解
- flutter 漂亮聊天UI界面实现 flutter-chatUI-again (11)
- 【Spring boot 常见问题】
- 推荐一个基于 SpringCloud 设计精良的网上商城
- 文章还需自己写,论文抄袭误国家
热门文章
- 列表标签(HTML)
- HTML/CSS 面试总结
- html选择器 并列,CSS 中的选择器 (二)- 组合选择器
- hibernate里的实体类中不能重写toString
- 【Computer Organization笔记25】I/O:程序直接控制,程序中断方式,直接存储访问(DMA),通道控制方式
- 「项目已被 macOS 使用,不能打开」的处理办法
- codewars028: Persistent Bugger
- java ftc 68是什么意思_机器人比赛;FTC项目介绍与院校简介
- 怎么删除w7桌面计算机图标,w7桌面图标箭头怎么去掉?w7桌面图标箭头去掉方法...
- python改变日期的输出格式,关于python:解析日期字符串并更改格式