講解Delphi下的OpenGL開發入門

OpenGL最初是由Silicon圖形公司開發的底層圖形庫規範。你的系統中准確實現這個規範的部分,通常被稱爲OpenGL驅動,它允許你使用幾何集合(點,線,多邊形,圖像等等)來描述你希望表現的場景。讓肉眼觀察起來較爲舒適的中等規模場景,通常在毫秒級的速度上實現,這意味著該庫文件有足夠的能力來支持你創建一個生機勃勃的虛擬世界。

OpenGL驅動一般以二進制庫文件的形式提供。它能夠動態的連接到你的程序中。在Windows平台上,它將是成爲DLL的形式(在你的系統目錄下檢查opengl.dll)。自從Delphi能夠使用任何DLL開始,它對OpenGL 3D編程的能力就像其他任何語言一樣容易了。本文將幫助你獲得在Delphi中進行OpenGL開發的有效知識。

數學基礎

OpenGL擁有強大的數學基礎,因此對它功能的限制完全取決于你的想象能力(譯者注:沒有做不到,只有想不到)。對于理解那些公理和引理,更好的是讓我們立刻認識一個簡單的3D坐標系統,它是3D編程中慣用的坐標系統。如下:

王朝网络

你應該如何理解你的屏幕(藍色的方塊)在場景中的放置位置呢?發出四條射線並形成屏幕的那個點,是該想象空間中的視點(point of view)。OpenGL讓你調用兩個簡單的函數來定義這個場景

glMatrixMode(GL_PROJECTION);

glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);

在這個調用的過程中的-0.1,0.1,-0.1,0.1定義了這個可視屏幕的左上角和右下角坐標;0.3指定視愕狡聊壞木嗬?就好象「近剪貼板」(near clipping plane))同時25.0指定「遠剪貼板」(far clipping plane)。任何近剪貼板前面的物體以及遠剪貼板後面的物體都將不可見。當然,你能夠任意擺弄這些數字,以使他們適合你需要的場景。

從基本元素(primitive)到對象

現在開始最有意思的部分:對象。OpenGL僅僅支持以下幾種基本幾何圖形:點,線和多邊形。沒有表面或者更高級的圖形(比如球狀圖形)能被作爲基本圖形元素繪制。但是它們能夠用多邊形完美的模仿出來。隨意看看現代3D遊戲,你會發現它們完全由三角形建立。因此,我們不會被此限制所約束。

對象的繪制非常類似Pascal語言編程。每個塊都應該被begin-end包含著,更爲確切的說是glBegin()和glEnd()。如同下面的例子:

const S=1.0; D=5.0;

...

glBegin(GL_TRIANGLES);

glVertex3f( -S, 0, D); glVertex3f(S, 0, D); glVertex3f(0, S, D);

glEnd;

這是個簡單的三角形。它距離你的視點有5個單位,自身高1個單位,寬2個單位。

這是屏幕截圖:

王朝网络

即使它看起來不象3D圖形,但它是我們的初始塊。在下面你可以看到這個例子的源代碼。

在你開始鑽研代碼前,還有些話要說。每次OpenGL編程,都包含一些初始化輸出設備的OS設定(OS-specific)代碼。如果你使用Win32,你將需要設置像素格式以及建立顯示上下文環境脫離windows設備上下文環境。如果windows系統級編程你並不很在行,你可以把如下的代碼作爲模版使用。FormCreate中被調用函數的詳細信息可以參考幫助文檔。

FILE: Tri.pas

unit Tri;

interface

uses

OpenGL, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls, ComCtrls;

type

TForm1 = class(TForm)

procedure FormCreate(Sender: TObject);

procedure FormPaint(Sender: TObject);

private

procedure Draw; //Draws an OpenGL scene on request

public

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure setupPixelFormat(DC:HDC);

const

pfd:TPIXELFORMATDESCRIPTOR = (

nSize:sizeof(TPIXELFORMATDESCRIPTOR); // size

nVersion:1; // version

dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or

PFD_DOUBLEBUFFER; // support double-buffering

iPixelType:PFD_TYPE_RGBA; // color type

cColorBits:24; // preferred color depth

cRedBits:0; cRedShift:0; // color bits (ignored)

cGreenBits:0; cGreenShift:0;

cBlueBits:0; cBlueShift:0;

cAlphaBits:0; cAlphaShift:0; // no alpha buffer

cAccumBits: 0;

cAccumRedBits: 0; // no accumulation buffer,

cAccumGreenBits: 0; // accum bits (ignored)

cAccumBlueBits: 0;

cAccumAlphaBits: 0;

cDepthBits:16; // depth buffer

cStencilBits:0; // no stencil buffer

cAuxBuffers:0; // no auxiliary buffers

iLayerType:PFD_MAIN_PLANE; // main layer

bReserved: 0;

dwLayerMask: 0;

dwVisibleMask: 0;

dwDamageMask: 0; // no layer, visible, damage masks

);

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

// set viewing projection

glMatrixMode(GL_PROJECTION);

glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);

// position viewer

glMatrixMode(GL_MODELVIEW);

glEnable(GL_DEPTH_TEST);

end;

procedure TForm1.FormCreate(Sender: TObject);

var DC:HDC;

RC:HGLRC;

i:integer;

begin

DC:=GetDC(Handle); //Actually, you can use any windowed control here

SetupPixelFormat(DC);

RC:=wglCreateContext(DC); //makes OpenGL window out of DC

wglMakeCurrent(DC, RC); //makes OpenGL window active

GLInit; //initialize OpenGL

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;

procedure TForm1.FormPaint(Sender: TObject);

begin

Draw;

end;

end.

FILE: Tri.dfm

object Form1: TForm1

BorderStyle = bsDialog

Caption = \'BASIC OpenGL Program\'

ClientHeight = 318

ClientWidth = 373

OnCreate = FormCreate

OnPaint = FormPaint

end

3D曆險

好了,讓我們開始真正的3D吧。將先前的代碼作爲框架,我們增加一些畫線的代碼建立一個帶陰影面的四面體。應該如何用基本圖形元素來構建呢?我們使用四個三角形。一個在底部,另外三個作爲側面。這裏就是生成他們的代碼:

procedure TForm1.Draw;

const D=1.5;

H1=D/1.732;

H2=D*1.732-H1; // D/H = tg(30) = 1/sqrt(3)

HY=3.0;

const //vertexes

a1:TGLArrayf3=(-D, 0, -H1); //bootom left

a2:TGLArrayf3=( D, 0, -H1); //bootom right

a3:TGLArrayf3=( 0, 0, H2); //bootom back

a4:TGLArrayf3=( 0, HY, 0); //top

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);

glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4);

glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4);

glEnd;

SwapBuffers(wglGetCurrentDC);

end;

雖然看起來有點複雜,不過當你面對下面這張圖時,它就很容易理解了。

王朝网络

我們定義頂點a1 ? a4同時依據4個頂點位置建立指定的三角形。當你定義自己的三角形(或者其他的多邊形),請使用如下的規則:始終按照逆時針順序排列定點序號,就像你正在外部觀看側面一樣。通過這個規則,我們可以指定指定a1-a2-a4,a1-a3-a2(仰視),a2-a3-a4和a3-a1-a4。

現在就替換Tri.pas中TForm1.Darw()部分,程序運行的效果不會體現出過多的變化。它看起來仍然不象三維圖形。這是因爲我們還沒有設定任何光源。

LIGHTS! CAMERA! OPENGL!

在OpenGL中光源模式有兩部分:光源自身(顔色,強度等等)和對象材質。材質,依次包括顔色,一些物理參數(比如不透明性光澤性)以及紋理。深入其中,這會是一個巨大的世界,我們將一步步地接近。

定義一個光源相當容易。

procedure GLInit;

const

light0_positi

 
Delphi下的OpenGL開發
Delphi下的OpenGL開發
OpenGL最初是由Silicon图形公司开发的底层图形库规范。你的系统...查看完整版>>Delphi下的OpenGL開發
 
VC.NET開發OpenGL應用入門
OpenGL被嚴格定義爲“一種到圖形硬件的軟件接口”。從本質上說,它是一個完全可移植並且速度很快的3D圖形和建模庫。使用OpenGL,你可以創建視覺質量接近射線跟蹤程序的精致漂亮的3D圖形。使用OpenGL的最大好處是它比...查看完整版>>VC.NET開發OpenGL應用入門
 
Delphi 7程序設計入門-編程之道/點十成金|報價¥9.50|教育音像與電子出版物,軟件與計算機,程序設計/編程開發,Delphi,
目錄:教育音像與電子出版物,軟件與計算機,程序設計/編程開發,Delphi,品牌:産品參數·操作系統:Windows·格式:CD-ROM·條碼:9787900669377·可參與人數:1産品描述詳細內容: 1CD-ROM!Delphi是美國Borland公司推...查看完整版>>Delphi 7程序設計入門-編程之道/點十成金|報價¥9.50|教育音像與電子出版物,軟件與計算機,程序設計/編程開發,Delphi,
 
用Delphi進行OpenGL編程學習心得
---- 在開發圖形程序時,尤其是三維的圖形程序,因爲感覺OpenGL沒有DirectX那麽龐雜,所以選擇了DelphiOpenGL,憑感覺而言,Delphi也沒有C++那麽繁雜而且更加人性化,于是選擇Delphi+OpenGL進行工作。在這過程中,碰...查看完整版>>用Delphi進行OpenGL編程學習心得
 
用Delphi做一個OpenGL控件
OpenGL是一個獨立于窗口的圖形庫,而圖形最終是在窗口系統裏繪制出來的,那麽OpenGL的繪圖命令是怎麽在窗口裏生成輸出的呢?   這就是各個系統上的OpenGL實現者需要做的工作了。在Windows裏是通過wgl庫完成的,在X...查看完整版>>用Delphi做一個OpenGL控件