在Delphi中使用OpenGL類庫實現燃燒、跳動的火焰效果,很不錯吧,在本例中,介紹OpenGL 動畫的實現方法。運行的實例圖如下:
設計思路如下:
本例先定義OpenGL 動畫場景,然後在自定義的消息函數中用渲染模式繪制圖像動畫,並利用時間回調函數實現計時。關閉窗體時,需要終止計時、釋放設置的OpenGL 場景和釋放圖像占用的內存。
1.新建工程文件:
(1)啟動Delphi 6.0 程序。選擇“文件”菜單下的“新建”命令,從彈出的子菜單中選擇Application 選項,則出現新建工程的Form1 窗口。
(2)選擇“文件”菜單下的“工程另存為”命令,彈出Save Unit1 As 對話框。在“保存在”列表框中選擇需要存放該窗口文件所在的目錄名;在“文件名”編輯框中填寫文件名,這裡填寫“Main”,點擊“保存”按鈕,保存上面的選項。
(3)執行上一步後,將彈出“工程另存為”對話框。在“保存在”列表框中選擇需要存放該工程的目錄名,最好和第(2)步選取相同的目錄;在“文件名”編輯框中填寫保存處理該工程的源代碼的文件名,這裡填寫“Project1”,點擊“保存”按鈕,保存上面的選項。
2.修改窗口
激活Main 窗口,在“屬性”面板中設置該窗體的Caption 屬性為“跳動的火焰”,Color 屬性設置為“clBtnFace”。
代碼分析如下:
(1)在“屬性”窗口的“事件”頁中,為MainForm 窗口添加OnCreate 消息,用於初始化設置OpenGL 場景:
procedure TMainForm.FormCreate(Sender: TObject);//初始化設置OpenGL場景 var I:integer; begin initopengl; DC:= GetDC(Handle); SetDCPixelFormat; hrc:= wglCreateConText(DC); wglMakeCurrent(DC, hrc); glEnable(GL_DEPTH_TEST); glenable(GL_Texture_2d); glenable(gl_blend); glblendfunc(GL_ONE,GL_ONE); glMatrixMode(GL_PROJECTION); QO:= gluNewQuadric; gluQuadricTexture(QO, GL_TRUE); uTimerID:= timeSetEvent (10, 0, @FNTimeCallBack, 0, TIME_PERIODIC); FDPI:= GetDeviceCaps(Canvas.Handle, LOGPIXELSX); for i:=1 to 8 do Tex[i]:=CreateTexture(inttostr(i)+’.jpg’); end;
(2)在Object Inspector 窗口的Events 頁中,為MainForm 窗口添加OnReSize 消息,用於設置窗口隨窗口尺寸變化的位置:
procedure TMainForm.ApplyPerspective(Viewport: TRectangle; Width, Height: Integer; DPI: Cardinal);//設置窗口隨窗口尺寸變化的位置 begin MaxDimI:= Width; if Height > MaxDimI then MaxDimI:= Height; RatioI:= (2 * Viewport.Width + 2 * Viewport.Left - Width) / Width; RightI:= RatioI * Width / (2 * MaxDimI); RatioI:= (Width - 2 * Viewport.Left) / Width; LeftI:= -RatioI * Width / (2 * MaxDimI); RatioI:= (2 * Viewport.Height + 2 * Viewport.Top - Height) / Height; TopI:= RatioI * Height / (2 * MaxDimI); RatioI:= (Height - 2 * Viewport.Top) / Height; BottomI:= -RatioI * Height / (2 * MaxDimI); FNearPlane:= 72 * 2 * DPI / (25.4 * MaxDimI); zFarI:= FNearPlane + 72; glFrustum(LeftI, RightI, BottomI, TopI, FNearPlane, zFarI); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45,Width/Height, 0.1, 20000); glMatrixMode(GL_MODELVIEW); InvalidateRect(Handle, nil, False); end; procedure TMainForm.FormReSize(Sender: TObject);//設置窗口隨窗口尺寸變化的位置 begin glViewport(0, 0, ClientWidth, ClientHeight); with FViewport do begin Left:= 0; Top := 0; Width:= ClientWidth; Height:= ClientHeight; end; glMatrixMode(GL_PROJECTION); glLoadIdentity; ApplyPerspective(FViewport, ClientWidth, ClIEntHeight, FDPI); end;
(3)在Object Inspector 窗口的Events 頁中,為MainForm 窗口添加OnPaint 消息,用於獲取窗口的分辨率以及應用投影方式。
procedure TMainForm.FormPaint(Sender: TObject); //獲取窗口的分辨率以及應用投影方式 begin FDPI := GetDeviceCaps(Canvas.Handle, LOGPIXELSX); glMatrixMode(GL_PROJECTION); glLoadIdentity; ApplyPerspective(FViewport, ClientWidth, ClIEntHeight, FDPI); end;
(4)在Object Inspector 窗口的Events 頁中,為MainForm 窗口添加OnDestroy 消息,用於終止計時、釋放設置的OpenGL 場景和釋放圖像占用的內存。
procedure TMainForm.FormDestroy(Sender: TObject); //終止計時、釋放設置的OpenGL 場景和釋放圖像占用的內存 begin timeKillEvent(uTimerID); wglMakeCurrent(0, 0); wglDeleteConText(hrc); ReleaseDC(Handle, DC); gluDeleteQuadric (qO); end;
基本上就是這樣了,自己試著動手完善下吧,記著要引入OpenGL庫哦。