標籤:directx
這裡藉助部分網上的文字和圖片說明,讓大家更清楚的瞭解DirectX中的攝像機。(部分內容來源於肖澤雲老師書中內容,最終目的是讓大家更清楚瞭解C#中的DirectX開發)
在使用攝像機前先來瞭解三個概念:世界空間(world space)、攝像機空間(cameraspace)和模型空間(model space)。世界空間(world space)可以認為是客觀世界空間,所有對象都位於這個世界空間中。攝像機空間(camera space)用於展示顯示地區,類似於人的眼睛。模型空間(model space)為模型自身的空間座標系,如匯入某個模型之前在建模時就具有的空間。
下面再介紹三個概念:View Transformation、World Transformation 和ProjectionTransformation。View Transformation(視圖變換)是表示觀察者位於世界空間,也稱攝像機變換,把頂點轉換成攝像機空間中的點。World Transformation(世界變換)是用於從模型空間轉換座標到全局座標。Projection Transformation(投影變換)可以認為是用來控制攝像機的,有點類似於設定攝像機鏡頭,這也是這三種變換形式中最複雜的。其中定義視圖變換和投影變換是類比攝像機必須的,若不指定世界矩陣,預設情況下它為一個四階單位矩陣。三維空間中的座標,經過世界變換、視圖變換(攝像機變換)、投影變換和螢幕轉換,才得到二維螢幕上的座標,其過程如所示:
首先我們定義視圖變換:可以使用Matrix.LookAtLH 或Matrix.LookAtRH 來建立一個視圖矩陣,用於表示攝像機位置和攝像機目標位置,其中Matrix.LookAtLH 用於建立左手法則的視圖矩陣,Matrix.LookAtRH 用於建立右手法則的視圖矩陣。建立視圖矩陣代碼如下:
Vector3 eye = new Vector3(0, 0, -30);Vector3 at = new Vector3(0, 0, 0);Vector3 up = new Vector3(0, 1, 0);Matrix viewMatrix = Matrix.LookAtLH(eye, at, up);
其中向量eye 表示攝像機位置,向量at 表示攝像機目標位置,向量up 表示向上的方向,該向量一般都為(0,1,0)。
其次定義投影變換:可以使用Matrix.PerspectiveFovLH 或Matrix.PerspectiveFovRH 建立一個基於視場(FOV)的投影變換,其中PerspectiveFovLH 用於建立左手法則的投影矩陣,PerspectiveFovRH 用於建立右手法則的投影矩陣。下面以PerspectiveFovRH 為例來說明,PerspectiveFovRH()函數的定義如下:
public static Matrix PerspectiveFovLH
(
float fieldOfViewY,
float aspectRatio,
float znearPlane,
float zfarPlane
);
其中參數fieldOfViewY表示視場在Y 方向的弧度,參數aspectRatio 表示平面縱橫比,
參數znearPlane,表示近平面的距離,參數zfarPlane表示遠平面的距離。如所示:
建立投影矩陣代碼如下:
Matrix projection = Matrix.PerspectiveFovLH((float)Math.PI / 4,this.Width/this.Height, 1.0f, 50.0f);
之後是設定繪圖裝置投影及視圖矩陣、繪製三角形等。全部代碼如下:
using System;using System.ComponentModel;using System.Data;using System.Drawing;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;namespace 攝像機{ public partial class Camera : Form { Device device = null;//定義繪圖裝置 public Camera() { this.ClientSize = new Size(800, 800);//指定表單尺寸 this.Text = "攝像機";//指定表單標題 } public bool InitializeDirect3D() { try { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = true; //指定以Windows表單形式顯示 presentParams.SwapEffect = SwapEffect.Discard; //當前螢幕繪製後它將自動從記憶體中刪除 device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //執行個體化device對象 return true; } catch (DirectXException e) { MessageBox.Show(e.ToString(), "Error"); //處理異常 return false; } } public void Render() { if (device == null) //如果device為空白則不渲染 { return; } Vector3 eye = new Vector3(30, 0, -30); Vector3 at = new Vector3(0, 0, 0); Vector3 up = new Vector3(0, 1, 0); Matrix viewMatrix = Matrix.LookAtLH(eye, at, up); Matrix projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width/this.Height, 1.0f, 50.0f); device.Transform.Projection = projection; device.Transform.View = viewMatrix; device.RenderState.FillMode = FillMode.WireFrame; device.RenderState.Lighting = false; device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0); //清除windows介面為黑色 device.BeginScene(); //在此添加渲染圖形代碼 CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[3];//定義頂點 vertices[0].Position = new Vector3(0f, 0f, 0f); vertices[0].Color = Color.Red.ToArgb(); vertices[1].Position = new Vector3(5f, 10f, 0f); vertices[1].Color = Color.Green.ToArgb(); vertices[2].Position = new Vector3(10f, 0f, 0f); vertices[2].Color = Color.Yellow.ToArgb(); device.VertexFormat = CustomVertex.PositionColored.Format; device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, vertices); device.EndScene(); device.Present(); } static void Main() { Camera Camera = new Camera(); //建立表單對象 if (Camera.InitializeDirect3D() == false) //檢查Direct3D是否啟動 { MessageBox.Show("無法啟動Direct3D!", "錯誤!"); return; } Camera.Show(); //如果一切都初始化成功,則顯示表單 while (Camera.Created) //設定一個迴圈用於即時更新渲染狀態 { Camera.Render(); //保持device渲染,直到程式結束 Application.DoEvents(); //處理鍵盤滑鼠等輸入事件 } } }}
最終效果
本文源碼:http://download.csdn.net/detail/yangyisen0713/8385885
Visual C# 的DirectX開發系列二瞭解攝像機