在嵌入式linux上玩OpenGL

2022-09-28 12:56:49 浏览数 (1)

前言

在我的嵌入式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多,且TinyX底层基于帧缓冲的fb0,后续可以尝试玩玩儿)。作为XFree86 4.0(Index of /pub/XFree86/4.0)的子集,性能和稳定性都非常好,适合内存资源比较少的系统的X系统,它是以 XFree86为基准,所以构置或设定的方式与 xfree86 是相同的。一般的X Server都太过于庞大,因此Keith Packard就以XFree86为基础,精简了不少东西而成Tiny X Server,它的体积可以小到几百Kb而已,非常适合应用于嵌入式环境。

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的一处bug,在backends/vesafb/tk.c的第一行增加宏

#define _FB_TK_

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

代码语言:javascript复制
struct fb_fix_screeninfo FixedInfo;

struct fb_var_screeninfo VarInfo, OrigVarInfo;

修改为

代码语言:javascript复制
#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

代码语言:javascript复制
$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设定编译后库和示例程序安装位置。

最后

代码语言:javascript复制
$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

0 人点赞