程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> Delphi應用OpenGL2d畫圖之繪圖片Bmp的辦法

Delphi應用OpenGL2d畫圖之繪圖片Bmp的辦法

編輯:更多關於編程

Delphi應用OpenGL2d畫圖之繪圖片Bmp的辦法。本站提示廣大學習愛好者:(Delphi應用OpenGL2d畫圖之繪圖片Bmp的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是Delphi應用OpenGL2d畫圖之繪圖片Bmp的辦法正文


1、媒介:

關於Delphi來講,要繪圖片要先處置一下,須要援用其余單位,而Delphi中沒帶,須要別的下載Gl.pas。網上罕見自帶的OpenGl單位封裝的是1.0版的,有此函數未聲明。網上可以找到Gl.pas單位。別的須要一個Glaux.pas單位與glaux.dll,是幫助庫。在本文最初會供給下載。

2、完成流程:

繪繪圖片須要以下幾個流程。Window自己的畫圖是以位圖為基本的,png,jpg等,繪畫時,可以轉為bmp再畫。

1.加載bmp圖片:應用auxDIBImageLoadA或其他函數

2.轉換為紋理:glGenTextures -> glBindTexture -> glTexImage2D, glTexParameteri用於設置相干參數

3.繪制紋理:glBindTexture -> glBegin(GL_QUADS) -> glTexCoord2f -> glVertex2f -> glEnd

3、應用glDrawPixels函數畫圖

glDrawPixels共有以下5個參數:

width: 表圖象的寬度
height: 表圖象的高度
format:表圖象的數據存儲格局
atype: 未知
pixels: DIB數據的指針

示例代碼以下:

procedure TForm1.Draw;
var
 Bmp: TBitmap;
begin
 Bmp := TBitmap.Create;
 Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp');
 // 清空緩沖區
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 // TBitmap的圖象數據在內存中是按行倒序持續寄存的,經由過程TBitmap.ScanLine[TBitmap.Height-1]可以獲得首地址即圖象緩沖區地址
 // bmp圖片的色彩是按b g r存儲的,所以要選 GL_BGR_EXT做為參數
 glDrawPixels(Bmp.Width, Bmp.Height, GL_BGR_EXT, GL_UNSIGNED_BYTE, Bmp.ScanLine[Bmp.Height - 1]);
 SwapBuffers(FDC);
 Bmp.Free;
end;

用以上辦法繪制圖片不須要啟用紋理映照,可以經由過程glPixelZoom函數來縮放圖片,顯示地位在窗口的左下角(臨時不曉得若何轉變圖象地位。)

3、應用紋理畫圖

想要按制圖片的顯示地位與縮小減少,可以用以下辦法。

1.按流程,我們先把圖片加載到法式裡,獲得相干的圖片信息

將圖片加載到紋理中,可參考本站:http://www.jb51.net/article/52125.htm

在delphi中加載一張位圖是很簡略的,可以經由過程以下方法加載:

(1)經由過程幫助庫的auxDIBImageLoadA函數加載圖片,前往是一個PTAUX_RGBImageRec數據指針,DIB數據格局為RGB。

 // RGB數據的構造體
 TAUX_RGBImageRec = record
  sizeX, sizeY: GLint;
  data: pointer;
 end;
 PTAUX_RGBImageRec = ^TAUX_RGBImageRec;
var
 p: PTAUX_RGBImageRec;
begin
 p := auxDIBImageLoadA(PAnsiChar(ExtractFilePath(ParamStr(0)) + '1.bmp'));
 // p 怎樣釋放? Dispose與Freemem都沒法操作這個指針
end;

(2)經由過程TBitmap.LoadFromFile加載圖片。Delphi自帶,從效力上比較,與auxDIBImageLoadA機能是一樣的,但DIB數據格局為BGR,DIB指針為TBitmap.ScanLine[Bmp.Height - 1]

var
 Bmp: TBitmap;
begin
 Bmp := TBitmap.Create;
 TBitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp');
 // do something
 // 用完釋放
 Bmp.Free;
end;

2.創立紋理,個中的glGenTextures與glBindTexture,在Gl.pas中。

 // 創立紋理區域
 glGenTextures(1, @texture);
 // 綁定紋理區域
 glBindTexture(GL_TEXTURE_2D, texture);
 // 應用位圖創立圖象紋理
 glTexImage2D(
  GL_TEXTURE_2D,      // 紋理是一個2D紋理 GL_TEXTURE_2D
  0,            // 圖象的具體水平 默許 0
  3,            // 數據的成份數。由於圖象是由紅,綠,藍三種構成 默許3
  Bmp.Width,        // 紋理的寬度
  Bmp.Height,        // 紋理的高度
  0,            // 邊框的值 默許 0
  GL_BGR_EXT,        // 數據格局 bmp應用 bgr
  GL_UNSIGNED_BYTE,     // 構成圖象的數據是無符號字節類型的
  Bmp.ScanLine[Bmp.Height - 1] // DIB數據指針
 );
 // 上面兩行是讓opengl在縮小原始的紋理年夜(GL_TEXTURE_MAG_FILTER)或減少原始紋理(GL_TEXTURE_MIN_FILTER)時OpenGL采取的濾波方法。
 // GL_LINEAR 應用線性濾波,可以把圖片處置處膩滑,但須要更多的內存與CPU
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 線形濾波
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 線形濾波

3.繪制紋理

繪制紋理之前,必需告訴OpenGL開啟紋理映照glEnable(GL_TEXTURE_2D)。開啟後,非紋理的繪制將不起感化。用完記得封閉便可以了。

 // 以下是畫圖,應用一個四邊形,繪制圖片
 // 啟用紋理映照
 if glIsEnabled(GL_TEXTURE_2D) = 0 then
  glEnable(GL_TEXTURE_2D);
 // 清空緩沖區
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); 
 l := 10;
 t := 10;
 w := 200; // 縮小為200*200的圖片
 // 選擇紋理 假如場景中應用多個紋理,不克不及在glBegin() 和 glEnd() 之間綁定紋理
 glBindTexture(GL_TEXTURE_2D, texture);
 glBegin(GL_QUADS);
 // glTexCoord2f 的第一個參數是X坐標。
 // 0.0是紋理的左邊。 0.5是紋理的中點, 1.0是紋理的右邊。
 // glTexCoord2f 的第二個參數是Y坐標。
 // 0.0是紋理的底部。 0.5是紋理的中點, 1.0是紋理的頂部。
 glTexCoord2f(0, 1);
 glVertex2f(l, t);
 glTexCoord2f(1, 1);
 glVertex2f(l + w, t);
 glTexCoord2f(1, 0);
 glVertex2f(l + w, t + w);
 glTexCoord2f(0, 0);
 glVertex2f(l, t + w);
 glEnd();

以上的繪制就停止了,以下是Draw中完全的代碼,可以不援用幫助庫Glaux.pas

procedure TForm1.Draw;
var
 Bmp: TBitmap;
 texture: GLuint;
 l, t, w: Integer;
begin
 Bmp := TBitmap.Create;
 Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp');
 // 創立紋理區域
 glGenTextures(1, @texture);
 // 綁定紋理區域
 glBindTexture(GL_TEXTURE_2D, texture);
 // 應用位圖創立圖象紋理
 glTexImage2D(
  GL_TEXTURE_2D,      // 紋理是一個2D紋理 GL_TEXTURE_2D
  0,            // 圖象的具體水平 默許 0
  3,            // 數據的成份數。由於圖象是由紅,綠,藍三種構成 默許3
  Bmp.Width,        // 紋理的寬度
  Bmp.Height,        // 紋理的高度
  0,            // 邊框的值 默許 0
  GL_BGR_EXT,        // 數據格局 bmp應用 bgr
  GL_UNSIGNED_BYTE,     // 構成圖象的數據是無符號字節類型的
  Bmp.ScanLine[Bmp.Height - 1] // DIB數據指針
 );
 // 上面兩行是讓opengl在縮小原始的紋理年夜(GL_TEXTURE_MAG_FILTER)或減少原始紋理(GL_TEXTURE_MIN_FILTER)時OpenGL采取的濾波方法。
 // GL_LINEAR 應用線性濾波,可以把圖片處置處膩滑,但須要更多的內存與CPU
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 線形濾波
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 線形濾波
 // 以下是畫圖,應用一個四邊形,繪制圖片
 // 啟用紋理映照
 if glIsEnabled(GL_TEXTURE_2D) = 0 then
  glEnable(GL_TEXTURE_2D);
 // 清空緩沖區
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); 
 l := 10;
 t := 10;
 w := 200; // 縮小為200*200的圖片
 // 選擇紋理 假如場景中應用多個紋理,不克不及在glBegin() 和 glEnd() 之間綁定紋理
 glBindTexture(GL_TEXTURE_2D, texture);
 glBegin(GL_QUADS);
 // glTexCoord2f 的第一個參數是X坐標。
 // 0.0是紋理的左邊。 0.5是紋理的中點, 1.0是紋理的右邊。
 // glTexCoord2f 的第二個參數是Y坐標。
 // 0.0是紋理的底部。 0.5是紋理的中點, 1.0是紋理的頂部。
 glTexCoord2f(0, 1);
 glVertex2f(l, t);
 glTexCoord2f(1, 1);
 glVertex2f(l + w, t);
 glTexCoord2f(1, 0);
 glVertex2f(l + w, t + w);
 glTexCoord2f(0, 0);
 glVertex2f(l, t + w);
 glEnd();
 Bmp.Free;
 SwapBuffers(FDC);
end;

本實例完全代碼可點此下載。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved