C++ X Win32 X Rendering 从入门到放弃

C++ X Win32 X Rendering 從入門到放棄

GDI, Direct2D, DirectX, So messy!

不不,我不是在開玩笑,我真的差點就直接放棄了好伐

爲了重製偽春菜内核,並盡可能將其渲染後端做的完美,我碰了那個我這個年紀怎麽都不該去碰的C++和Win32,以及他們的渲染。

CPP這樣反人類的語言之所以能活到今天我覺得主要還是靠他的背後撐腰大佬微軟和古代程序員的信仰,而且太多東西在上個世紀就被寫成,無法修改了,而上個世紀基本上就是C++的元年,儘管python出生於1994年但是它在那時的地位根本無法和主流語言同臺競技。

於是,各界使用CPP編寫的東西多少都會有那麽一些 惡  臭  歷  史  遺  留  物 就這麽被留下來了(便乘),包括我們的Microsoft,當然,這其實也沒有辦法,畢竟一個操作系統,似乎用CPP才能算是最妥當的手段,而且畢竟在當時那個年代沒有什麽別的選擇,所以這并不能怪誰。可我到現在還是希望微軟能把Win32的那些函數宏啊枚舉(數值)宏啊和C風格字符串稍微封裝,優化一下,不然作爲一個被現在modern語言慣壞的程序員光是指針和傳址賦值這種編程模式我都真的很難適應啊(捂臉)

好吧好像也有,std庫?應該還是很好用的,畢竟人家《C++ Primer Plus》裏都説了,開發std庫的人是一群强迫症病入膏肓角度刁鑽的神經病非常在意效率的算法工程師,所以這玩意兒本身應該認可度還是相當高的。

所以孩♂子啊,using namespace std 吧!

好了,不吐槽C++了,那麽來説説我們這次的Win32最偉大也最毒瘤的2D渲染機制(引擎)

GDI/GDI+(Graphic Devive Interface)

以及後來做了一個好了許多的卻沒人用的

D2D(Direct2D)

先來説説GDI,GDI+無非是在Windows 2000的時候做的一個GDI的升級版本,更易於使用,但其本質是相同的,他在早期的Windows裏,撐起的就是渲染的壟斷地位(當然應該也有許多其他渲染引擎,但Windows9X的時候系統級的渲染器在Windows裏就他一個,一般的圖形工作基本就會教給它),我不得不承認他很强大,他用途廣汎,它和Windows兼容性超好,他做了好多事,可是,可是。。他略有些過時的不美觀編寫模式咱先不説,他的效率我沒有具體測過但是他是用軟件渲染(也就是CPU處理渲染程序)我也不抱什麽期待了,可他渲染出來的圓圈鋸齒大的清晰可見每一根毛都看得清清楚楚實在令在下無法接受,而更有趣的是,即使在今天看來這樣拙劣,也仍然有無數的應用或多或少的使用著他的功能。而終於微軟在開發DirectX渲染引擎一邊欣賞著《光環》那無與倫比的畫面表現一邊在老闆的眼皮子底下搞内部小斗爭的時候也差不多意識到了自己來到了科技發達的21世紀(笑),不願留這麽個僅有兼容性的瓜娃子獨霸全場了。於是,DirectX家族多了一位專注平面渲染三十年的Direct2D。

而Direct2D則是非常靈性的東西了,Direct2D的目標定位和GDI是同樣的,渲染UI,2D應用程序,但是D2D因爲能用到硬件加速(也就是用到顯卡去渲染來提高效率)和更高的渲染質量(媽媽再也不用擔心我的圓圈有超大鋸齒了),而且也同時能夠兼容GDI的DC,所以對於一般的應用來説,這個可以説是兩全其美了(除了偶爾可能會出現的一些魔幻bug),不過呢,他——麻煩,對,初始化的時候有很强的自定義性和很多選項,以及需要初始化的資源很多,就連基本的導入圖片文件都需要近百行代碼才能實現,不過在實際作用的渲染代碼上,它比GDI的代碼看上去會好一些。當然,不像我這樣有特別需要的話,GDI+渲染些位圖其實也足夠用啦。

MSDN官方嘲諷可還行

而這倆玩意兒在Windows裏有多重要呢?基本上所有擁有圖形(graphic)方面功能的應用都一定會用到這兩者之一或混用(游戲除外,游戲會用的一般是OpenGL或者DirectX這樣更加具有專業性和3D渲染能力的引擎),也就是說,只要不是只用到最基本的Win32控件程序,稍微需要在界面上美化一下什麽的,GDI或者D2D八重櫻或者德莉莎必須得上一個。

當然如果你的强迫症足夠嚴重的話,可以考慮使用DirectX(DXGI)的3D引擎來渲染2D窗口,也是完全沒有問題的!而且也有相關的文章裏説過大概該怎麽做(而且對這三個引擎的介紹大概比這裏還透徹吧),DirectX 最高質量 最强性能 童叟無欺 滿足你最刁鑽的角度!

What the hell is DC and RT, how it works?

DC(Device Context),是Windows窗口渲染中最重要的概念,他叫做“設備上下文”,是個很玄乎的名字,但其實,他其實就是一個類似於canvas(畫布)的struct。每個窗口(HWND)畫面都有一個DC,包括整個Windows所呈現出來的屏幕,都是一個大大的DC,所以在Windows下獲取屏幕截圖,其實就是獲取了屏幕的DC。

好了,雖然DC是一塊可以隨意調教的畫布,但既然DC也是一個程序中的結構體(struct),就説明他也可以被就那麽藏在内存裏,深藏不露,也不顯示出來,這種,就叫做“内存DC”(memory DC),爲什麽需要他呢?因爲如果我們現場渲染任何一樣東西都需要程序去一步一步按你的指令渲染,而渲染這個過程并不是一個可以快到人眼無法捕捉到的過程,但我們也沒法看清他在一步一步地渲染,而實際的效果,便是閃爍,我想我們總不希望自己渲染的畫面總是在很鬼畜地閃爍個不停吧,那麽有什麽辦法呢?寫一個内存DC,等我們在内存裏渲染好了所有内容,再放到實際我們可以看到的畫面上,就不會有閃爍啦。就像是在烤肉店裏,如果我們不希望有自己一塊一塊放到烤盤上烤的這個繁瑣的過程的話,可以叫服務員現在厨房裏都烤好,端上來就能吃啦(雖然我還是喜歡自己烤hh)。

而RT(Render Target)則不是這麽廣汎的一個定義了,比起DC,他只是一個Direct2D裏的渲染器罷了,但他對Direct2D來説則是一個重要的概念,Direct2D爲了兼容性考慮,他不止應該渲染在窗口上,也要能夠渲染在DC上,渲染在位圖上,等等,這時候,爲了告訴Direct2D他應該渲染在哪裏,則有了不同的Render Target,他們各個也具備了不同的功能,爲了兼容。這樣同樣的渲染代碼的最終效果,在哪裏都是是一樣的。這點也必須得表揚MS一下,能在兼容性上做這麽好。

這次算是理論篇?不過本來還是想放一些實際代碼來更好地説明一下來著的,但目前這個我感覺我還是玩得還不夠透徹,等我把我的偽春菜專用渲染器寫出來了(並去西方提高一下姿勢水平),我再來總結一番(談一談人生經驗)

那麽差不多就到這裏了,非常感謝閲讀~ 接下來兩天可能會更新或者改掉一些錯誤的地方。還有就是emmmmmmm本文章可能也有一些誤區,或者我理解錯的地方,歡迎各位大佬來指(da)正(lian)。

 

No Comments

Add your comment

Translate/繁简转换