在本次的工程實踐中,個人題目是《基於opengl的車載虛擬儀表軟件開發》,是一項校企合做的項目,在項目中之前作過的學長也向咱們分享了以往作過的相關的項目的源代碼,代碼主要是由c語言寫出,經過調用opengl的api接口規範來實現的圖像旋轉,拉伸,平移等操做,源代碼以下 :編程
#include "config.h"
#include "main.h"
#include "./lib/lib_opengl.h"
#include "./font.h"
#include "./resource.h"api
#ifdef DEBUG_LOCATION
#undef DEBUG_LOCATION
#endif
#define DEBUG_LOCATION "MAIN"數組
pthread_t taskTimer;
extern void *threadTimer(void);緩存
int main(int argc, char* argv[])
{
float rotate = 0;
FT_ULong strW[10] = {0};
u32 delay = 0;
InitGL();
initFont();
initResource();
loadImage(IDIMG_BG);服務器
enableGlStatus();網絡
//多線程
//pthread_create(&taskTimer, NULL, threadTimer, NULL)多線程
while(1)
{
delay++;
if(delay > 1000)
{
if(rotate < 9.0)
rotate += 1.0;
else
rotate = 0; 編程語言
delay = 0;編輯器
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 255.0f);
#if 0
glPushMatrix();
//themeHandle();函數
glTranslatef(960, 360, 0);
glDisable(GL_TEXTURE_2D);
glRotatef(45, 1, 0, 0);
glRotatef( rotate, 0, 1, 0);
//glVertexPointer(3, GL_FLOAT, 0, vertices);
glColor4f(255, 0, 0, 255);
static GLfloat front[] = { SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX,SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX,-SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX,-SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX,};
glVertexPointer(3, GL_FLOAT, 0, front);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColor4f(0, 255, 0, 255);
static GLfloat back[] = { -SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX,-SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX,SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,};
glVertexPointer(3, GL_FLOAT, 0, back);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColor4f(0, 0, 255, 255);
static GLfloat top[] = {SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,-SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,};
glVertexPointer(3, GL_FLOAT, 0, top);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColor4f(255, 255, 0, 255);
static GLfloat bottom[] = { -SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX,-SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX,SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX,SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX, };
glVertexPointer(3, GL_FLOAT, 0, bottom);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColor4f(0, 255, 255, 255);
static GLfloat left[] = {-SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX,-SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,};
glVertexPointer(3, GL_FLOAT, 0, left);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glColor4f(255, 0, 255, 255);
static GLfloat right[] = {SIZE_OF_BOX, -SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX, -SIZE_OF_BOX,SIZE_OF_BOX, -SIZE_OF_BOX, SIZE_OF_BOX,SIZE_OF_BOX, SIZE_OF_BOX, SIZE_OF_BOX,};
glVertexPointer(3, GL_FLOAT, 0, right);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();
#endif
glPushMatrix();
glEnable(GL_TEXTURE_2D);
drawImage(IDIMG_BG, 0, 0);
setFontColor(255, 255, 255, 255);
memset(strW, 0, sizeof(strW));
sprintl(strW, "%.0f", rotate);
drawFont(FONT_GEELY, 100, 100, 32, strW);
memset(strW, 0, sizeof(strW));
sprintl(strW, "%.0f", 9.0 - rotate);
drawFont(FONT_GEELY, 100, 150, 32, strW);
setFontColor(255, 255, 255, 255);
glPopMatrix();
swapBuffers();
}
}
return 0;
}
目錄結構中包括了主函數的.c和.h文件,此外還寫了一些函數和方法,和.h文件做爲頭文件,有一個lib文件夾用於放一些opengl所須要的庫,這些都構成了這個程序可以正確運行的基礎。
文件名主要突出了各個部件的功能,是按實際的效果命名的,好比像上圖中的Layout_AnimyPlane.c文件主要就是負責界面的佈局顯示的效果,readme主要是這套代碼的介紹;
類名中主要是調用了opengl庫中的一些經常使用的類以下:
函數名中 glClear主要用於清除指定的緩存數據並重設爲當前的清除值。mask是一個能夠經過邏輯或操做來指定多個數值的參數;
glClearClolor用於設置當前使用的清除顏色值,用於RGBA模式下對顏色緩存的清除工做。這裏的red,green,blue,alpha都會被截斷到【0,1】的範圍內。默認的清除顏色是(0,0,0,0)表示黑色。
glPushMatrix();glPushMatrix、glPopMatrix操做其實就至關於棧裏的入棧和出棧。
OpenGL是Open Graphics Library(開放性圖形庫)的縮寫,是一套三維圖形處理庫,也是該領域的工業標準。計算機三維圖形是指將用數據描述的三維空間經過計算轉換成二維圖像並顯示或打印出來的技術。
OpenGL就是支持這種轉換的程序庫,它源於SGI公司爲其圖形工做站開發的IRIS GL,在跨平臺移植過程當中發展成爲OpenGL。SGI在1992年7月發佈1.0版,後成爲工業標準,由成立於1992年的獨立財團OpenGL Architecture Review Board (ARB)控制。SGI等ARB成員以投票方式產生標準,並製成規範文檔(Specification)公佈,各軟硬件廠商據此開發本身系統上的實現。只有經過了ARB規範所有測試的實現才能稱爲OpenGL。1995年12月ARB批准了1.1版本,最新版規範是1999.5經過的1.2.1。
OpenGL被設計成獨立於硬件,獨立於窗口系統的,在運行各類操做系統的各類計算機上均可用,並能在網絡環境下以客戶/服務器模式工做,是專業圖形處理、科學計算等高端應用領域的標準圖形庫。它低端應用上的主要競爭對手是MS-Direct3D,該圖形庫是以COM接口形式提供的,因此極爲較複雜,穩定性差,另外微軟公司擁有該庫版權,目前只在Windows平臺上可用。D3D的優點在速度上,但如今低價顯卡都能提供很好的OpenGL硬件加速,因此作3D使用Direct3D已沒有特別的必要,在專業圖形處理特別是高端應用方面目前尚未出現以Direct3D技術爲基礎的例子,而遊戲等低端應用也有轉向OpenGL的趨勢。
微軟在Windows NT對OpenGL的支持始於3.51,在Windows9x中的支持始於Win95 OEM Service Release 2。Windows下經常使用的OpenGL庫有兩種,MS實現的和SGI實現的,MS-OpenGL調用會自動檢測是否存在顯示卡製造商提供的ICD(Installable Client DeviceDriver)驅動程序,有則調用ICD中的例程,不然才用CPU進行計算,因此能利用顯示卡的OpenGL加速能力。對開發者來講使用方法並無區別,只是有ICD驅動時更快些。SGI的版本是純軟件實現不能利用硬件加速而且SGI已經在1999年宣佈中止支持,但這套庫便於調試程序,仍有很多開發者使用。
SGI曾經宣佈研發OpenGL++,該圖形庫最大的特色是面象對象,提供了樹形場景支持,大大減省了使用OpenGL處理複雜場景的工做量。後來(1999)SGI宣佈與M$合做開發Ferihant,即Windows的下一代圖形處理體系,包括DirectX與OpenGL的低級圖形處理接口和以場景圖支持爲特色的高級接口,而且就此中止對其在Windows下的OpenGL實現的支持以示決心。此舉世矚目,你們都覺得Windows圖形處理快要過上幸福生活了,然而,不久,SGI宣佈停止合做,並撤回派出的科學家,Ferihant基本上夭折。SGI 稱終止合做的緣由是M$不願積極合做,光想把SGI 的技術合併進DirectX,真正內幕不詳。不過以SGI在圖形處理界的老大地位來講,仍是有幾分可信度的,由於M$初支持OpenGL就不積極。
OpenGL的特色
1.硬件無關的軟件接口
能夠在不一樣的平臺如Windows 9五、Windows NT、Unix、Linux、MacOS、OS/2之間進行移植。所以,支持OpenGL的軟件具備很好的移植性,能夠得到很是普遍的應用。
2.能夠在客戶機/服務器系統中工做,即具備網絡功能。
這一點對於製做大型3D圖形、動畫很是有用。例如,《玩具總動員》、《泰坦尼克號》等電影的電腦特技畫面就是經過應用OpenGL的網絡功能,使120多臺圖形工做站共同工做來完成的。
因爲OpenGL是與硬件無關的3D圖形接口,在 Windows、Unix/X-Windows、 MacOS、OS/2等不一樣版本的窗口相關部分(系統相關)略有差別。因爲OpenGL是3D圖形的底層圖形庫,沒有提供幾何實體圖元,不能直接用以描述場景。可是,經過一些轉換程序,能夠很方便地將AutoCAD、3DS等3D圖形設計軟件製做的DFX和3DS模型文件轉換成OpenGL的頂點數組。
另外,在OpenGL的基礎上還有Open Inventor、Cosmo3D、Optimizer等多種高級圖形庫,適應不一樣應用。其中,Open Inventor應用最爲普遍。該軟件是基於OpenGL面向對象的工具包,提供建立交互式3D圖形應用程序的對象和方法,提供了預約義的對象和用於交互的事件處理模塊,建立和編輯3D場景的高級應用程序單元,有打印對象和用其它圖形格式交換數據的能力。
1 文件結構
1.1 頭文件和定義文件的名稱是否合理?
1.2 頭文件和定義文件的目錄結構是否合理?
1.3 版權和版本聲明是否完整?
1.4 頭文件是否使用了 ifndef/define/endif 預處理塊?
1.5 頭文件中是否只存放「聲明」而不存放「定義」?
2 程序的版式
2.1 空行是否得體?
2.2 代碼行內的空格是否得體?
2.3 長行拆分是否得體?
2.4 「{」 和 「}」 是否各佔一行而且對齊於同一列?
2.5 一行代碼是否只作一件事?如只定義一個變量,只寫一條語句。
2.6 If、for、while、do 等語句自佔一行,不論執行語句多少都要加「{}」。
2.7 在定義變量(或參數)時,是否將修飾符 * 和 & 緊靠變量名?
2.8 註釋是否清晰而且必要?
2.9 註釋是否有錯誤或者可能致使誤解?
2.10 類結構的 public, protected, private 順序是否在全部的程序中保持一致?
3 命名規則
3.1 命名規則是否與所採用的操做系統或開發工具的風格保持一致?
3.2 標識符是否直觀且能夠拼讀?
3.3 標識符的長度應當符合「min-length && max-information」原則?
3.4 程序中是否出現相同的局部變量和所有變量?
3.5 類名、函數名、變量和參數、常量的書寫格式是否遵循必定的規則?
3.6 靜態變量、全局變量、類的成員變量是否加前綴?
4 表達式與基本語句
4.1 若是代碼行中的運算符比較多,是否已經用括號清楚地肯定表達式的操做順序?
4.2 是否編寫太複雜或者多用途的複合表達式?
4.3 是否將複合表達式與「真正的數學表達式」混淆?
4.4 是否用隱含錯誤的方式寫 if 語句? 例如
(1) 將布爾變量直接與 TRUE、FALSE 或者 一、0 進行比較。
(2) 將浮點變量用「==」或「!=」與任何數字比較。
(3) 將指針變量用「==」或「!=」與 NULL 比較。
4.5 若是循環體內存在邏輯判斷,而且循環次數很大,是否已經將邏輯判斷移到循環體的外面?
4.6 Case 語句的結尾是否忘了加break?
4.7 是否忘記寫 switch 的 default 分支?
4.8 使用 goto 語句時是否留下隱患? 例如跳過了某些對象的構造、變量的初始化、重要的計算等。
5 常量
5.1 是否使用含義直觀的常量來表示那些將在程序中屢次出現的數字或字符串?
5.2 在 C++ 程序中,是否用const 常量取代宏常量?
5.3 若是某一常量與其它常量密切相關,是否在定義中包含了這種關係?
5.4 是否誤解了類中的const 數據成員?由於const 數據成員只在某個對象生存期內是常量,而對於整個類而言倒是可變的。
6 函數設計
6.1 參數的書寫是否完整?不要貪圖省事只寫參數的類型而省略參數名字。
6.2 參數命名、順序是否合理?
6.3 參數的個數是否太多?
6.4 是否使用類型和數目不肯定的參數?
6.5 是否省略了函數返回值的類型?
6.6 函數名字與返回值類型在語義上是否衝突?
6.7 是否將正常值和錯誤標誌混在一塊兒返回?正常值應當用輸出參數得到,而錯誤標誌用 return 語句返回。
6.8 在函數體的「入口處」,是否用 assert 對參數的有效性進行檢查?
6.9 使用濫用了 assert? 例如混淆非法狀況與錯誤狀況,後者是必然存在的而且是必定要做出處理的。
6.10 return 語句是否返回指向「棧內存」的「指針」或者「引 用」?
6.11 是否使用const 提升函數的健壯性?const 能夠強制保護函數的參數、返回值,甚至函數的定義體。「Use const whenever you need」
7 內存管理
7.1 用 malloc 或 new 申請內存以後,是否當即檢查指針值是否爲 NULL?(防止使用指針值爲 NULL 的內存)
7.2 是否忘記爲數組和動態內存賦初值?(防止將未被初始化的內存做爲右值使用)
7.3 數組或指針的下標是否越界?
7.4 動態內存的申請與釋放是否配對?(防止內存泄漏)
7.5 是否有效地處理了「內存耗盡」問題?
7.6 是否修改「指向常量的指針」的內容?
7.7 是否出現野指針?例如
I 指針變量沒有被初始化。
II 用 free 或delete 釋放了內存以後,忘記將指針設置爲 NULL。
7.8 是否將 malloc/free 和 new/delete 混淆使用?
7.9 malloc 語句是否正確無誤?例如字節數是否正確?類型轉換是否正確?
7.10 在建立與釋放動態對象數組時,new/delete 的語句是否正確無誤?
8 C++ 函數的高級特性
8.1 重載函數是否有二義性?
8.2 是否混淆了成員函數的重載、覆蓋與隱藏?
8.3 運算符的重載是否符合制定的編程規範?
8.4 是否濫用內聯函數?例如函數體內的代碼比較長,函數體內出現循環。
8.5 是否用內聯函數取代了宏代碼?
9 類的構造函數、析構函數和賦值函數
9.1 是否違背編程規範而讓 C++ 編譯器自動爲類產生四個缺省的函數:
(1)缺省的無參數構造函數;
(2)缺省的拷貝構造函數;
(3)缺省的析構函數;
(4)缺省的賦值函數。
9.2 構造函數中是否遺漏了某些初始化工做?
9.3 是否正確地使用構造函數的初始化表?
9.4 析構函數中是否遺漏了某些清除工做?
9.5 是否錯寫、錯用了拷貝構造函數和賦值函數?
9.6 賦值函數通常分四個步驟:
(1)檢查自賦值;
(2)釋放原有內存資源;
(3)分配新的內存資源,並複製內容;
(4)返回 *this。是否遺漏了重要步驟?
9.7 是否正確地編寫了派生類的構造函數、析構函數、賦值函數?注意事項:
I 派生類不可能繼承基類的構造函數、析構函數、賦值函數。
II 派生類的構造函數應在其初始化表裏調用基類的構造函數。
III 基類與派生類的析構函數應該爲虛(即加 virtual 關鍵字)。
IV 在編寫派生類的賦值函數時,注意不要忘記對基類的數據成員從新賦值。
10 類的高級特性
是否違背了繼承和組合的規則?
I 若在邏輯上 B 是 A 的「一種」,而且 A 的全部功能和屬性對B 而言都有意義,則容許B 繼承A 的功能和屬性。
II 若在邏輯上 A 是 B 的「一部分」(a part of),則不容許 B 從A 派生,而是要用A 和其它東西組合出 B。
11 其它常見問題
11.1 數據類型問題:
(1)變量的數據類型有錯誤嗎?
(2)存在不一樣數據類型的賦值嗎?
(3)存在不一樣數據類型的比較嗎?
11.2 變量值問題:
(1)變量的初始化或缺省值有錯誤嗎?
(2)變量發生上溢或下溢嗎?
(3)變量的精度夠嗎?
11.3 邏輯判斷問題:
(1)因爲精度緣由致使比較無效嗎?
(2)表達式中的優先級有誤嗎?
(3)邏輯判斷結果顛倒嗎?
11.4 循環問題:
(1)循環終止條件不正確嗎?
(2)沒法正常終止(死循環)嗎?
(3)錯誤地修改循環變量嗎?
(4)存在偏差累積嗎?
11.5 錯誤處理問題:
(1)忘記進行錯誤處理嗎?
(2)錯誤處理程序塊一直沒有機會被運行?
(3)錯誤處理程序塊自己就有毛病嗎?如報告的錯誤與實際錯誤不一致,處理方式不正確等等。
(4)錯誤處理程序塊是「馬後炮」嗎?如在被它被調用以前軟件已經出錯。
11.6 文件 I/O 問題:
(1)對不存在的或者錯誤的文件進行操做嗎?(2)文件以不正確的方式打開嗎?(3)文件結束判斷不正確嗎?(4)沒有正確地關閉文件嗎?