SharpGL學習筆記(三) 投影變換和視點變換

来源:http://www.cnblogs.com/hackpig/archive/2016/08/19/5788442.html
-Advertisement-
Play Games

從本節開始,我們使用SharpGL帶的VS2010擴展,來直接生成SharpGL工程。 如果你新建項目時,沒有看到下麵的SharpGL項目,那麼請事先在SharpGL源代碼中找到一個叫 ”SharpGL 2.0 Visual Studio Extension“目錄 ,安裝名為 SharpGL.vsi ...


 

從本節開始,我們使用SharpGL帶的VS2010擴展,來直接生成SharpGL工程。

如果你新建項目時,沒有看到下麵的SharpGL項目,那麼請事先在SharpGL源代碼中找到一個叫 ”SharpGL 2.0 Visual Studio Extension“目錄 ,安裝名為 SharpGL.vsix的vs2010擴展, 然後重啟你的vs2010.

 

利用上面的SharpGL項目,直接生成一個完整的SharpGL工程,它帶有Opengl窗體控制項,基本代碼已經都完成了, 你只需要修改3D繪圖部分的代碼就可以了。

生成的工程是還可以直接跑起來看到效果, 如下圖所示。

我們會看到了有個三棱體已經畫好了,並且還正在旋轉,下麵還動態顯示了渲染的幀數。

 

我們在前二篇寫的代碼生成的三角形像是2D的,現在如上圖這樣的效果,就感覺很有立體感覺了。其實,兩者不一樣的只是因為這個工程預設已經進行了投影變換視點變換

 

當三維體放在世界坐標系中後,由於顯示器只能用二維圖像顯示三維休,因此必須要依賴投影來把三維體降低維數。

投影變換的目的就是定義了一個視景體,使得視景體外多餘的部分不會顯示。

投影包括透視投影(perspective projection)和正視投影(orthographic projection)兩種。

上圖就是透視投影的效果,它符合人的觀察經驗,即離視點近的物體大,離視點遠的物體小,遠到極點就消失,成為滅點。就像筆直馬路的盡頭看上去就成為一個點。

 

我們看一下代碼中有關投影部分的代碼, 解釋一下相關功能函數的參數意義。

 1   private void openGLControl_Resized(object sender, EventArgs e)
 2         {
 3             //  TODO: Set the projection matrix here.
 4             OpenGL gl = openGLControl.OpenGL;
 5             gl.MatrixMode(OpenGL.GL_PROJECTION);
 6             gl.LoadIdentity();
 7 
 8             gl.Perspective(20.0f, (double)Width / (double)Height, 0.01, 100.0);
 9             gl.LookAt(-5, 5, -5, 0, 0, 0, 0, 1, 0);
10 
11             gl.MatrixMode(OpenGL.GL_MODELVIEW);
12         }

 

創建透視效果的函數名和原型為: 

Perspective(double fovy, double aspect, double zNerar, double zFar);

aspect是視窗的縱橫比

zNerar,zFar分別是近處和遠處的裁面位置。

fovy是控制視野在XY平面的角度,範圍是0--180度。你可以把它想象成是3dsmax中的相機鏡頭對應的視野參數。

 

 下麵的Perspective函數的示意圖中, 視角指的是參數fovy, aspect=w/h, zNerar為近平面距離, zFar為遠平面距離.

 

 對於比較難以理解的參數fovy, 如果你仍然不是太明白,下麵換個方式說明一下.

 

我們拿3dsmax的攝像機參數來做比喻(意義是類似的),上圖是我們使用15mm鏡頭(視野為100.389度)看到的效果。小鏡頭看到的視野更大。攝影裡面叫這種小鏡頭叫廣角鏡頭。

 

現在使用85mm的鏡頭(視野為23.913度),只可以看到物體的局部了。它的可視範圍變窄了。

那麼 Perspective()函數的fovy參數的意義就等同於鏡頭所代表的視野度數。

 


設置好投影變換後, 接下來還要設置視點變換. 

設置視點變換的函數LookAt的原形為:

LookAt(double eyex, double eyey, double eyez, double centerx, double centery, double centerz, double upx, double upy, double upz);

這個函數是做視點變換用的,你可以認為它是設置攝像機的函數。

在opengl中,預設時視點定位於坐標系的原點,初使方向指向Z軸負方向,前面說過,預設的三維模形也是貼著世界坐標系的Z軸0的深度上放置的, 因此,如果不進行視點變換,則相當於攝像機正好貼著物體,什麼也看不見,這就是為什麼上節的代碼裡面要有一句代碼gl.Translate()用於把把物體往Z軸負方向移動一定距離的原因。

 

我們還是以3dsmax中的攝像機來類比。下麵的示意圖中,我們使用的是一種被稱為”目標攝像機“的相機,之所以這麼稱謂,是因為為這個攝像機帶一個目標點可以調節。

 

前三個參數 eyex, eyey, eyez 表示攝像機本身位於世界坐標系中的位置。

 在3dsmax中,攝像機的位置可以任意平移的.

上圖我們放置的位置是XY軸剛好對著世界坐標系的原點。Z軸朝正方向走了老遠。因為攝像機離物體遠了,因此可以正常看到物體。

 

 上圖中,攝像機的XYZ都遠離了物體做了變換,相當於在圍繞三維體進行觀察。

 

 當中三個參數 centerx, centery,  centerz 相當於調整了3dsmax目標攝像機的目標點位置。

 如上圖所示, 改變目標點的位置也有類似圍繞觀察對象的效果。並且,這個目標點在Z軸上相對於物體的距離是沒有什麼意義的,主要意義是在XY上的變化上。這一點讀者可以自己去試驗。

 

 

 最後三個參數 upx, upy, upz相當於在旋轉3dsmax目標攝像機。

不過這個參數的值並不是角度值,而是向量,數值的大小沒意義,正負值才有意義。

 

在3dsmax中,攝像機是可以任意角度旋轉的。

但是在Lookat()函數中這最後三個參數, upx,upy 只能在上下,左右,45度這幾個角度中變換,而且upz取值似乎沒什麼意義。

 

解釋完這兩個函數,我們用程式繪製一個三角形來測試一下上述視點變換和投影變換的效果。

上圖是視野為20的效果,可以看到三角形看上去大些了。

 

視野改為60,三角形看上去小些了。

以上結果和上面分析Perspective()函數的fovy參數時結論是一致的。

 

現在我們改動LookAt的前三個參數,三角形正對著我們顯示了。

 

現在我們改變LookAt的最後三個參數,Y向量改為-1,相當於攝像機旋轉向下180度,結果三角形朝下了。

 

 

為了節約下載空間,以後的源代碼中,筆者都把SharpGL的三個dDLL文件都刪除了。

請你自己把這三個dll文件拷貝到: ”Dependencies“,  "bin\debug\" 這兩個目錄中去。再打開工程。

以後不在贅述。

 

本文源代碼下載

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 介紹 LINQ(目錄) 語言集成查詢 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的一項創新功能。 傳統上,針對數據的查詢都是以簡單的字元串表示,而沒有編譯時類型檢查或 IntelliSense 支持。 此外,您還必須針對以下各種數據源學 ...
  • 開始使用 LINQ (一)- 介紹 LINQ 查詢 查詢是一種從數據源檢索數據的表達式。 隨著時間的推移,人們已經為各種數據源開發了不同的語言;例如,用於關係資料庫的 SQL 和用於 XML 的 XQuery。 因此,開發人員不得不針對他們必須支持的每種數據源或數據格式而學習新的查詢語言。 LINQ ...
  • 開始使用 LINQ (二)- 基本 LINQ 查詢操作 一、獲取數據源:from 在 LINQ 查詢中,第一步是指定數據源。像在大多數編程語言中一樣,在 C# 中,必須先聲明變數,才能使用它。在 LINQ 查詢中,最先使用 from 子句的目的是引入數據源 (customers) 和範圍變數 (cu ...
  • 開始使用 LINQ(三)- 使用 LINQ 進行數據轉換 語言集成查詢 (LINQ) 不僅可用於檢索數據, 而且還是一個功能強大的數據轉換工具。 通過使用 LINQ 查詢,您可以將源序列用作輸入,並採用多種方式修改它以創建新的輸出序列。您可以通過排序和分組來修改該序列,而不必修改元素本身。但是,LI ...
  • 補充下上篇文章集合的命令。 上篇地址 博客園蝸牛 http://www.cnblogs.com/tdws/p/5785939.html SCARD Key獲得執行集合中元素的數量。 SDIFFSTORE 目標鍵 keys ... 將集合做DIFF差集操作,並存儲在目標鍵中。 另外同樣有SINTERS ...
  • 通常情況下我們在使用IBatisNet的時候,配置文件和映射文件都是暴露在外的,如果能進入到伺服器,那麼你的程式的操作資料庫的SQL語句,資料庫連接字元串等信息都將很輕鬆的被看到,這樣是很危險的。然而IBatisnet自身也沒有提供配置文件直接加密的方法,但我們可以用變通的方式來儘可能的保護這些文件 ...
  • 本隨筆續接:.NET 實現並行的幾種方式(一) 四、Task 3)Task.NET 4.5 中的簡易方式 在上篇隨筆中,兩個Demo使用的是 .NET 4.0 中的方式,代碼寫起來略顯麻煩,這不 .NET 4.5提供了更加簡潔的方式,讓我們來看一下吧。 /// <summary> /// Task. ...
  • 二三四五還沒寫,先寫六吧(有道友說想看看插件部分)。 這裡是一 從零開始編寫屬於我的CMS:(一)前言 一,首先預定義介面<!--?xml:namespace prefix = "o" ns = "urn:schemas-microsoft-com:office:office" /--> 新建類庫, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...