在win32項目中開發的程序windows
小知識: 控制檯應用程序運行就是dos的界面 項目通常採用了可視化開發 開發出來的東西就像QQ之類的 是有窗口界面的數組
程序運行結果是這樣的緩存
源代碼:對第45行進行覆蓋框架
1 #include <windows.h> //Windows的頭文件 2 #include <gl\gl.h> //包含OpenGL基本庫 3 #include <gl\glu.h> //包含OpenGL實用庫 4 #include <gl\glaux.h> //包含OpenGL輔助庫 5 #include <gl\glut.h> //包含OpenGL工具庫 6 //設置程序中使用的全部變量 7 HGLRC hRC = NULL; //OpenGL着色描述表句柄 8 HDC hDC = NULL; //設備描述表句柄 9 HWND hWnd = NULL; //保存窗口句柄 10 HINSTANCE hInstance; //保存程序的實例 11 //增長兩個全局變量來控制這兩個對象的旋轉。 12 GLfloat rtri; //用於三角形的角度 13 GLfloat rquad; //用於四邊形的角度 14 15 bool keys[256]; //保存鍵盤按鍵的數組 16 bool active = TRUE; //口的活動標誌,缺省爲TRUE 17 bool fullscreen = TRUE; //全屏標誌缺省,缺省設定成全屏模式 18 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //WndProc定義 19 GLvoid ReSizeGLScene(GLsizei width, GLsizei height) //重置OpenGL窗口大小 20 { 21 if (height == 0) //防止被零除 22 { 23 height = 1; 24 } //將Height設爲 25 glViewport(0, 0, width, height); //重置當前的視口 26 glMatrixMode(GL_PROJECTION); //選擇投影矩陣 27 glLoadIdentity(); //重置投影矩陣 28 gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); //設置視景體 29 glMatrixMode(GL_MODELVIEW); //選擇模型觀察矩陣 30 glLoadIdentity(); //重置模型觀察矩陣 31 } 32 int InitGL(GLvoid) //開始對OpenGL進行全部設置 33 { 34 glShadeModel(GL_SMOOTH); //啓用陰影平滑 35 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //黑色背景 36 glClearDepth(1.0f); //設置深度緩存 37 glEnable(GL_DEPTH_TEST); //啓用深度測試 38 glDepthFunc(GL_LEQUAL);//所做深度測試的類型 39 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //告訴系統對透視進行修正 40 return TRUE; //初始化OK 41 } 42 43 44 45 46 47 //將這段代碼覆蓋以後,往裏面添加東西。就能進行OpenGL 48 49 50 int DrawGLScene(GLvoid) //開始進行全部的繪製 51 { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度緩存 52 glLoadIdentity(); //重置當前的模型觀察矩陣 53 return TRUE; } // 一切OK 54 55 56 57 58 59 60 61 62 GLvoid KillGLWindow(GLvoid) //正常銷燬窗口 63 { 64 if (fullscreen) { //處於全屏模式嗎? 65 ChangeDisplaySettings(NULL, 0); //切回桌面 66 ShowCursor(TRUE); 67 } //顯示鼠標指針 68 if (hRC) { //擁有OpenGL着色描述表嗎? 69 if (!wglMakeCurrent(NULL, NULL)) { 70 //可否釋放DC和RC描述表? 71 MessageBox(NULL, "釋放DC和RC失 敗。", "關閉錯誤", MB_OK | MB_ICONINFORMATION); 72 } 73 if (!wglDeleteContext(hRC)){ //可否刪除RC? 74 MessageBox(NULL, "釋放RC失 敗。", "關閉錯誤", MB_OK | MB_ICONINFORMATION); 75 } 76 hRC = NULL; 77 } //將RC設爲NULL 78 if (hDC && !ReleaseDC(hWnd, hDC)) { 79 //可否釋放DC? 80 MessageBox(NULL, "釋放DC失敗。", "關閉錯誤", MB_OK | MB_ICONINFORMATION); 81 hDC = NULL; 82 } //將DC設爲NULL 83 if (hWnd && !DestroyWindow(hWnd)) { 84 //可否銷燬窗口? 85 MessageBox(NULL, "釋放窗口句柄失 敗。", "關閉錯誤", MB_OK | MB_ICONINFORMATION); 86 hWnd = NULL; 87 } //將hWnd設爲NULL 88 if (!UnregisterClass("OpenGL", hInstance)) { 89 //可否註銷類? 90 MessageBox(NULL, "不能註銷窗口類 。", " 關閉錯誤", MB_OK | MB_ICONINFORMATION); 91 hInstance = NULL; 92 } 93 } //hInstance爲NULL 94 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) 95 { 96 GLuint PixelFormat; //保存查找匹配的結果 97 WNDCLASS wc; //窗口類結構 98 DWORD dwExStyle; //擴展窗口風格 99 DWORD dwStyle; //窗口風格 100 RECT WindowRect; //取得矩形的左上角和右下角的座標值 101 WindowRect.left = (long)0; //將Left 設爲 102 WindowRect.right = (long)width; //將Right設爲要求的寬度 103 WindowRect.top = (long)0; //將Top設爲0 104 WindowRect.bottom = (long)height; //將Bottom設爲要求的高度 105 fullscreen = fullscreenflag; //設置全局全屏標誌 106 hInstance = GetModuleHandle(NULL); //取得窗口實例 107 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //移動時重畫,爲窗口取得DC 108 wc.lpfnWndProc = (WNDPROC)WndProc; //WndProc處理消息 109 wc.cbClsExtra = 0; //窗口類額外字節數 110 wc.cbWndExtra = 0; //窗口實例額外字節數 111 wc.hInstance = hInstance; //設置實例 112 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); //裝入缺省圖標 113 wc.hCursor = LoadCursor(NULL, IDC_ARROW); //裝入鼠標指針 114 wc.hbrBackground = NULL; //GL不須要背景 115 wc.lpszMenuName = NULL; //不須要菜單 116 wc.lpszClassName = "OpenGL"; //設定類名字 117 if (!RegisterClass(&wc)) //嘗試註冊窗口類 118 { 119 MessageBox(NULL, "註冊窗口失敗。", " 錯誤", MB_OK | MB_ICONEXCLAMATION); 120 return FALSE; //退出並返回FALSE 121 } 122 if (fullscreen) //要嘗試全屏模式嗎? 123 { 124 DEVMODE dmScreenSettings; //設備模式 125 memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); //確保內存爲零 126 dmScreenSettings.dmSize = sizeof(dmScreenSettings); //Devmode結構大小 127 dmScreenSettings.dmPelsWidth = width; //所選屏幕寬度 128 dmScreenSettings.dmPelsHeight = height; //所選屏幕高度 129 dmScreenSettings.dmBitsPerPel = bits; //每像素所選的色彩深度 dmScreenSettings.dmFields= DM_BITSPERPEL|DM_PELSWIDTH| DM_PELSHEIGHT; 130 //嘗試設置顯示模式並返回結果。 131 //注: CDS_FULLSCREEN 移去了狀態條。 132 if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 133 { 134 //若模式失敗,退出或在窗口內運行 135 if (MessageBox(NULL, "全屏模式在當前 顯卡上設置失敗!使用窗口模式? ", "OpenGL程序", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) 136 { 137 fullscreen = FALSE; //選擇窗口模式 138 } 139 else { 140 //彈出對話框告訴用戶程序結束 141 MessageBox(NULL, "程序將被關 閉。", "錯誤", MB_OK | MB_ICONSTOP); 142 return FALSE; // 退出並返回FALSE 143 } 144 } 145 } 146 if (fullscreen) //仍處於全屏模式嗎? 147 { 148 dwExStyle = WS_EX_APPWINDOW; //擴展窗體風格 149 dwStyle = WS_POPUP; //窗體風格 150 ShowCursor(FALSE); //隱藏鼠標指針 151 } 152 else 153 { 154 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //擴展窗體風格 155 dwStyle = WS_OVERLAPPEDWINDOW; // 窗體風格 156 } 157 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); //調整窗口到要求大小 158 if (!(hWnd = CreateWindowEx(dwExStyle, //擴展窗體風格 159 "OpenGL", //類名字 160 title, //窗口標題 161 WS_CLIPSIBLINGS | //必須窗體風格屬性 162 WS_CLIPCHILDREN |//必須窗體風格屬性 163 dwStyle, //選擇的窗體屬性 164 0, 0, //窗口位置 165 WindowRect.right - WindowRect.left, //計算調整好的窗口寬度 166 WindowRect.bottom - WindowRect.top, //計算調整好的窗口高度 167 NULL, //無父窗口 168 NULL, //無菜單 169 hInstance, //實例 170 NULL))) //不向WM_CREATE傳任何東西 171 { 172 KillGLWindow(); //重置顯示區 173 MessageBox(NULL, "建立窗口失敗。", "錯誤", MB_OK | MB_ICONEXCLAMATION); 174 return FALSE; 175 } //返回FALSE 176 static PIXELFORMATDESCRIPTOR pfd = //pfd 告訴窗口使用的像素格式 177 { 178 sizeof(PIXELFORMATDESCRIPTOR), //上述格式描述符的大小 179 1, //版本號 180 PFD_DRAW_TO_WINDOW | //格式支持窗口 181 PFD_SUPPORT_OPENGL | //格式必須支持OpenGL 182 PFD_DOUBLEBUFFER, //必須支持雙緩衝 183 PFD_TYPE_RGBA, //申請RGBA 格式 184 bits, //選定色彩深度 185 0, 0, 0, 0, 0, 0, //忽略的色彩位 186 0, //無Alpha緩存 187 0, //忽略Shift Bit 188 0, //無累加緩存 189 0, 0, 0, 0, //忽略彙集位 190 16, //16位Z-緩存(深度緩存) 191 0, //無模板緩存 192 0, //無輔助緩存 193 PFD_MAIN_PLANE, //主繪圖層 194 0, //Reserved 195 0, 0, 0 //忽略層遮罩 196 }; 197 if (!(hDC = GetDC(hWnd))) //獲取設備描述表? 198 { 199 KillGLWindow(); //重置顯示區 200 MessageBox(NULL, "不能建立GL設備描 述表。", "錯誤", MB_OK | MB_ICONEXCLAMATION); 201 return FALSE; 202 } //返回FALSE 203 if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) //Windows找到相應像素格式了嗎? 204 { 205 KillGLWindow(); //重置顯示區 206 MessageBox(NULL, "不能建立一種相匹配 的像素格式。", "錯誤", MB_OK | MB_ICONEXCLAMATION); 207 return FALSE; 208 } //返回FALSE 209 if (!SetPixelFormat(hDC, PixelFormat, &pfd)) //可以設置象素格式麼? 210 { 211 KillGLWindow(); //重置顯示區 212 MessageBox(NULL, "不能設置像素格式。 ", "錯誤", MB_OK | MB_ICONEXCLAMATION); 213 return FALSE; //返回FALSE 214 } 215 if (!(hRC = wglCreateContext(hDC))) //可否取得着色描述表? 216 { 217 KillGLWindow(); //重置顯示區 218 MessageBox(NULL, "不能建立着色描述 表。", "錯誤", MB_OK | MB_ICONEXCLAMATION); 219 return FALSE; 220 } //返回FALSE 221 if (!wglMakeCurrent(hDC, hRC)) //嘗試激活着色描述表 222 { 223 KillGLWindow(); //重置顯示區 224 MessageBox(NULL, "不能激活當前的 OpenGL着色描述表。", "錯誤", MB_OK | MB_ICONEXCLAMATION); 225 return FALSE; 226 } //返回FALSE 227 ShowWindow(hWnd, SW_SHOW);//顯示窗口 228 SetForegroundWindow(hWnd); //稍微提升優先級 229 SetFocus(hWnd); //設置鍵盤的焦點至此窗口 230 ReSizeGLScene(width, height); //設置透視GL 屏幕 231 if (!InitGL()) //初始化新建的GL窗口 232 { 233 KillGLWindow(); //重置顯示區 234 MessageBox(NULL, "初始化失敗。", "錯誤 ", MB_OK | MB_ICONEXCLAMATION); 235 return FALSE; //返回FALSE 236 } 237 return TRUE; //成功 238 } 239 LRESULT CALLBACK WndProc( 240 HWND hWnd, //窗口的句柄 241 UINT uMsg, //窗口的消息 242 WPARAM wParam, //附加的消息內容 243 LPARAM lParam) //附加的消息內容 244 { 245 switch (uMsg) { //檢查Windows消息 246 case WM_ACTIVATE: //監視窗口激活消息 247 { 248 if (!HIWORD(wParam)) //檢查最小化狀態 249 { 250 active = TRUE; 251 } //程序處於激活狀態 252 else 253 { 254 active = FALSE; 255 } //程序再也不激活 256 return 0; //返回消息循環 257 } 258 case WM_SYSCOMMAND: //系統中斷命令 259 { 260 switch (wParam) { //檢查系統調用 261 case SC_SCREENSAVE: //屏保要運行? 262 case SC_MONITORPOWER: //顯示器要進入節電模式? 263 return 0; 264 } //阻止發生 265 break; //退出 266 } 267 case WM_CLOSE: //收到Close消息? 268 { 269 PostQuitMessage(0); //發出退出消息 270 return 0; //返回 271 } 272 case WM_KEYDOWN: //有鍵按下麼? 273 { 274 keys[wParam] = TRUE; //如果設爲TRUE 275 return 0; //返回 276 } 277 case WM_KEYUP: //有鍵放開麼? 278 { 279 keys[wParam] = FALSE;//是則設爲FALSE 280 return 0; //返回 281 } 282 case WM_SIZE: //調整OpenGL窗口大小 283 { 284 ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); 285 //LoWord=Width,HiWord=Height 286 return 0; //返回 287 } 288 } 289 //向DefWindowProc傳遞全部未處理的消息。 290 return DefWindowProc(hWnd, uMsg, wParam, lParam); 291 } 292 int WINAPI WinMain( 293 HINSTANCE hInstance, //當前窗口實例 294 HINSTANCE hPrevInstance, //前一個窗口實例 295 LPSTR lpCmdLine, //命令行參數 296 int nCmdShow) //窗口顯示狀態 297 { 298 MSG msg; //Windowsx消息結構 299 BOOL done = FALSE; //退出循環的Bool變量 300 //提示用戶選擇運行模式 301 if (MessageBox(NULL, "你想在全屏模式下運 行嗎?", "設置全屏模式?", MB_YESNO | MB_ICONQUESTION) == IDNO) 302 { 303 fullscreen = FALSE; //FALSE爲窗口模式 304 } 305 //建立OpenGL窗口 306 if (!CreateGLWindow("OpenGL程序框架", 640, 480, 16, fullscreen)) 307 { 308 return 0; //失敗退出 309 } 310 while (!done) //保持循環直到done=TRUE 311 { 312 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //有消息在等待嗎? 313 { 314 if (msg.message == WM_QUIT) 315 //收到退出消息? 316 { 317 done = TRUE; //是則done=TRUE 318 } 319 else //不是,處理窗口消息 320 { 321 TranslateMessage(&msg);//翻譯消息 322 DispatchMessage(&msg); //發送消息 323 } 324 } 325 else //若是沒有消息 326 { 327 //繪製場景。監視ESC鍵和來自 //的退出消息,而後調用DrawGLScene() 328 if (active) //程序激活的麼? 329 { 330 if (keys[VK_ESCAPE])//ESC按下麼? 331 { 332 done = TRUE; //ESC發退出信號 333 } 334 else //不是退出的時候,刷新屏幕 335 { 336 DrawGLScene(); //繪製場景 337 SwapBuffers(hDC); //交換緩存(雙緩存) 338 } 339 } 340 if (keys[VK_F1]) //F1鍵按下了麼? 341 { 342 keys[VK_F1] = FALSE; //如果,使對應的Key數組中的值爲FALSE 343 KillGLWindow(); //銷燬當前窗口 344 fullscreen = !fullscreen; //切換全屏/窗口模式 345 //重建OpenGL 窗口 346 // if (!CreateGLWindow("OpenGL程 序框架",640,480,16,fullscreen)) 347 // { 348 // return 0; //若是窗口未能建立,程序退出 349 // } 350 // } 351 if (!CreateGLWindow("繪製基本圖元", 640, 480, 16, fullscreen)) 352 { 353 return 0; //若窗口未能建立程序退出 354 } 355 } 356 357 } 358 } 359 //關閉程序 360 KillGLWindow(); //銷燬窗口 361 return (msg.wParam); //退出程序 362 }