C# Direct3D9开发实例二:树木成林

一、     所用基础知识:

1)关于创建设备

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

       Device共有三个构造函数,最常用的一个如下:

 public Device(int adapter,DeviceType deviceType,Control renderWindow, CreateFlags behaviorFlags, PresentParameters[] presentationParameters);  

首先来看第一个参数的意思:它表示我们将要使用哪个物理图形卡。计算机里的所有图形卡都有一个唯一的适配器标识符,默认的显卡总是标识为0 的图形卡。

第二个参数:DeviceType,告诉了DirectX3D要创建哪种类型的device。最常用的值是DeviceType.Hardware,表示将创建一个硬件设备。也可以选择DeviceType.Reference,这种设备允许使用“参考光栅器”(reference rasterizer),所有的效果由DirectX3D运行时来实现,速度较慢。应该仅在调试或测试显卡不支持的特性时使用这个选项。

第三个参数表示把设备绑定到的窗口。因为windows form控件类都包含了一个窗口句柄(windows handle),所以很容易把一个确定的类作为渲染窗口。可以使用pictureboxpanel或其他任意的控件作为这个参数的值。本例用form

第四个参数用来描述设备创建之后的行为。大部分CreateFlags枚举的成员都能组合起来使用,使设备具有多种行为。但有一些flag是相互排斥的。本例使用SoftwareVertexProcessing标志。这个标志适合于所有顶点处理都用CPU计算的情况。

最后一个参数,它表示你的设备把数据呈现到显示器的方式。Presentation Parameter类的外观都可以由这个类来控制。

para.Windowed = true;表示以窗口模式运行,另外还可以全屏方式运行。

para.SwapEffect用于控制缓存交换的行为。如果选择了SwapEffect.Flip,运行时会创建额外的后备缓冲(back buffer),并且在显示时拷贝front bufferSwapEffect.CopyFlip相似,但要求把后备缓冲设为1SwaoEffect.Discard是指如果缓冲没有准备好被显示,则会丢弃缓冲中的内容

 

 

 

二、     设备的Clear()方法:

在本例中会有这样一行代码:

device.Clear( ClearFlags.Target, Color.Black , 1.0f, 0 );

   使用Clear()方法把窗口填充为实心的颜色。它的第一个参数指定了要填充的对象;在例子里,填充的即是目标窗口。第二个参数是我们所要填充的颜色。其他的两个参数先暂时忽略。在device被填充之后,必须更新显示:Present方法会为完成这个任务。

所以,在完成之后,会有这么一行代码:

device.Present();

   三、顶点:

    在本例中,使用TransformedColored结构来保存顶点结构,这个结构告诉DirectX3D运行时三角不需要进行坐标变换(比如旋转或移动),因为已经指定了使用屏幕坐标系。它也包含了每一个点(顶点)的颜色的信息。

    Vector4结构是保存这种信息最方便的方式。Vector4其实就是(x,y,z,w)经过变换后成为(x/w,y/w,z/w)。然后设置点的颜色。本例中使用标准颜色的ToArgb方法。

二、实例过程:

(1):新建工程,加入引入,并导入名称空间。在工程中新添加一个类:Tree.cs

(2):在Tree类中,定义设备对象变量,并在构造函数中,设置要显示的设备:

private Device displayDevice; //需要显示在哪个设备上。

         public Tree(ref Device device)

         {

              displayDevice = device;

    

         }

3)添加一个Render()方法,传入一个参数定义生成树的位置,长和宽。接下来利用顶点绘制三角形,形成一棵树:

              public void Render(Rectangle rec)

         {

              CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[15];

 

 

 

              verts[0].Position = new Vector4( rec.X+rec.Width*3/6, rec.Y , 0.5f, 1.0f );

              verts[0].Color =Color.Green.ToArgb();

              verts[1].Position = new Vector4( rec.X+rec.Width*4/6, rec.Y+rec.Height/4, 0.5f, 1.0f );

              verts[1].Color =Color.Green.ToArgb();

              verts[2].Position = new Vector4( rec.X+rec.Width*2/6, rec.Y+rec.Height/4, 0.5f, 1.0f );

              verts[2].Color =Color.Green.ToArgb();

             

              verts[3].Position = new Vector4( rec.X+rec.Width*3/6, rec.Y+rec.Height/4-rec.Height/8, 0.5f, 1.0f );

              verts[3].Color =Color.Green.ToArgb();

              verts[4].Position = new Vector4(rec.X+rec.Width*5/6, rec.Y+rec.Height*2/4, 0.5f, 1.0f );

              verts[4].Color =Color.Green.ToArgb();

              verts[5].Position = new Vector4(rec.X+rec.Width/6, rec.Y+rec.Height*2/4, 0.5f, 1.0f );

              verts[5].Color =Color.Green.ToArgb();

 

 

 

              verts[6].Position = new Vector4( rec.X+rec.Width*3/6, rec.Y+rec.Height*2/4-rec.Height/8, 0.5f, 1.0f );

              verts[6].Color =Color.Green.ToArgb();

              verts[7].Position = new Vector4(rec.X+rec.Width, rec.Y+rec.Height*3/4, 0.5f, 1.0f );

              verts[7].Color =Color.Green.ToArgb();

              verts[8].Position = new Vector4(rec.X, rec.Y+rec.Height*3/4, 0.5f, 1.0f );

              verts[8].Color =Color.Green.ToArgb();

 

 

 

              verts[9].Position = new Vector4(rec.X+rec.Width*2/6, rec.Y+rec.Height*3/4, 0.5f, 1.0f );

              verts[9].Color =Color.Maroon.ToArgb();

              verts[10].Position = new Vector4(rec.X+rec.Width*4/6, rec.Y+rec.Height, 0.5f, 1.0f );

              verts[10].Color =Color.Maroon.ToArgb();  

              verts[11].Position = new Vector4(rec.X+rec.Width*2/6, rec.Y+rec.Height, 0.5f, 1.0f );

              verts[11].Color =Color.Maroon.ToArgb();

//

              verts[12].Position = new Vector4(rec.X+rec.Width*2/6, rec.Y+rec.Height*3/4, 0.5f, 1.0f );

              verts[12].Color =Color.Maroon.ToArgb();

              verts[13].Position = new Vector4(rec.X+rec.Width*4/6, rec.Y+rec.Height*3/4, 0.5f, 1.0f );

              verts[13].Color =Color.Maroon.ToArgb();  

              verts[14].Position =new Vector4(rec.X+rec.Width*4/6, rec.Y+rec.Height, 0.5f, 1.0f );

     verts[14].Color =Color.Maroon.ToArgb();

 

 

 

              displayDevice.VertexFormat = CustomVertex .TransformedColored .Format;

              displayDevice.DrawUserPrimitives( PrimitiveType.TriangleList, 5, verts );

         }

4):回到窗口代码,声明变量:

private Device device = null;

              private Tree[] myTree=new Tree[10] ;

              Rectangle rec;

在这里,声明了树数组,表示要生成10棵树。

5)在图形的初始化函数里:进行设备的初始化,并创建设备,其含义前面已经介绍了,接着对树对象进行实例化。

public void InitializeGraphics()

         {

              PresentParameters para = new PresentParameters();

              para.Windowed = true;

              para.SwapEffect = SwapEffect.Discard   ;

              device = new Device( 0, DeviceType.Hardware, this , CreateFlags.HardwareVertexProcessing, para );

             

              for(int i=0;i<10;i++)

              {

               myTree[i] = new Tree(ref device);

              }

             

         }

     6)、在Render()方法中先将背景设置为黑色,然后,生成不同位置,不同大小的树木,形成森林。

public void Render()

         {

              device.Clear( ClearFlags.Target, Color.Black , 1.0f, 0 );

              device.BeginScene();

              rec=new Rectangle(100,200,100,100);

              myTree[0].Render(rec);

              rec= new Rectangle(200,400,200,100);

              myTree[1].Render(rec);

              rec=new Rectangle(100,300,130,150);

              myTree[2].Render(rec);

              rec= new Rectangle(300,330,200,200);

              myTree[3].Render(rec);

              rec=new Rectangle(400,150,80,150);

              myTree[4].Render(rec);

              rec= new Rectangle(190,400,80,50);

              myTree[5].Render(rec);

              rec=new Rectangle(150,190,40,80);

              myTree[6].Render(rec);

              rec= new Rectangle(300,400,90,90);

              myTree[7].Render(rec);

              rec=new Rectangle(220,30,10,100);

              myTree[8].Render(rec);

              rec= new Rectangle(10,400,40,40);

              myTree[9].Render(rec);

             

              device.EndScene();

              device.Present();

              this.Invalidate();

         }

7)主函数是这的:

static void Main()

         {

              using ( Form1 frm = new Form1() )

              {

                   frm.InitializeGraphics();

                   frm.Show();

                   while(frm.Created)

                   {

                       frm.Render();

                       Application.DoEvents();

                   }

                   frm.Dispose();

              }

         }

 

 

 

三、      运行程序:

结果如下:

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值