接下來的**段建立我們的opengl視窗。我花了很多時間來做決定是否建立固定的全屏模式這樣不需要許多額外的**,還是建立乙個容易定製的友好的視窗但需要更多的**。當然最後我選擇了後者。我經常在email中收到諸如此類的問題:怎樣建立視窗而不使用全螢幕?怎樣改變視窗的標題欄?怎樣改變視窗的解析度或pixel format(象素格式)?以下的**完成了所有這一切!儘管最好要學學材質,這會讓您寫自己的opengl程式變得容易的多!
正如您所見,此過程返回布林變數(true 或 false)。他還帶有5個引數:視窗的標題欄,視窗的寬度,視窗的高度,色彩位數(16/24/32),和全屏標誌(true --全屏模式, false--視窗模式 )。返回的布林值告訴我們視窗是否成功建立。
bool createglwindow(char* title, int width, int height, int bits, bool fullscreenflag)
檢視程式應該在全屏模式還是視窗模式下執行。如果應該是全屏模式的話,我們將嘗試設定全屏模式。
if (fullscreen) // 要嘗試全屏模式嗎?
else
}}
由於全屏模式可能失敗,使用者可能決定在視窗下執行,我們需要在設定螢幕/視窗之前,再次檢查fullscreen的值是true或false。
if (fullscreen) // 仍處於全屏模式嗎?
else
下一行**根據建立的窗體型別調整視窗。調整的目的是使得視窗大小正好等於我們要求的解析度。通常邊框會占用視窗的一部分。使用adjustwindowrectex 後,我們的opengl場景就不會被邊框蓋住。實際上視窗變得更大以便繪製邊框。全屏模式下,此命令無效。
adjustwindowrectex(&windowrect, dwstyle, false, dwexstyle); // 調整視窗達到真正要求的大小
下一段**開始建立視窗並檢查視窗是否成功建立。我們將傳遞createwindowex()所需的所有引數。如擴充套件風格、類名字(與您在註冊視窗類時所用的名字相同)、視窗標題、窗體風格、窗體的左上角座標(0,0 是個安全的選擇)、窗體的寬和高。我們沒有父視窗,也不想要選單,這些引數被設為null。還傳遞了視窗的例項,最後乙個引數被設為null。
注意我們在窗體風格中包括了 ws_clipsiblings 和 ws_clipchildren。要讓opengl正常執行,這兩個屬性是必須的。他們阻止別的窗體在我們的窗體內/上繪圖。
if (!(hwnd=createwindowex( dwexstyle, // 擴充套件窗體風格
"openg", // 類名字
title, // 視窗標題
ws_clipsiblings | // 必須的窗體風格屬性
ws_clipchildren | // 必須的窗體風格屬性
dwstyle, // 選擇的窗體屬性
0, 0, // 視窗位置
windowrect.right-windowrect.left, // 計算調整好的視窗寬度
windowrect.bottom-windowrect.top, // 計算調整好的視窗高度
null, // 無父視窗
null, // 無選單
hinstance, // 例項
null))) // 不向wm_create傳遞任何東東
下來我們檢查看視窗是否正常建立。如果成功, hwnd儲存視窗的控制代碼。如果失敗,彈出訊息視窗,並退出程式。
下面的**描述象素格式。我們選擇了通過rgba(紅、綠、藍、alpha通道)支援opengl和雙快取的格式。我們試圖找到匹配我們選定的色彩深度(16位、24位、32位)的象素格式。最後設定16位z-快取。其餘的引數要麼未使用要麼不重要(stencil buffer模板快取和accumulation buffer聚集快取除外)。
static pixelformatdescriptor pfd= // /pfd 告訴視窗我們所希望的東東,即視窗使用的畫素格式
;
如果前面建立視窗時沒有錯誤發生,我們接著嘗試取得opengl裝置描述表。若無法取得dc,彈出錯誤訊息程式退出(返回false)。
if (!(hdc=getdc(hwnd))) // 取得裝置描述表了麼?
設法為opengl視窗取得裝置描述表後,我們嘗試找到對應與此前我們選定的象素格式的象素格式。如果windows不能找到的話,彈出錯誤訊息,並退出程式(返回false)。
if (!(pixelformat=choosepixelformat(hdc,&pfd))) // windows 找到相應的象素格式了嗎?
windows 找到相應的象素格式後,嘗試設定象素格式。如果無法設定,彈出錯誤訊息,並退出程式(返回false)。
if(!setpixelformat(hdc,pixelformat,&pfd)) // 能夠設定象素格式麼?
正常設定象素格式後,嘗試取得著色描述表。如果不能取得著色描述表的話,彈出錯誤訊息,並退出程式(返回false)。
if (!(hrc=wglcreatecontext(hdc))) // 能否取得著色描述表?
如果到現在仍未出現錯誤的話,我們已經設法取得了裝置描述表和著色描述表。接著要做的是啟用著色描述表。如果無法啟用,彈出錯誤訊息,並退出程式(返回false)。
if(!wglmakecurrent(hdc,hrc)) // 嘗試啟用著色描述表
一切順利的話,opengl視窗已經建立完成,接著可以顯示它啦。將它設為前端視窗(給它更高的優先順序),並將焦點移至此視窗。然後呼叫resizeglscene 將螢幕的寬度和高度設定給透視opengl螢幕。
showwindow(hwnd,sw_show); // 顯示視窗
setforegroundwindow(hwnd); // 略略提高優先順序
setfocus(hwnd); // 設定鍵盤的焦點至此視窗
resizeglscene(width, height); // 設定透視 gl 螢幕
跳轉至 initgl(),這裡可以設定光照、紋理、等等任何需要設定的東東。您可以在 initgl()內部自行定義錯誤檢查,並返回 true (一切正常)或false (有什麼不對)。例如,如果您在initgl()內裝載紋理並出現錯誤,您可能希望程式停止。如果您返回 false的話,下面的**會彈出錯誤訊息,並退出程式。
if (!initgl()) // 初始化新建的gl視窗
到這裡可以安全的推定建立視窗已經成功了。我們向winmain()返回true,告知winmain()沒有錯誤,以防止程式退出。
return true; // 成功
}
第04課 OpenGL 旋轉
旋 在這一課裡,我將教會你如何旋轉三角形和四邊形。左圖中的三角形沿y軸旋轉,四邊形沿著x軸旋轉。上一課中我教給您三角形和四邊形的著色。這一課我將教您如何將這些彩色物件繞著座標軸旋轉。其實只需在上節課的 上增加幾行就可以了。下面我將整個例程重寫一遍。方便您知道增加了什麼,修改了什麼。我們增加兩個變數來...
第11課 OpenGL 飄動的旗幟
飄動的旗幟 這一課從第六課的 開始,建立乙個飄動的旗幟。我相信在這課結束的時候,你可以掌握紋理對映和混合操作。include 引入數學函式庫中的sin 我們將使用points陣列來存放網格各頂點獨立的x,y,z座標。這裡網格由45 45點形成,換句話說也就是由44格 44格的小方格仔依次組成了。wi...
Git命令學習 第01課
git config global user.name your name git config global user.email email example.com global引數,表示你這台機器上所有的git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的使用者名稱和email位址。gi...