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


    第四章 入门程序‍‍‍

    一、创建设备
    本节介绍的示例为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);
    执行结果是:
    把每一对点作为单独的直线来绘制。使用时至少需要有两个顶点。

  • 相关阅读:
    UNIX环境高级编程 第9章 进程关系
    UNIX环境高级编程 第8章 进程控制
    UNIX环境高级编程 第7章 进程环境
    最小截断[AHOI2009]
    切糕[HNOI2013]
    餐巾
    happiness[国家集训队2011(吴确)]
    奇怪的道路[JXOI2012]
    王者之剑
    抵制克苏恩[Lydsy2017年4月月赛]
  • 原文地址:https://www.cnblogs.com/lcxu2/p/2004037.html
Copyright © 2020-2023  润新知