OpenGL 是跨平台高效能 3D 圖形 API,在 C++Builder 中整合需處理 DC/RC 建立、像素格式協商、雙緩衝、反鋸齒、視口追蹤等繁瑣細節。本文提煉一套可直接落地的標準化框架,涵蓋 FormCreate 初始化、FormDestroy 清理、FormPaint 繪圖迴圈、RenderScene 業務分離、FormResize 視口自適應,適合波形顯示、譜圖、3D 統計圖表等工程視覺化場景。
| 術語 | 說明 |
|---|---|
| DC (Device Context) | GDI 繪圖裝置描述表,GetDC(hwnd) 取得 |
| RC (Rendering Context) | OpenGL 狀態機容器,wglCreateContext 建立,wglMakeCurrent 綁定 |
| Pixel Format | 描述色彩深度、Z-buffer、Stencil、雙緩衝等屬性的 PIXELFORMATDESCRIPTOR |
| Double Buffer | 前/後緩衝區交換 (SwapBuffers),消除閃爍、撕裂 |
| Anti-Aliasing | GL_LINE_SMOOTH + GL_BLEND 實現邊緣平滑 |
class TMainForm : public TForm {
__published:
// 元件...
private:
HGLRC hRC; // OpenGL Rendering Context
HDC hDC; // Device Context
void RenderScene(); // 業務繪圖函數
protected:
virtual void __fastcall FormCreate(TObject*);
virtual void __fastcall FormDestroy(TObject*);
virtual void __fastcall FormPaint(TObject*);
virtual void __fastcall FormResize(TObject*);
};
#include
#include
void __fastcall TMainForm::FormCreate(TObject*) {
// 1. 取得 DC
hDC = GetDC(Handle); // 或 Panel1->Handle
// 2. 定義像素格式
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, 24, // 24-bit 色彩
0,0,0,0,0,0, 0,0,0,0,0,0,0,
32, // 32-bit 深度緩衝
0, 0,
PFD_MAIN_PLANE, 0, 0, 0
};
// 3. 選擇並設定像素格式
int pf = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pf, &pfd);
// 4. 建立 RC 並設為當前
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
// 5. 全域 OpenGL 狀態初始化
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 黑背景
glEnable(GL_DEPTH_TEST); // 深度測試
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void __fastcall TMainForm::FormDestroy(TObject*) {
wglMakeCurrent(NULL, NULL); // 解除綁定
if (hRC) { wglDeleteContext(hRC); hRC = 0; }
if (hDC) { ReleaseDC(Handle, hDC); hDC = 0; }
}
void __fastcall TMainForm::FormPaint(TObject*) {
// 1. 確保 DC/RC 當前(多視窗時必要)
wglMakeCurrent(hDC, hRC);
// 2. 清除緩衝區
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 3. 可選:啟用反鋸齒
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
// 4. 呼叫業務繪圖
RenderScene();
// 5. 關閉反鋸齒(避免影響後續 GDI 繪圖)
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
// 6. 強制刷新並交換緩衝
glFlush();
SwapBuffers(hDC);
}
void TMainForm::RenderScene() {
// 在此撰寫純 OpenGL 呼叫:glBegin/glEnd、VBO、Shader、gluSphere 等
// 範例:繪製簡單三角形
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glBegin(GL_TRIANGLES);
glColor3f(1,0,0); glVertex3f(0, 1, 0);
glColor3f(0,1,0); glVertex3f(-1,-1, 0);
glColor3f(0,0,1); glVertex3f(1,-1, 0);
glEnd();
}
void __fastcall TMainForm::FormResize(TObject*) {
if (!hRC) return;
wglMakeCurrent(hDC, hRC);
glViewport(0, 0, ClientWidth, ClientHeight); // 佔滿客戶區
// 透視投影矩陣重算(視需求)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)ClientWidth/ClientHeight, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
}
hDC/hRC,FormPaint 前 wglMakeCurrent 切換glViewport 使用邏輯像素,配合 SetProcessDpiAwarenessContextwglCreateContext 改用 wglCreateContextAttribsARB,載入 GLEW/GLAD 管理擴充函數glFinish + QueryPerformanceCounter 測量 GPU 時間GLenum err = glGetError() 封裝為宏 GL_CHECK()將 OpenGL 初始化、清理、繪圖迴圈、視口管理封裝為表單生命週期的標準覆寫,業務邏輯集中於 RenderScene,即可獲得結構清晰、易維護、高效能的視覺化開發基礎。框架碼量極小,卻涵蓋雙緩衝、深度測試、反鋸齒、視口自適應等工程必備要素,可直接作為專案模板複用。