科學計算視覺化、電腦動畫、虛擬實體是電腦圖形學三大熱點,核心皆為三維真實感繪圖。OpenGL (Open Graphics Library) 憑藉跨平台、簡便、高效、功能完善,已成為三維圖形事實上的工業標準。自 Windows NT 3.51 支援 OpenGL 起,Windows 95 OSR2、NT 4.0 連續提供開發環境。Visual C++ 4.2+ 完整支援 OpenGL API,使三維開發普及化。
PIXELFORMATDESCRIPTOR 結構決定物理裝置屬性(如 PFD_DOUBLEBUFFER 決定是否支援雙緩衝動畫)。先用 ChoosePixelFormat 選擇 DC 支援的最接近格式,再用 SetPixelFormat 設定。wglCreateContext 建立 RC,wglMakeCurrent 使 RC 與 DC 關聯成為當前。wglMakeCurrent(NULL, NULL) 斷開關聯,判斷 RC 控制代碼有效性後 wglDeleteContext 刪除 RC,再 ReleaseDC 或 DeleteDC 處理 DC。附贈程式以 MFC 完成簡單 OpenGL 繪圖(輔助庫繪製帶光源實心球),以下為 MFC 開發 OpenGL 必須注意的要點:
WS_CLIPCHILDREN | WS_CLIPSIBLINGS一旦設定 DC 像素格式,其關聯視窗格式隨之固定。若視窗含子視窗或同級視窗,其像素格式未設定為與 RC 一致,OpenGL 繪圖易出錯。主框架視窗構造函數中指定:
LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, NULL, NULL);
auxReshapeFunc 定義視口大小回呼 → MFC 用 WM_SIZE 處理函數。auxMainLoop 定義繪圖回呼 → MFC 用 WM_PAINT 處理函數。WM_KEYDOWN、WM_MOUSEMOVE 等 Windows 訊息。OpenGL 有 glClear 清除背景,應禁止 Windows 自動擦除背景。否則背景色非白色時,重繪會產生一幀白色閃爍(動畫時明顯)。WM_ERASEBKGND 處理函數中直接 return TRUE 即可。
OpenGL 跨平台需使用系統調色板。GL_INDEX_MODE 繪圖時必須自行定義調色板,但 GL_RGBA_MODE 較方便,鮮少用索引模式。
CS_OWNDCOpenGL 佔用 DC 時間長,設定 CS_OWNDC 避免頻繁 Get/Release DC。MFC 預設未設此屬性,需在 PreCreateWindow 自行註冊視窗類別:
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS | CS_NOCLOSE | CS_OWNDC, ...);
CS_HREDRAW/CS_VREDRAW:視窗縮放產生 WM_PAINT,修正視口與繪圖尺寸。CS_SAVEBITS:視窗被遮蓋後顯現時用記憶體圖像填充,不產生 WM_PAINT,以空間換時間。OpenGL 出錯回傳錯誤碼、不拋出異常,錯誤後續函數通常仍回傳錯誤碼,易被忽略。對每個函數檢查錯誤較繁瑣,編寫時需格外小心。
程式運行需 OpenGL32.dll、glu.dll、glaux.dll 置於 Windows System 目錄。VC 專案需加入 OpenGL.h、glu.h、glaux.h 及 OpenGL.lib、glu.lib、glaux.lib (VC 自帶)。
主視窗類別定義 (OpenGLWnd.h)、實作 (OpenGLWnd.cpp)、應用程式類別 (SimpleGLApp.h/.cpp) 完整原始碼請參考原文附件,核心包含:
PreCreateWindow 註冊 CS_OWNDC 視窗類別OnCreate 建立 DC、設定像素格式、建立 RC、初始化 OpenGL 狀態OnSize 更新 glViewport 與投影矩陣OnDestroy 正確清理 RC/DCOnEraseBkgnd 回傳 TRUE 禁止背景擦除OnPaint 執行 OpenGL 繪圖 (含光源、深度測試、auxSolidSphere)