a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > Delphi > 正文

Delphi使用OpenGL2d繪圖之畫圖片Bmp的方法

2020-01-31 20:51:42
字體:
供稿:網(wǎng)友

一、前言:

對于Delphi來說,要畫圖片要先處理一下,需要引用別的單元,而Delphi中沒帶,需要另外下載Gl.pas。網(wǎng)上常見自帶的OpenGl單元封裝的是1.0版的,有此函數(shù)未聲明。網(wǎng)上可以找到Gl.pas單元。另外需要一個Glaux.pas單元與glaux.dll,是輔助庫。在本文最后會提供下載。

二、實現(xiàn)流程:

繪畫圖片需要以下幾個流程。Window本身的繪圖是以位圖為基礎(chǔ)的,png,jpg等,繪畫時,可以轉(zhuǎn)為bmp再畫。

1.加載bmp圖片:使用auxDIBImageLoadA或其他函數(shù)

2.轉(zhuǎn)換為紋理:glGenTextures -> glBindTexture -> glTexImage2D, glTexParameteri用于設(shè)置相關(guān)參數(shù)

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

三、利用glDrawPixels函數(shù)繪圖

glDrawPixels共有如下5個參數(shù):

width: 表圖像的寬度
height: 表圖像的高度
format:表圖像的數(shù)據(jù)存儲格式
atype: 未知
pixels: DIB數(shù)據(jù)的指針

示例代碼如下:

procedure TForm1.Draw;var Bmp: TBitmap;begin Bmp := TBitmap.Create; Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp'); // 清空緩沖區(qū) glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // TBitmap的圖像數(shù)據(jù)在內(nèi)存中是按行倒序連續(xù)存放的,通過TBitmap.ScanLine[TBitmap.Height-1]可以取得首地址即圖像緩沖區(qū)地址 // bmp圖片的顏色是按b g r存儲的,所以要選 GL_BGR_EXT做為參數(shù) glDrawPixels(Bmp.Width, Bmp.Height, GL_BGR_EXT, GL_UNSIGNED_BYTE, Bmp.ScanLine[Bmp.Height - 1]); SwapBuffers(FDC); Bmp.Free;end;

用以上方法繪制圖片不需要啟用紋理映射,可以通過glPixelZoom函數(shù)來縮放圖片,顯示位置在窗口的左下角(暫時不知道如何改變圖像位置。)

三、使用紋理繪圖

想要按制圖片的顯示位置與放大縮小,可以用以下方法。

1.按流程,我們先把圖片加載到程序里,獲取相關(guān)的圖片信息。

將圖片加載到紋理中,可參考本站://www.5lwq4hdr.cn/article/52125.htm

在delphi中加載一張位圖是很簡單的,可以通過以下方式加載:

(1)通過輔助庫的auxDIBImageLoadA函數(shù)加載圖片,返回是一個PTAUX_RGBImageRec數(shù)據(jù)指針,DIB數(shù)據(jù)格式為RGB。

 // RGB數(shù)據(jù)的結(jié)構(gòu)體 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數(shù)據(jù)格式為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.創(chuàng)建紋理,其中的glGenTextures與glBindTexture,在Gl.pas中。

 // 創(chuàng)建紋理區(qū)域 glGenTextures(1, @texture); // 綁定紋理區(qū)域 glBindTexture(GL_TEXTURE_2D, texture); // 使用位圖創(chuàng)建圖像紋理 glTexImage2D(  GL_TEXTURE_2D,      // 紋理是一個2D紋理 GL_TEXTURE_2D  0,            // 圖像的詳細程度 默認 0  3,            // 數(shù)據(jù)的成分數(shù)。因為圖像是由紅,綠,藍三種組成 默認3  Bmp.Width,        // 紋理的寬度  Bmp.Height,        // 紋理的高度  0,            // 邊框的值 默認 0  GL_BGR_EXT,        // 數(shù)據(jù)格式 bmp使用 bgr  GL_UNSIGNED_BYTE,     // 組成圖像的數(shù)據(jù)是無符號字節(jié)類型的  Bmp.ScanLine[Bmp.Height - 1] // DIB數(shù)據(jù)指針 ); // 下面兩行是讓opengl在放大原始的紋理大(GL_TEXTURE_MAG_FILTER)或縮小原始紋理(GL_TEXTURE_MIN_FILTER)時OpenGL采用的濾波方式。 // GL_LINEAR 使用線性濾波,可以把圖片處理處平滑,但需要更多的內(nèi)存與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)。開啟后,非紋理的繪制將不起作用。用完記得關(guān)閉就可以了。

 // 以下是繪圖,利用一個四邊形,繪制圖片 // 啟用紋理映射 if glIsEnabled(GL_TEXTURE_2D) = 0 then  glEnable(GL_TEXTURE_2D); // 清空緩沖區(qū) 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 的第一個參數(shù)是X坐標。 // 0.0是紋理的左側(cè)。 0.5是紋理的中點, 1.0是紋理的右側(cè)。 // glTexCoord2f 的第二個參數(shù)是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();

以上的繪制就結(jié)束了,以下是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'); // 創(chuàng)建紋理區(qū)域 glGenTextures(1, @texture); // 綁定紋理區(qū)域 glBindTexture(GL_TEXTURE_2D, texture); // 使用位圖創(chuàng)建圖像紋理 glTexImage2D(  GL_TEXTURE_2D,      // 紋理是一個2D紋理 GL_TEXTURE_2D  0,            // 圖像的詳細程度 默認 0  3,            // 數(shù)據(jù)的成分數(shù)。因為圖像是由紅,綠,藍三種組成 默認3  Bmp.Width,        // 紋理的寬度  Bmp.Height,        // 紋理的高度  0,            // 邊框的值 默認 0  GL_BGR_EXT,        // 數(shù)據(jù)格式 bmp使用 bgr  GL_UNSIGNED_BYTE,     // 組成圖像的數(shù)據(jù)是無符號字節(jié)類型的  Bmp.ScanLine[Bmp.Height - 1] // DIB數(shù)據(jù)指針 ); // 下面兩行是讓opengl在放大原始的紋理大(GL_TEXTURE_MAG_FILTER)或縮小原始紋理(GL_TEXTURE_MIN_FILTER)時OpenGL采用的濾波方式。 // GL_LINEAR 使用線性濾波,可以把圖片處理處平滑,但需要更多的內(nèi)存與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); // 清空緩沖區(qū) 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 的第一個參數(shù)是X坐標。 // 0.0是紋理的左側(cè)。 0.5是紋理的中點, 1.0是紋理的右側(cè)。 // glTexCoord2f 的第二個參數(shù)是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;

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 亚洲午夜在线 | 日本一区视频 | 国产成人精品一区二 | 亚洲网站在线播放 | 日本一区二区三区在线观看 | 国产精品日本一区二区不卡视频 | 中文不卡在线 | 91麻豆精品国产91久久久更新资源速度超快 | 在线视频91| 国产成人午夜 | 一区二区三区四区久久 | 特黄视频 | 国内精品久久久久久久97牛牛 | 日韩成人三级 | 久久国产精品亚洲 | 久久精品亚洲 | 亚洲国产一区视频 | 亚洲综合无码一区二区 | 免费观看一级毛片 | 欧美在线激情 | 久久精品久久久久电影 | 啪啪免费小视频 | 99久久婷婷国产综合精品 | 狠狠躁日日躁夜夜躁东南亚 | 在线免费一级片 | 一区二区三区在线 | 视频在线91 | 九九热在线免费视频 | 中国1级黄色片 | 91成人在线 | 亚洲综合一区二区三区 | 日本一本在线 | 久久成人毛片 | 久久综合九色综合欧美狠狠 | 久草久草久草 | 一区二区三区在线免费观看 | 精品国产一区二区三区免费 | 成人在线不卡 | 日韩一区二区精品 | 国产欧美日韩综合精品 | 久久国内精品 |