• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Delphi > Delphi使用OpenGL2d绘图之画图片Bmp的方法

Delphi使用OpenGL2d绘图之画图片Bmp的方法

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了delphi jpg转bmp,delphi bmp,delphi jpg bmp,delphi 绘图,delphi使用教程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一、前言:

对于Delphi来说,要画图片要先处理一下,需要引用别的单元,而Delphi中没带,需要另外下载Gl.pas。网上常见自带的OpenGl单元封装的是1.0版的,有此函数未声明。网上可以找到Gl.pas单元。另外需要一个Glaux.pas单元与glaux.dll,是辅助库。在本文最后会提供下载。

二、实现流程:

绘画图片需要以下几个流程。Window本身的绘图是以位图为基础的,png,jpg等,绘画时,可以转为bmp再画。

1.加载bmp图片:使用auxDIBImageLoadA或其他函数

2.转换为纹理:glGenTextures -> glBindTexture -> glTexImage2D, glTexParameteri用于设置相关参数

3.绘制纹理:glBindTexture -> glBegin(GL_QUADS) -> glTexCoord2f -> glVertex2f -> glEnd

三、利用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;

</div>

用以上方法绘制图片不需要启用纹理映射,可以通过glPixelZoom函数来缩放图片,显示位置在窗口的左下角(暂时不知道如何改变图像位置。)

三、使用纹理绘图

想要按制图片的显示位置与放大缩小,可以用以下方法。

1.按流程,我们先把图片加载到程序里,获取相关的图片信息。

将图片加载到纹理中,可参考本站:http://www.weikejianghu.com/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;
</div>

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

</div>

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); // 线形滤波

</div>

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

</div>

以上的绘制就结束了,以下是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;

</div>

本实例完整代码可点此下载。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • delphi实现将BMP格式图形转化为JPG格式图形的方法
  • Delphi使用OpenGL2d绘图之画图片Bmp的方法

相关文章

  • 2017-05-28Delphi基本图像处理方法汇总
  • 2017-05-28Delphi实例演示Rect、Bounds生成TRect的区别
  • 2017-05-28插件管理框架 for Delphi(一)
  • 2017-05-28Delphi书籍15本网盘下载地址整理
  • 2018-11-21Delphi CLSIDFromProgID
  • 2017-05-28Delphi中判断文件是否为文本文件的函数
  • 2017-05-28Delphi下OpenGL2d绘图之初始化流程详解
  • 2017-05-28Delphi实现碰撞球体完整实例代码
  • 2017-05-28delphi mysql adbquery数据提供程序或其他服务返回 E_FAIL 状态
  • 2017-05-28Delphi实现Listbox中的item根据内容显示不同颜色的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Delphi实现获取磁盘空间大小的方法
    • Delphi隐藏TPageControl的标签实例介绍
    • delphi发送消息控制滚动条使用示例
    • Delphi实现读取系统时间与日期完整实例
    • delphi建立、读取、存贮INI文件的方法《三》
    • 截取指定符号之间的字符串(随机读取)delphi实例代码
    • delphi制作wav文件的方法
    • 插件管理框架 for Delphi(二)
    • Delphi中设置条件断点的方法讲解
    • Delphi实现毫秒级别的倒计时实例代码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有