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;
本實例完全代碼可點此下載。