在嵌入式linux上玩OpenGL

简介: 在嵌入式linux上玩OpenGL

前言


在我的嵌入式linux上板子资源和性能还是有限。想玩下OpenGL,倒不是板子flash或内存太小,而是底层图形接口是基于framebuffer的dev/fb0的,在标准的OpenGL下不支持。网上了解到在嵌入式linux或单片机上,可以跑OpenGL的一个子集,叫做TinyGL。


OpenGL简介


OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。


OpenGL ES 是 OpenGL 的子集,早先定义 OpenGL ES 是 OpenGL 的嵌入式设备版本,用于移动端平台(Android、iOS)。区别在于 OpenGL ES 删减了 OpenGL 一切低效能的操作方式,有高性能的决不留低效能的,即只求效能不求兼容性。(即:OpenGL ES 能实现的,OpenGL 也能实现;OpenGL 部分 API,OpenGL ES 不支持)但由于嵌入式设备要求的是高性能,所以一些其它纯追求高性能的设备也开始用这种 API 方式。


它与OpenCV的区别是,OpenCV是跨平台开源计算机视觉库,图像处理和计算机视觉方面的很多通用算。OpenCV 和 OpenGL 区别在于:OpenCV 是从图像到数据,主要是提供图像处理和视频处理的基础算法库,还涉及一些机器学习的算法。比如你想实现视频的降噪、运动物体的跟踪、目标(比如人脸)的识别这些都是 CV 的领域;专注于从采集到的视觉图像中获取信息,是用机器来理解图像。OpenGL 是从数据到图像;主要用于生成二维、三维图像,绘制合适的视觉图像给人看。


TinyGL介绍


TinyGL 是提供给嵌入式系统或者游戏的非常小的 OpenGL子集。TinyGL 只实现了 OpenGL 的主要函数调用。TinyGL 最大的特色是快,简单,不完全兼容 OpenGL。最特别的是,纹理映射和几何转换非常的快。


TinyGL 主要特性如下:


  • GLX 的子集,非常容易测试 X Window


  • 类似 GLX 的 API (NGLX) to use it with NanoX in Microwindows.


  • 非常小:x86 系统编译后代码大小为 40 KB


  • 支持 x86-Linux 和 sparc-Solaris


TinyGL的详细介绍见官方网站:TinyGL : a Small, Free and Fast Subset of OpenGL*


TinyGL的故事


TinyGL的作者是法布里斯贝拉(FabriceBellard),是位程序员界绝对的大牛。


即便没听说过TinyGL也一定知道他的另外一个著名的开源项目FFMPEG 。这个项目无比强大,我们今天所熟知的视频播放软件,如暴风影音、QQ影音、YouTube、VLC等都使用了FFmpeg的编解码函数库。FFmpeg易扩展、功能强、速度快、占资源少,支持的音视频格式极其广泛,基本上超越了其他所有同类软件,被誉为处理数字视频和音频的“瑞士军刀”。

继FFmpeg之后,贝拉另一个杰出的成就便是在2005年发布的QEMU。


法布里斯贝拉(FabriceBellard)有着“天才程序员”之称,因为FFmpeg、QEMU等项目而闻名于业界。同时,他凭着极其深厚的计算机底层功力编写出了多款编译器和虚拟机,并靠着出色的数学知识提出了最快圆周率算法贝拉公式。然而面对这些成就,贝拉坦言不过是因为是喜欢做自己感兴趣的事情。


高中写出压缩软件


贝拉于1972年生在法国格勒诺布尔,从小就对电子设备表现出与生俱来的兴趣,据说他咿呀学语时说出的第一个词语是“magn etophone” (录音机)。


良好的家境使得幼时的贝尔能够更加容易地获得他所探索领域的知识和设备。在他9岁时,家里就给贝拉购买了一台TI-59科学计算器,好满足他对编程的好奇之心。11岁时,贝拉拥有了一台更为先进的TI-49/4A私人电脑。15岁时,贝拉的装备换成了Amstrad PC1512,更为强大的配置和全 qwerty 键盘,令贝拉对计算机和编程所表现出来的浓厚兴趣发挥得淋漓尽致。


读高中的贝拉在PC1512 上编程时,因为磁盘空间有限,他想到通过压缩文件来节省有限的磁盘空间。他用8086 汇编语言(PC1512的机器语言)重写了现有的压缩方法LZSS,优化了程序的结构,使得压缩、解压过程变得更加快速,同时允许被压缩的可执行文件在后续的启动时不需要明确的解压缩。这就是后来著名的可执行压缩程序LZEXE,是当年DOS上第一个广泛使用的文件压缩程序。


贝拉将LZEXE发给几个朋友并发布到各种论坛里,引起了不小的轰动,贝拉的编程能力开始崭露头角。


求学时的思考


高中毕业后,贝拉先后进入巴黎高等综合理工学院和法国电信研究院求学。


早年在编程方面的经历,以及在理工学院求学的经历让日渐成熟的贝拉对计算机科学的整体面貌有了更为全面的认识和思考。他认为计算机科学最重要的两个方面是学习计算机如何运作的原理和知识,以及通过学习计算本身来开发语言,用各种不同的方法让计算机更加有效地工作。


而编程必是基于原始程序设计经验,从一个非常靠近机器的语言开始,慢慢发展为高级的语言。贝拉觉得有志向的计算机科学家通过汇编语言和计算机硬件来深度理解计算机的工作原理是必不可少的一个环节。


写出VReng和TinyGL


1998年,贝拉开发出VReng (虚拟现实引擎),这是一个分布式 3D 应用程序,运用多播技术允许通过 Internet 连接在虚拟世界中导航。之后,贝拉注意到有效的OpenGL后端是基于软件的,比实际需求要慢很多。于是他决定基于 VReng 的代码来编写一个更小和更快的3D光栅。


最终在 2002 年,贝拉发布了 TinyGL,一个 OpenGL 的子集的小型实现。TinyGL 比 Mesa 和Solaris 的OpenGL 快很多,是平台独立的,并且数量级比后二者小很多,总共才 400KB。这也是他在图像处理领域取得的重要成就。


开发出 FFmpeg


2000年,贝拉化名Gérard Lantau公布了著名的FFmpeg项目。通过这个项目,贝拉将自己在电信和数字信号处理方面的专长带到了最前沿。


FFMPE允许用户在许多不同的格式之间进行转换。FFMPEG分割成几个部分,由 libavcodec和libformat 构成,Libavcodec收集音频和视频编解码库,Libavformat提供音频和视频容器复用及解复用库,这两个模块结合起来提供了解析和在不同格式之间进行转换的各种方法。


开发出QEMU


继FFmpeg之后,贝拉另一个杰出的成就便是在2005年发布的QEMU。


QEMU是一个处理器仿真,可以用软件来模拟不同处理器体系,允许为一个特定处理器编译的程序通过软件仿真在另外一个体系上运行。QEMU近似于已有的Bochs、PearPC,但具有后两者所不具备的高速及跨平台等特性。


贝拉在QEMU之中大量加入了自己的设计构想,使得它不止是一个简单的处理器仿真器,也可以通过动态翻译来提高性能,借助KQEMU加速器处理,甚至能模拟至接近真实电脑的速度。


QEMU非常强大,若没有过硬的底层硬件和操作系统知识根本完成不了,现在许多的底层开发人员都依赖于它,甚至操作系统教学领域也多用其作为演示。


因为QEMU的速度之快、效率之高,它被包含在许多主要的虚拟化技术中,如 VirtualBox、Xen以及Linux Kernel-based 虚拟机(KVM)。


2011年,贝拉用JavaScript写了一个PC虚拟机Js linux,仿真了一个32位的x86兼容处理器,一个8259可编程中断控制器,一个8254可编程中断计时器,和一个16450 UART。在普通桌面电脑的Chrome浏览器中,Jslinux只用了仅仅5.075秒就启动了Linux。


兴趣最重要


有人问他为什么决定在这样宽广的领域中工作,贝拉回答说:“这也不是决定,只是往往我做同样的事情时感觉很无聊,所以我尝试一次又一次的转换项目。”


当贝拉沉浸在这些工作中时,他希望与全世界共享他的工作成果,也希望这对对他人有所帮助。贝拉不屑于行政管理和社交任务,他喜欢做好的、自己感兴趣的事情。


嵌入式linux上移植TinyGL


TinyGL是Fabrice Bellard开发的OpenGL 1.1子集。Fabrice不用多说,是神仙级程序员。TinyGL是他开发的一个轻量级C语言的OpenGL软件实现。TinyGL的一大优点是,本身实现是纯C的,没有用到任何汇编内嵌,而且编译结果按官方说明只有40K,非常适合移植。


但是标准TinyGL源码底层使用的图形接口好像是基于X11(X Window System)。


X11,X Window System简称。是以位图方式显示软件窗口,为 GUI 环境提供基本框架,但它比较大,有几百兆吧。


TinyX则是一个针对嵌入式系统设计的X Window,相对PC版的X Window而言,它占用的资源要少很多,服务器程序仅700多K,客户端的动态库约2M多。作为XFree86 4.0(Index of /pub/XFree86/4.0)的子集,性能和稳定性都非常好,适合内存资源比较少的系统的X系统,它是以 XFree86为基准,所以构置或设定的方式与 xfree86 是相同的。一般的X Server都太过于庞大,因此Keith Packard就以XFree86为基础,精简了不少东西而成Tiny X Server,它的体积可以小到几百Kb而已,非常适合应用于嵌入式环境。


TinyX底层是基于帧缓冲的fb0,后续可以尝试玩玩儿。但光有TinyX还不够,它只是偏底层的显示驱动。若用来开发GUI可以利用Tiny X 和Gtk+1.2的组合作为嵌入式图形界面的一种解决方案。资源足的用嵌入式QT也是一种方案。GTK+使用c语言,资源占用相对较小,QT则偏C++。


x11这在一些嵌入式linux板子上是没有的,所以选择了一个PicoGL。


PicoGL基于TinyGL 4.0,增加了直接写Linux Framebuffer的backend、使用Makefile组织项目、增加了定点数运算支持。要使用这个软件包还必须有支持软件浮点的交叉编译器。


PicoGL是一位台湾同胞写的, 他的主页 http://jserv.sayya.org/。但是这个软件包的源码极其难找,找到一个能用的地址是 http://people.openmoko.org/jserv/graphics/picogl-20051108.tar.bz2


交叉编译PicoGL


解压缩picogl,修改picogl的代码。


首先是picogl的一处bug,在backends/vesafb/tk.c的第一行增加宏


#define _FB_TK_


然后把backends/vesafb/glx_impl.h里面的


struct fb_fix_screeninfo FixedInfo;
struct fb_var_screeninfo VarInfo, OrigVarInfo;


修改为


#ifdef _FB_TK_
struct fb_fix_screeninfo FixedInfo;
struct fb_var_screeninfo VarInfo, OrigVarInfo;
#else
extern struct fb_fix_screeninfo FixedInfo;
extern struct fb_var_screeninfo VarInfo, OrigVarInfo;
#endif


这是因为有好几个文件调用了backends/vesafb/glx_impl.h,如果不这么改,会出现多重定义错误。然后,为了让你的程序使用picogl更方便些,最好再改个地方include/GL/glx.h


#include GLX_IMPL_HEADER


改为你喜欢的方式,指向backends/vesafb/glx_impl.h


修改backends/vesafb/tk.c中,initialize_fbdev函数有关VarInfo的设置,改为适合你的LCD的。


配置


# cd PicoGL


$CC=/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu/bin/arm-softfloat-linux-gnu-gcc 
./configure --with-backend=vesafb --host=arm-softfloat-linux-gnu --prefix=/home/yang/builtPicoGL


说明


CC=设置交叉编译器的位置


--with-backend=vesafb指定使用FB作为显示设备


host=arm- softfloat-linux-gnu设定交叉编译


--prefix=/home/yang/builtPicoGL设定编译后库和示例程序安装位置。


最后


 $make
 $make install


在/home/lxz/builtPicoGL/lib里就有PicoGL的库了,把动态库文件拷贝到arm-linux根文件系统的/lib 里面。


引用


TinyGL : a Small, Free and Fast Subset of OpenGL*


在ESP32上移植OpenGL实现(一) - 腾讯云开发者社区-腾讯云


OpenGL | ES - 梦来是缘 - 博客园


在ARM Linux上使用OpenGL - 爱码网


OpenGL | ES 移植(装载)_weixin_30496751的博客-CSDN博客


https://www.cnblogs.com/mingjie/archive/2012/11/28/opengl.html


FFmpeg 作者法布里斯贝拉:我只是在做我感兴趣的事


https://www.jianshu.com/p/927748982748


OpenGL ES 简介_猿说编程的博客-CSDN博客


TinyX显示驱动在ARM开发板上的移植 - 百度文库


在Linux下,从头构建图形环境(TinyX + GTK)


TinyX移植步骤_linuxarmsummary的博客-CSDN博客


在ESP32上移植OpenGL实现 | KAAAsS's blog


GTK+系列---关于GTK+_drsonxu的博客-CSDN博客


GTK+介绍_WongKyunban的博客-CSDN博客_gtk+


GTK+笔记之入门(一)_鸿蕊瑞琳的博客-CSDN博客_gtk+


嵌入式设备GUI开发之GTK+入门(一) - 知乎

相关文章
|
6月前
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
130 1
|
2天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
34 13
|
6月前
|
网络协议 算法 Linux
【嵌入式软件工程师面经】Linux网络编程Socket
【嵌入式软件工程师面经】Linux网络编程Socket
190 1
|
4月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
127 3
|
4月前
|
Linux
关于linux的qt发布(linuxdeployqt)中opengl版本过高的解决
关于linux的qt发布(linuxdeployqt)中opengl版本过高的解决
|
4月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
217 0
|
5月前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
|
6月前
|
物联网 Linux 芯片
学习嵌入式是选择单片机还是Linux?
单片机通常指的是一种集成了处理器、存储器和各种外设接口的微控制器芯片,常见的有STC、51系列、AVR、ARM Cortex-M等。单片机具有低成本、低功耗、实时性强等特点,适用于对资源要求较低、功耗要求较低、实时性要求较高的嵌入式系统。学习单片机开发可以让您深入了解嵌入式系统的底层原理和硬件编程,对于对嵌入式系统底层开发感兴趣的人来说,是一个很好的选择。
144 4
|
6月前
|
消息中间件 安全 Java
【嵌入式软件工程师面经】Linux多进程与多线程
【嵌入式软件工程师面经】Linux多进程与多线程
79 1
|
6月前
|
存储 缓存 Unix
【嵌入式软件工程师面经】Linux文件IO
【嵌入式软件工程师面经】Linux文件IO
53 1