Direct3D世界的Hello:高洛德渲染的三角形(轉)
Direct3D世界的Hello:高洛德渲染的三角形(轉)[@more@] Direct3D的所有操作都是在Direct3D裝置上進行的。建立裝置要使用Device類的建構函式。 public Device ( System.Int32 adapter , Microsoft.DirectX.Direct3D.DeviceType deviceType , System.Windows.Forms.Control renderWindow , Microsoft.DirectX.Direct3D.CreateFlags behaviorFlags, Microsoft.DirectX.Direct3D.PresentParameters presentationParameters ) Direct3D裝置有3種型別,Hardware, Software和Reference型別。其中Reference型別只有在DirectX SDK中的runtime才有。我們通常使用的DirectX Runtime沒有這種型別的裝置。 建立裝置的時候我們還要指定在那個顯示卡上進行操作,一般情況下,我們指定0,表示使用預設的顯示卡。 我們還要把該裝置與一個視窗關聯起來。 CreateFlags中我們經常使用的引數,就是指定要使用硬體/軟體定點處理。 當我們縮放視窗的時候,拉大視窗肯定會導致視窗被重繪,但是縮小視窗並不能導致視窗被繪製。這也是合情合理的,因為縮小視窗只是導致視窗可見面積的減小, 沒有必要重新繪製。當然這是一般情況,在我們的例子,我們要求三角形總是在視窗中央,所以這樣的表現不被接受。我們需要自己來強制重繪,所以,我們在Form1_Paint()事件中加入了this.Invalidate()函式。 但是這樣又引入了另外的問題,執行修改後的程式後,我們發現我們繪製的內容不見了。這是因為在Windows Form中不是所有的繪製都發生在Paint中,因為Windows XP支援透明視窗,這個透明處理是由作業系統自動完成的,這就說明在Paint事件之外會發生一些繪製操作,Windows會用預設的資訊來重繪視窗,這導致我們繪製的內容被覆蓋掉。這就是為什麼我們要在我們的Form類的建構函式種使用SetStyle函式了。 (??為什麼加入了Invalidate()後會出現這種現象? 我的看法,不對的地方還請高手指教了。嘿嘿。 我們是先Render,然後才呼叫Invalidate()的。Invalidate()觸發Windows的Piant外繪製,我們的繪製被覆蓋。移動的時候,反覆這樣清除,導致閃爍,所以 就有了我們看到的現象。 ) this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); 這一語句告訴Windows 我們的視窗不是透明的,並要求所有的繪製都要發生在Paint事件中。否則,我們會發現我們繪製的內容根本看不到,當移動視窗的時候,會隱隱看到我們繪製的三角形在閃爍。大家可以試試看,在我的機器上,不是很明顯。 在繪製三角形的時候,我們使用了TransfomredColored的頂點格式。這種格式就如他的名字一樣,是已經轉換過的,對於這種格式的頂點,Direct3D不再做Lighting, View Transform,Projection Transform.我們在資料中指定的座標值就是這些頂點要顯示的地方。 而且我們可以看到,繪製出來的三角形內部已經被填充了,可是我們並沒有做任何類似的操作。這其實是一種渲染模式(Shading Mode, 不知道這麼翻譯對不對)。 高洛德(Gouraud)渲染,還有Flat Shading Mode和Phong Shading Mode. (Gouraud渲染很有用的,尤其是在用多個三角形描述一個曲面/物件的時候,面對幾千個上萬個三角形,你不可能自己去計算每個三角形的光照吧。Gouraud可以根據每個三角形面和光源的角度自動計算這些三角形頂點的具體顏色和亮度,然後用差值平滑處理三角形內部的點,這樣就可以形成真實的物體了。具體來說是這樣, 每個三角形是是一個平面,有自己的法向向量,光線也有自己的向量,根據這個三角形面和光線的角度可以計算出這個三角形的頂點的具體光照情況,然後根據材料特性就可以計算出這些頂點的具體顏色、亮度等。然後對於三角形內部的其他點,可以用差值平滑處理,計算出這些點的顏色和亮度資訊。具體怎麼算,我也不知道,呵呵, 我不是搞演算法的,不關心這個。 如果你把頂點資料的格式改成 PositonColored,你會發現,又看不到我們繪製的東西了,呵呵,我們下面會知道為什麼。 好了,下面是這節的例子。 #region Using directives using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; #endregion namespace Ch01 { partial class Form1 : Form { private Device device = null; public Form1() { InitializeComponent(); this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true ); } public void InitializeGraphics() { PresentParameters para = new PresentParameters(); para.Windowed = true; para.SwapEffect = SwapEffect.Discard; device = new Device( 0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, para ); } private void Form1_Paint(object sender, PaintEventArgs e) { device.Clear( ClearFlags.Target, Color.Blue, 1.0f, 0 ); CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3]; verts[0].Position = new Vector4( this.Width / 2.0f, 50.0f, 0.5f, 1.0f ); verts[0].Color = Color.Aqua.ToArgb(); verts[1].Position = new Vector4( this.Width - this.Width / 5.0f, this.Height - ( this.Height / 5.0f ), 0.5f, 1.0f ); verts[1].Color = Color.Black.ToArgb(); verts[2].Position = new Vector4( this.Width / 5.0f, this.Height - ( this.Height / 5.0f ), 0.5f, 1.0f ); verts[2].Color = Color.Purple.ToArgb(); device.BeginScene(); device.VertexFormat = CustomVertex .TransformedColored .Format; device.DrawUserPrimitives( PrimitiveType.TriangleList, 1, verts ); device.EndScene(); device.Present(); this.Invalidate(); } static void Main() { using ( Form1 frm = new Form1() ) { // Show our form and initialize our graphics engine frm.Show(); frm.InitializeGraphics(); Application.Run( frm ); } } } } BeginScene()和EndScene()是配對的。必需呼叫Present()函式後,我們繪製的東西才能顯示出來。 DrawUserPrimitives()是具體的繪製函式,還有個類似的函式DrawPrimitives(),這個函式用起來就比較麻煩了,得建立頂點緩衝,然後透過Device的SetStreamSource()函式設定到裝置上去,並且要把頂點資料,寫到這個頂點緩衝中去,然後才能夠呼叫DrawPrimitives()繪製。 在使用DrawUserPrimitives()的時候,我們使用了PrimitiveType.TrangleList,這裡涉及了一個基本概念,3D Primitive.在Direct3D中支援多種型別。 其中比較重要的是,Triangle List, Triangle Strip, Triangle Fan.具體概念,可以參考其他的資料。並且這些Primitive在不同的Shading Mode中的含義也是不同的,起碼在Gouraud shading mode中是這樣,TriangleList的每個三角形被單獨平滑處理,TriangleStrip中的三角形被作為一個整體來平滑,TriangleFan呢? 也應該和TriangleStrip一樣吧,沒有試過,有心人給確認一下吧。 而且組織頂點資料的時候還涉及了Backface Culling的概念,也就是說頂點的順序也是有講究的,不能亂來。否則,打死你也看不到你畫的東西,除非你在device.RenderState.CullMode中關掉了Backface Culling
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-952141/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【C++】使用 libass,完成 Direct3D 11 下的字幕渲染C++3D
- 初入 Vue 的世界 Say HelloVue
- 德洛斯 ·德菲-Delos定義了傳統業務和DeFi加密世界之間的橋樑加密
- 高德渲染閘道器Go語言重構實踐Go
- 高德「渲染練習生計劃」啟動,開啟專業渲染技術人旅程!
- 高德解析城市的分析,根據高德的經緯度獲取城市cityCode
- 洛谷 P1216 數字三角形
- vue 實現高德座標轉GPS座標Vue
- 高德 SDK
- python xmind轉Excel(puppet洛洛原創)PythonExcel
- 高德地圖的四處進擊地圖
- 高德地圖之地圖的屬性地圖
- 三角形的 N 種畫法與瀏覽器的開放世界瀏覽器
- 從真實世界到渲染
- 高德地圖之地圖的生命週期地圖
- react中使用高德地圖的原生APIReact地圖API
- 對接高德地圖API的總結地圖API
- WebGL 的 Hello WorldWeb
- react的”Hello World !“React
- Parsing Direct3D shader bytecode3D
- 高德地圖首席科學家任小楓:視覺智慧在高德地圖的應用地圖視覺
- 高德地圖app怎麼使用北斗地圖? 高德地圖設定北斗地圖的教程地圖APP
- uniapp使用高德地圖解析經緯度轉為中文地址APP地圖圖解
- [] == ![],走進==隱式轉換的世界
- 高德網路定位演算法的演進演算法
- MaxCompute在高德大資料上的應用大資料
- js高德API定位JSAPI
- 高德地圖未來行程規劃在哪裡? 高德地圖預設出行時間的技巧教程地圖行程
- 基於深度學習的影像分割在高德的實踐深度學習
- 高德深度資訊接入的平臺化演進
- UI自動化技術在高德的實踐UI
- String s = “hello“和String s = new String(“hello“)的區別
- gps wgs4座標與高德gcj02座標互轉GC
- 高德“成本價”:高精地圖的一次行業現實折射地圖行業
- 最長的Hello, World!(Python)Python
- 愛德曼:2020年全世界對科技公司的信任度全面下降
- 一個高效能的 Vue 高德地圖元件庫Vue地圖元件
- 持續交付體系在高德的實踐歷程
- 如虎添翼!高德地圖+Serverless 護航你的假日出行地圖Server