OpenGL研究, GUI框架分析, 虚拟机比较, Win10历险记, WxWidget, uboot, WireShark
http://antkillerfarm.github.io/
OpenGL研究
書籍
我手上其實有幾本關于OpenGL的實體書,但是比較了一下之后,發現還是電子版的《OpenGL編程指南》(俗稱OpenGL紅寶書)寫的更好一些。該書目前已經出到第8版,我看的是第7版中文版的電子版。該書的官網是:
http://www.opengl-redbook.com
可以從上面獲得書中例子的源代碼。
教程
書籍偏重理論,而教程偏重實踐。這里推薦Nate Robins的教程,該教程在上面的書中也多次提及過。它的網址是:
http://user.xmission.com/~nate/opengl.html
該教程和上面的書籍一樣,都是基于GLUT庫的,因此代碼的移植性相當好。
教程中示例程序的操作非常簡單,基本沒什么好說的。唯一需要注意的是,點擊鼠標右鍵會彈出菜單。而且右邊屏幕的菜單不可點擊,否則程序會退出,但可以用菜單上標注的鍵盤快捷鍵選中。這些都是看源代碼之后,才發現的。
環境準備
Ubuntu
主要需要這幾個包:
freeglut3-dev。最經典的跨平臺OpenGL工具包。書籍和教程都用且只用了它。
libglew-dev。可以用來運行GLSL的相關例子。這個對于OpenGL新特性的支持要強于glut。
libglfw-dev。一個glut的替代品。glut適合做demo,而這個可以用來做產品。
libepoxy-dev。GTK項目選擇的OpenGL庫。
OpenGL vs Direct X
這兩者的爭斗已經有近20年的歷史了。我最初知道它們,還是在2003年,跟隨同學W學習VC的時候。當時我的判斷是由于Direct X集成了開發游戲所需的一系列工具,因此它在PC上將超越OpenGL。后來的情況也差不多是這樣的。
不過坦率的說,我對Direct X的了解,僅限于DirectDraw和DirectSound,基本上只夠開發一些2D應用。
去年底由于想實現一些特殊的Android特效,才接觸到OpenGL。按照我的估計,今后隨著移動應用越來越重要,OpenGL的應用前景要好于Direct X。而且這個要不了多久,估計也就是這兩年的事情。特此備忘。
各種GUI框架分析
綜合型GUI框架
如MFC、Qt、GTK、Minigui、WxWidget等。這些框架不僅提供窗口管理,而且還提供了豐富的控件,因此從分類學的角度又被稱為widget toolkits。除此之外,部分框架還提供了一些非GUI的功能模塊,方便用戶開發APP。
由于提供了控件,因此控件的繪制和消息在控件之間的分發,就成為了實現的難點。
從流派來看,又可分為兩類:
1.以WxWidget為代表的框架,使用native控件及窗口系統。
2.以GTK為代表的框架,采用自繪控件,并管理控件消息的方式。我之前在L公司時,公司產品用的就是這種方案,它的特點是APP在所有平臺的外觀都是一致的。
簡易型GUI框架
如glut、SDL等。這類框架僅提供窗口系統的功能,不提供控件。
特效型
如cocos2d,clutter等。這類框架構建于前兩者之上,提供動畫之類的特效。一些諸如圓形按鈕、浮動按鈕之類的非傳統UI特效,在這類框架上實現起來要遠比傳統框架簡單。
GUI框架的圖形渲染
自繪型GUI框架需要自己來處理圖形渲染。圖形渲染主要包括位圖貼圖和矢量繪圖兩部分。
早期框架的圖形渲染處理主要有以下幾個步驟:
1.申請一塊內存緩沖區,按照特定格式組成像素緩沖區。
2.對像素緩沖區進行圖形渲染。
3.將像素緩沖區繪制到顯示設備上。
其中前兩步都是平臺無關的操作,只有第3步和硬件實現有關。這也是眾多框架能跨平臺的奧秘所在。
上面這種方法將圖形計算完全放到CPU上。而隨著硬件的進步,越來越多的設備配備了專門的GPU。因此現代GUI框架的圖形處理步驟變成了這樣:
1.申請一塊顯存緩沖區,按照特定格式組成像素緩沖區。
2.對像素緩沖區進行圖形渲染。
3.將像素緩沖區繪制到顯示設備上。
而完成這些操作的接口就是OpenGL。
這也是SDL從v1.2升級到v2.0所做的最大的改變。
虛擬機
早期如Bochs之類的沒用過,現在估計也沒什么人用了吧。
現在主要是以下三個選擇:
1.VMware。商業收費軟件。有免費版本的VMware Player,但該版本不可創建虛擬機,只可使用別人已經建好的虛擬機。
2.VirtualBox。開源免費軟件。
3.Qemu。Qemu的易用性不佳,作為使用的話,能不用就不用了。但其不僅開源,而且支持的架構也很多,有的時候往往是唯一之選。作為研究學習來說,這個是首選。
這里主要討論前兩者的選擇。
VMware由于是收費軟件之故,因此用戶的軟件升級是個大問題。(土豪除外,有錢的話,這個就不是事了。)而舊的軟件,往往對新的Linux發行版的支持較差。很多情況下,VMware Tool因為這個原因總是無法完美運行。嚴重影響了軟件的易用性。
反之,VirtualBox就沒有這些問題。雖然比較同期的VMware來說,VirtualBox的性能略遜。但是一般來說,科技行業里領先半年就已經是巨大的優勢了。我相信現在的VirtualBox,無論如何也不會弱于兩年前的VMware。
因此與其守著過時的VMware 8.0,還不如換用VirtualBox,這就是我的選擇。
Win10歷險記
我大概在2015年4、5月間,聽說了Win10免費升級的消息。于是一直很期待7月29日的到來。果然到了29日當天下午的時候,公司電腦就收到了升級的通知。然而由于網速不給力,當天并未對公司電腦進行升級。倒是晚上在家里的電腦上,雖然耗時2小時,但卻一路順利的升級成功。
Win10給人的第一感覺,其實和Win8差不多,不過是加了個更像Win7的開始菜單而已。不過既來之則安之,一段時間用下來,總算還是要比Win7強不少的。
又過了幾天,公司的電腦也升級成功。正得意間,忽然發現VirtualBox在Win10下工作不正常。查了VirtualBox官網方知,其目前尚不支持Win10 Host。于是不得不重新降級到Win7??磥韲L鮮也是有得有失的。對于工作用的電腦,有的時候夠用就好,沒必要什么都求新的。
WxWidget
WxWidget在windows平臺的安裝包是個奇葩的東西,它并不是可執行文件的安裝包,而是個源代碼安裝包。因此安裝之后,還需要編譯,才能使用。
以MinGW編譯為例,說一下編譯的步驟:
1.設置MinGW環境。這里需要強調的是MinGW和WxWidget的安裝路徑都不能有空格。
2.進入build/msw文件夾,執行以下命令:
mingw32-make -f makefile.gcc BUILD=release SHARED=0 MONOLITHIC=1 UNICODE=1 CXXFLAGS=-fno-keep-inline-dllexport
uboot
從uboot到Linux
這里以uboot 2014年11月的主線代碼為例分析從uboot到linux的全過程。之所以寫這篇文章,是由于網上的資料多數都很陳舊,諸如start_armboot之類的函數在新的代碼里根本找不到了。由于uboot支持的CPU以及Board非常的多,所以本文僅以Samsung exynos為例來介紹這個過程。
從上電到uboot啟動:
1./arch/arm/cpu/armv7/start.S: reset——uboot的匯編入口
2./arch/arm/lib/crt0.S: _main
3./arch/arm/lib/board.c: board_init_f——初始化第一階段
4./arch/arm/lib/board.c: board_init_r——初始化第二階段
5./common/main.c: main_loop——uboot主循環
uboot啟動Linux
1.uboot中有個bootd的命令選項,執行該命令會進入/common/cmd_bootm.c: do_bootd
2.common/cli.c: run_command,傳入bootcmd命令作為參數。
3.common/cmd_bootm.c: do_bootm
4.arch/arm/lib/bootm.c: do_bootm_linux
5.arch/arm/lib/bootm.c: do_jump_linux——跳轉到Linux內核的入口地址
uImage格式是專為uboot開發的格式,主要解決了uboot和linux在嵌入式設備的存儲上共存的問題。
uboot命令處理流程
從main_loop到命令處理:
1./common/main.c: main_loop
2./common/cli.c: cli_loop
3./common/cli_simple.c: cli_simple_loop
4./common/cli.c: run_command_repeatable
5./common/cli_simple.c: cli_simple_run_command
6./common/cli_simple.c: cmd_process
7./common/command.c: cmd_call
上面的流程僅是主循環如何調用命令回調函數的過程。下面介紹一下命令是如何聲明、存儲和查詢的。
首先查看鏈接腳本,uboot使用的鏈接腳本文件名為u-boot.lds。根據cpu和board的不同,u-boot.lds也有所差異。例如Samsung exynos所用的u-boot.lds在arch\arm\cpu下。
其中有個.u_boot_list段就是用來存儲命令數據的。它的表述如下所示:
.u_boot_list : {KEEP(*(SORT(.u_boot_list*)));}命令的聲明,通常使用U_BOOT_CMD宏。這個宏最終展開為:
_type _u_boot_list_2_##_list##_2_##_name __aligned(4) \__attribute__((unused, \section(".u_boot_list_2_"#_list"_2_"#_name)))這也就是.u_boot_list*的來歷了。
可以使用/common/command.c: find_cmd函數在命令列表中,根據名稱查找命令數據。
環境變量
/common/cmd_nvedit.c: setenv–這個函數用于設置環境變量的值。它的原理是:
1.首先在環境變量數組default_environment中,更改相應內容的值。
2.然后調用saveenv,保存default_environment的值,到具體的硬件中。例如NAND設備的代碼在/common/env_nand.c中。
在linux內核層面也可以修改uboot的環境變量。通常的做法步驟如下:
1.uboot代碼中有個tools/env文件夾。編譯改代碼可以得到fw_printenv文件。編譯的命令是:
make env
2.將fw_printenv放到linux系統的/usr/sbin路徑下,并創建符號鏈接fw_setenv。此處的符號鏈接并不是可有可無的,這里有個編程小技巧:如何用同一個可執行文件執行不同的功能呢?
除了最常用的使用參數區分的方法之外,還可以采用如下方法:
int main(int argc, char *argv[])
這是main函數的聲明,其中argv是參數數組,而argv[0]是輸入的命令本身,因此可以使用這個作為判斷依據,來區分不同的用途。這時候符號鏈接也就派上用場了。
tftpsrv
有些uboot提供了tftpsrv的功能,用于從網口傳輸文件(主要是燒寫用的鏡像文件)。
該tftpsrv默認監聽的ip地址保存在uboot的ip環境變量中。如果需要的話,可進行必要的修改并重啟。
客戶端傳輸鏡像文件時,需要采用二進制模式。命令如下:
tftp 10.3.9.161 -m binary -c put <file name>
WireShark
WireShark是一個網絡協議包分析工具,最初名叫Ethereal。它的官網是:
www.wireshark.org
在ubuntu上的安裝
sudo apt-get install wireshark
安裝好了之后,還不能立即使用。需要給/usr/bin/dumpcap提升權限,才能使用WireShark的抓包功能。否則會出no interfaces的錯誤。
提升權限的方法有:
1.root方式。
命令行:sudo wireshark
桌面圖標:gksudo wireshark
sudo dpkg-reconfigure wireshark-common
sudo usermod -a -G wireshark <your user name>
sudo chgrp wireshark /usr/bin/dumpcap
sudo chmod 4750 /usr/bin/dumpcap
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
最后注銷當前用戶,重新登陸即可。
過濾器規則
WireShark以豐富的過濾器著稱,現將我使用到的過濾器規則摘錄如下:
ip.src == 10.3.9.234 || ip.dst == 10.3.9.234
過濾源地址和目標地址。
tcp matches Bob
匹配特定字符串。
tcp.stream eq id
將一次TCP交互的包過濾出來,id表示是第幾次交互。
總結
以上是生活随笔為你收集整理的OpenGL研究, GUI框架分析, 虚拟机比较, Win10历险记, WxWidget, uboot, WireShark的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu使用技巧(一)
- 下一篇: ZigBee,ZStack