Visual C# 的DirectX開發系列二瞭解攝像機

來源:互聯網
上載者:User

標籤: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開發系列二瞭解攝像機

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.