首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 開發 OpenGL 3D 圖形程式設計入門指南

     編輯:Delphi

OpenGL 核心架構與 Delphi 整合

OpenGL 最初由 Silicon Graphics 公司開發,是一套跨平台的底層圖形庫規範。作為業界標準的 3D 圖形 API,它透過幾何圖元(點、線、多邊形、圖像等)描述場景,並利用硬體加速在毫秒級渲染中等規模場景,足以支撐生動逼真的虛擬世界構建。在 Windows 平台上,OpenGL 以動態連結庫形式提供,Delphi 完美支援 DLL 呼叫,使 3D 程式開發如同其他語言般直觀便捷。

3D 座標系統與投影設定

OpenGL 擁有強大的數學基礎,功能限制僅取決於想像力。理解 3D 程式設計的第一步是掌握右手座標系統:X 軸向右、Y 軸向上、Z 軸指向觀察者。螢幕在場景中位於近剪裁平面,視點發出四條射線形成可視錐體。透過 glMatrixMode(GL_PROJECTION) 切換至投影矩陣模式,再呼叫 glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0) 定義透視投影:前四個參數設定近平面左、右、下、上邊界;0.3 為視點到近平面距離;25.0 為遠剪裁平面距離。超出此範圍的物體將不被渲染,開發者可根據場景需求自由調整參數。

3D座標系統示意圖

從基本圖元到複雜物件建模

OpenGL 僅支援點、線、多邊形三種基本圖元,但透過三角形組合可模擬任意複雜曲面——現代 3D 遊戲即完全由三角形構建。繪圖流程類似 Pascal 的 begin...end 區塊,以 glBegin() 和 glEnd() 包裹頂點資料。例如繪製一個距離視點 5 單位、高 1、寬 2 的三角形:

const S = 1.0; D = 5.0;
glBegin(GL_TRIANGLES);
glVertex3f(-S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D);
glEnd;
簡單三角形渲染結果

Win32 環境初始化與渲染迴路

每個 OpenGL 程式都需進行作業系統層級的初始化:設定像素格式、建立渲染內容並關聯裝置內容。以下程式碼展示完整的 Delphi 視窗應用程式框架,包含像素格式描述符設定、OpenGL 狀態初始化(深度測試、投影矩陣)、WM_PAINT 訊息處理與雙緩衝交換:

procedure setupPixelFormat(DC: HDC);
const pfd: TPIXELFORMATDESCRIPTOR = (
  nSize: SizeOf(TPIXELFORMATDESCRIPTOR); nVersion: 1;
  dwFlags: PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or PFD_DOUBLEBUFFER;
  iPixelType: PFD_TYPE_RGBA; cColorBits: 24; cDepthBits: 16;
  iLayerType: PFD_MAIN_PLANE; bReserved: 0; ...);
var pixelFormat: Integer;
begin
  pixelFormat := ChoosePixelFormat(DC, @pfd);
  if pixelFormat = 0 then Exit;
  if SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE then Exit;
end;

procedure GLInit;
begin
  glMatrixMode(GL_PROJECTION);
  glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
  glMatrixMode(GL_MODELVIEW);
  glEnable(GL_DEPTH_TEST);
end;

procedure TForm1.FormCreate(Sender: TObject);
var DC: HDC; RC: HGLRC;
begin
  DC := GetDC(Handle);
  setupPixelFormat(DC);
  RC := wglCreateContext(DC);
  wglMakeCurrent(DC, RC);
  GLInit;
end;

procedure TForm1.Draw;
const S = 1.0; D = 5.0;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity;
  glTranslatef(0.0, 0.0, -12.0);
  glBegin(GL_TRIANGLES);
  glVertex3f(-S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D);
  glEnd;
  SwapBuffers(wglGetCurrentDC);
end;

進階 3D 建模:四面體構建與法向量計算

利用四個三角形組成四面體:一個底面、三個側面。頂點定義需遵循逆時針順序(從外部觀察),確保法向量指向外側。程式碼示範如何計算頂點座標並組合三角形:

procedure TForm1.Draw;
const D = 1.5; H1 = D / 1.732; H2 = D * 1.732 - H1; HY = 3.0;
const a1: TGLArrayf3 = (-D, 0, -H1); a2: TGLArrayf3 = (D, 0, -H1);
      a3: TGLArrayf3 = (0, 0, H2);   a4: TGLArrayf3 = (0, HY, 0);
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity; glTranslatef(0.0, 0.0, -12.0);
  glBegin(GL_TRIANGLES);
  glVertex3fv(@a1); glVertex3fv(@a3); glVertex3fv(@a2); // 底面
  glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a4); // 側面1
  glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4); // 側面2
  glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4); // 側面3
  glEnd;
  SwapBuffers(wglGetCurrentDC);
end;
四面體線框結構示意圖

光照系統與材質渲染

OpenGL 光照包含光源屬性(位置、顏色、強度)與材質屬性(顏色、光澤、透明度、貼圖)。啟用光照需三步驟:glEnable(GL_LIGHTING)、設定光源參數(glLightfv)、啟用特定光源(glEnable(GL_LIGHT0))。環境光確保陰影面仍可見。關鍵在於為每個多邊形指定法向量,供光照計算使用。以下函數根據三個頂點(逆時針序)計算法向量(叉積):

function getNormal(p1, p2, p3: TGLArrayf3): TGLArrayf3;
var a, b: TGLArrayf3;
begin
  a[0] := p2[0] - p1[0]; a[1] := p2[1] - p1[1]; a[2] := p2[2] - p1[2];
  b[0] := p3[0] - p1[0]; b[1] := p3[1] - p1[1]; b[2] := p3[2] - p1[2];
  Result[0] := a[1]*b[2] - a[2]*b[1];
  Result[1] := a[2]*b[0] - a[0]*b[2];
  Result[2] := a[0]*b[1] - a[1]*b[0];
end;

繪製時為每個三角形設定法向量,並啟用法向量正規化、平面著色與背面剔除:

procedure TForm1.Draw;
const D = 1.5; H1 = D/1.732; H2 = D*1.732-H1; HY = 3.0;
const a1: TGLArrayf3 = (-D, 0, -H1); a2: TGLArrayf3 = (D, 0, -H1);
      a3: TGLArrayf3 = (0, 0, H2);   a4: TGLArrayf3 = (0, HY, 0);
var n1, n2, n3, n4: TGLArrayf3;
begin
  n1 := getNormal(a1, a3, a2); n2 := getNormal(a1, a2, a4);
  n3 := getNormal(a2, a3, a4); n4 := getNormal(a3, a1, a4);
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glEnable(GL_NORMALIZE); glShadeModel(GL_FLAT); glCullFace(GL_BACK);
  glLoadIdentity; glTranslatef(0.0, 0.0, -12.0);
  glBegin(GL_TRIANGLES);
  glNormal3fv(@n1); glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a3);
  glNormal3fv(@n2); glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a4);
  glNormal3fv(@n3); glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4);
  glNormal3fv(@n4); glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4);
  glEnd;
  SwapBuffers(wglGetCurrentDC);
end;
帶光照陰影的四面體渲染效果

動畫與互動:讓場景動起來

在視窗放置 Timer 元件,每次觸發增加旋轉角度並重繪。在 glBegin 前插入 glRotatef(angle, 0.0, 1.0, 0.0) 即可實現 Y 軸自轉,瞬間賦予靜態模型生命力:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  angle := angle + 1.0;
  Draw;
end;

至此,從環境建置、基本圖元、複雜建模、光照渲染到動畫互動,完整展示了 Delphi 下 OpenGL 3D 開發的核心流程與關鍵技術點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved