三维三角形的开发
这里要引入一个概念:投影
以下是投影函数的签名:
public static Matrix PerspectiveFovLH( float fieldOfViewY,float aspectRatio,float znearPlane,float zfarPlane);
投影变换描绘了场景的视见体(注:即可见部分)。视见体是由可视角度和前裁剪面(Near Plane)与后裁剪面(Far Plane)定义的一个平截头体(注:比如四棱锥横截面与底面之间的部分,上帝保佑,你还记得高中几何),在这个平截头体之内的即是可见部分。函数头里的nearPlane和farPlane两个参数,描绘了锥体的边界:farPlane就是锥体的底面(远平面的距离),而nearPlane则是横截面(近平面的距离)。fieldOfView参数描绘了锥体的角度。aspectRatio类似于电视的高宽比,比如,宽银幕电视的高宽比是1.85。你可以用可视区域的宽度来比上高度得出这个值。DirectX3D只绘制在这个平截头体中的物体。
既然我没从来没有进行过投影变换,也就根本不存在一个视见体,应此DirectX3D什么也没有绘制。但是,就算我们进行了投影变换,我们还没有进行包含了摄像机信息的view transform。可以用一下函数完成这个任务:
public static Matrix LookAtLH(Matrix pOut, Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector);
仅仅通过各变量的名字你就可以知道如何使用这个函数。其中三个是用来描述摄像机的属性:它的位置、它观察点的位置以及一个被参考为“up”的方向。有了投影变换和view transform的帮助,DirectX3D已经有足够的信息来绘制三角了。
Vector3 eye=new Vector3(0, 0, -30);
Vector3 at=new Vector3(0, 0, 0);
Vector3 up=new Vector3(0, 1, 0);
eye表示摄像机位置,at表示摄像机目标位置,up表示向上的方向,通常为(0, 1, 0)
具体代码:
public partial class CameraForm : Form
{
Device device = null;
public CameraForm()
{
//InitializeComponent();
this.ClientSize = new Size(800, 600); //绘制窗口大小
this.Text = "第一个DirectX程序"; //标题
}
/// <summary>
/// 初始化绘图类Device
/// </summary>
/// <returns>是否成功</returns>
public Boolean InitializeDirect3D()
{
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 e)
{
MessageBox.Show(e.ToString(), "Error");
return false;
}
}
public void Render()
{
if (device == null)
{
return;
}
device.Clear(ClearFlags.Target, System.Drawing.Color.WhiteSmoke, 1.0f, 0); //清除窗体,并将其绘制成白色
device.BeginScene();
//添加渲染代码
triangle();
device.RenderState.Lighting = false; //将灯光关闭,否则图形是黑色的
device.EndScene();
device.Present();
}
static void Main()
{
CameraForm basicForm = new CameraForm();
if (basicForm.InitializeDirect3D() == false)
{
MessageBox.Show("无法启动DirectX3D","错误!");
return;
}
basicForm.Show();
while(basicForm.Created)
{
basicForm.Render();
Application.DoEvents();
}
}
/// <summary>
/// 绘制一个三角形
/// </summary>
public void triangle()
{
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[3];
verts[0].Position = new Vector3(0f,0f,0f);
verts[0].Color = Color.Red.ToArgb();
verts[1].Position = new Vector3(5f, 10f, 0f);
verts[1].Color = Color.Green.ToArgb();
verts[2].Position = new Vector3(10f, 0f, 0f);
verts[2].Color = Color.Yellow.ToArgb();
device.VertexFormat = CustomVertex.PositionColored.Format;
//建立摄像机
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1f, 50f); //定义投影场景
device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -30), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); //定义摄像机
device.DrawUserPrimitives(PrimitiveType.TriangleList,1,verts);
}
}