虽然上一节这样就算一个完整的Direct3D程序了,但是你不看代码的话完全看不出他和一个默认的c#工程有哪些区别,所以,我们必须在我们的场景中建立一些东西来说明我们编写的是一个完整的Direct3D程序
在windows forms类中,有一个内部方法可以在适当的时候重画窗口,我们所要做的就是重写此方法,每当窗口发生变化的时候就会从新载入此
方法,所以这个方法内是我们编写代码的好地方,不必去理会用户是否改变的窗口,一切判断都由windows自动帮我们完成了。哈哈
函数如下
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);
device.Present();
}
这里告诉我们要画一个蓝色窗口。clear方法负责清除窗口显示,并且画出底色好了,现在你编译这个程序,会发现窗口已经变成蓝色,而且不管你放大,缩小,最大化,最小化,蓝色总是充满了整个窗口,到这里,你可能会觉得我还是在钻牛角尖,直接在form的属性设置底色为蓝色一样可以达到这样的效果,所以,接下来,我们要来一点稍微不同的东西。
呵呵,在3d图形系统中,最基础的对象就是三角形,有了足够多的三角形,我们可以创造任何东西,包括平滑的曲面,所以,在我们的一个程序中,很自然的就是想要创造一个三角形。在这里,我们使用的坐标系统是屏幕坐标系统而不是世界坐标,(世界坐标系统和坐标转换我们将在以后详细讨论)在我们创造三角形必须要做两件事:
第一,我们需要一些数据信息来构造我们的三角形;
第二,我们要告诉我们刚刚建立的设备来着手画这个三角形。
非常幸福的事,Managed Direct3D运行库已经有现成的构造器来建立我们的三角形,这个就是Direct3D命名空间下面的CustomVertex类,他包括了一些基本的格式来建立基本的图形。他的构造函数可以建立一些Direct3D能够明白而且我们也能够使用的数据,我们将在后面详细讨论这个类,但是现在,我们将使用TransformedColored 构造函数来构造我们的三角形,使用这个函数来告诉Direct3D我们建立的三角形不需要变换,也就是不需要旋转或者移动,而且还将给每一个顶点指定颜色,好了,我们在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].SetPosition(new Vector4(this.Width - (this.Width / 5.0f), this.Height –
(this.Height / 5.0f), 0.5f, 1.0f));
verts[1].Color = System.Drawing.Color.Black.ToArgb();
verts[2].SetPosition(new Vector4(this.Width / 5.0f, this.Height - (this.Height / 5.0f)
, 0.5f, 1.0f));
verts[2].Color = System.Drawing.Color.Purple.ToArgb();
我的Managed DirectX是1.900版本的,所以有SetPosition方法,有些人可能下的1.2039或者其他的版本,可能编译不能通过,那么把SetPosition改成Position= 就可以了。后面的程序有些地方可能还要修改,所以建议大家安装完全的DirectX9.c而不是单独的Managed DirectX上面一共有三个顶点,每个顶点储存我们需要的信息,前面两个是x坐标和y坐标,第三个是z坐标,第四个是w(三维其次坐标)后面两个我们可以忽略,然后是设置颜色,ToArgb()方法是把设置的颜色转换成Direct3D能够识别的32-bit色,在这里,我们用了一个向量来表示四个参数。
好了,我们已经有了数据了,接下来的工作就是画图了。
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
device.BeginScene()方法是告诉Direct3D我们要开始画图了。同样EndScene()是告诉它我们已经结束画图了。VertexFormat属性是告诉它我们将要画什么,也就是告诉它我们将以什么样的格式来画画,注意,我们前面申请的数据就是这个格式的,所以这里使用这个格式画图。
DrawUserPrimitives函数是告诉Direct3D我们将画什么,画多少,第一个PrimitiveType.TriangleList是告诉它我们要画三角形,第二个1是数
量,这个数值式我们前面定义的数组除以3得来的,最后一个是我们的数据。
好了,在OnPaint的最后加上一下代码:
this.Invalidate();
如果现在编译运行程序的话,你会发现但移动或重置窗口大小之后,并不会更新显示。原因是当我们需要重绘整个窗口时,Windows并不会每一次都计算窗口的收缩情况。因此,你只是移除了显示过的数据,当并没有删除已经显示的内容。很幸运,有个简单的方法解决这个问题,我们可以告诉Windows窗口总是需要被整个的重绘。
哦,现在只能显示一片空白了,并且我们的三角看起来还在不停的闪烁,尤其是当你调整窗口大小的时候。原来Windows总是尝试在Invalidate()方法后来绘制当前的窗口(即空白的这个窗口)。在我们的OnPaint方法之外还存在其他的绘制过程!能容易的通过改变窗口的“style”属性来解决。在构造函数里加上如下代码
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ConstolStyles.Opaque, true);
好了,现在开始运行程序,会发现一个三角形在屏幕中,这里,我们已经完成了Direct3D的画图功能,下面一章,我们要开始画真正的3D图形了。
下一章我还在翻译中,可能还要等一两天,大家可以到www.gameres.com去看看,那里有人已经翻译了不少,但是他是选择性翻译的,我这里会一章一章翻译,只看自己有那个能力和体力没有,我大四了,而的英语4级也是刚刚才知道通过了,所以呵呵,水平有限,翻译得不好的地方希望大家指出来,谢谢。。。。