0%

Linux 图形编程简介

简单介绍 Linux 图形编程概念、协议及库

  • SDL
  • OpenGL
  • DirectFB
  • FrameBuffer

OpenGL

OpenGL is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics. The interface consists of over 250 different function calls which can be used to draw complex three-dimensional scenes from simple primitives. OpenGL was developed by Silicon Graphics Inc. (SGI) in 1992[4] and is widely used in CAD, virtual reality, scientific visualization, information visualization, and flight simulation. It is also used in video games, where it competes with Direct3D on Microsoft Windows platforms (see OpenGL vs. Direct3D).

OpenGL 是一套规范 (Specification),由 Khronos Group 开发维护。
它主要为我们定义了用来操作图形和图片的一系列函数的 API,需要注意的是 OpenGL 本身并非 API。
GPU 的硬件开发商则需要提供满足 OpenGL 规范的实现,这些实现通常被称为“驱动”,它们负责将 OpenGL 定义的 API 命令翻译为 GPU 指令。

OpenGL 仅仅是标准,而如果你要使用 OpenGL,则需要找到可以实现这些 OpenGL 标准函数的程序库或源代码。
主要的 OpenGL|ES 程序库有:Klimt,Vincent (ogles),TinyGL 等

DirectX

linux 不支持对于游戏来说非常重要的驱动——DirectX。

游戏驱动一般来说有两种——OpenGL 和 DirectX。
OpenGL 驱动不仅在游戏方面很重要,还在图形处理方面有举足轻重的作用。所以大家在装显卡驱动后都可以看到 OpenGL 的设置选项。几乎所有的操作系统(windows,linux,MacOS)都支持 OpenGL。
DirectX 是微软专门 为游戏设计的一套驱动(程序接口)

SDL

SDL 是一个跨平台的多媒体库,它通过 OpenGL 和 2D 视频帧缓冲,提供了针对音频、视频、键盘、鼠标、控制杆及 3D 硬件的低级别的访问接口。

SDL is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, etc. It also supports 3D hardware via OpenGL.

SDL uses OpenGL as a hardware renderer for content that wants hardware rendering on some platforms. If you have such a platform, then OpenGL is the underlying API over which SDL is an abstraction.

SDL(Simple DirectMedia Layer)作为免费的跨平台多媒体应用编程接口,已经被人们广泛用于开发二维游戏,其优秀的消息框架支持、文件支持和声音支持都使得它能与微软 DirectX 匹敌。

现在很多 game 游戏里面,都采用 SDL+OpenGL ES 的模式来绘制 3D 界面。 可以让 SDL 使用 OpenGL ES 的函数接口来渲染 3D。

SDL 在结构上是将不同操作系统的库再包装成相同的函数,例如 SDL 在 Windows 平台上其实是 DirectX 的再包装。而在使用 X11 的平台上(包括 Linux),SDL 则是与 Xlib 库沟通来输出图像。

SDL Modules

从图中可以看到 SDL 是平台性质,可以基于 FBOpenGL

SDL 库分为 Video、Audio、CD-ROM、Joystick 和 Timer 等若干子系统,除此之外,还有一些单独的官方扩充函数库。这些库由官方网站提供,并包含在官方文档中,共同组成了 SDL 的“标准库”:

  • SDL_image—支持时下流行的图像格式:BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。
  • SDL_mixer—更多的声音输出函数以及更多的声音格式支持。
  • SDL_net—网络支持。
  • SDL_ttf—TrueType 字体渲染支持。
  • SDL_rtf—简单的 RTF 渲染支持。

Linux FrameBuffer

Linux 下的 framebuffer 是用于在显示器上显示图像的硬件无关抽象层,意味着包含当前视频帧的一块内存区域

Framebuffer 看成是显示内存的一个映像,将其映射到进程地址空间之后,可以直接进行读写操作,写操作可以立即反应在屏幕上,这种操作是抽象统一的,用户态进程不必关心物理显存的位置、换页机制等等具体细节(由 Framebuffer 设备驱动来完成)

Framebuffer 对应的设备文件一般是 /dev/fb0/dev/fb1

使用方法:

  • 打开 framebuffer 设备 (/dev/fbX)
  • 通过 ioctl FBIOGET_VSCREENINFO 命令获取当前 fb_var_screeninfo 信息
  • 设置需要修改的 fb_var_screeninfo 参数,并通过 ioctl FBIOPUT_VSCREENINFO 设置这些信息(可选)
  • 设置 global alpha 和 blank/unblank 参数,通过用于多个 fb 的情况(可选)
  • 计算屏幕的总大小(占用字节数): xres * yres * bits_per_pixel / 8
  • 映射到用户进程地址空间:mmap
  • 往映射的地址空间写入数据
  • 删除映射 (munmap), 关闭 framebuffer 设备

DirectFB

DirectFB 项目是由德国 Convergence 公司推动的 Open source 计划的一部分,它是专门为满足嵌入式设备要求而开发的小巧、强大、灵活和易于使用的图形系统,并且试图成为一个建构于 Linux Framebuffer Device 之上的新图形标准。它在 FrameBuffer 的基础上提供了图形加速、输入设备处理提取、透明窗口和多重显示层的功能,能够对嵌入式系统 GUI 有较好的支持。与那些通用的嵌入式 GUI 系统相比,它具有非常简洁、高效的体系结构和硬件图形加速功能。

DirectFB 是一个轻量级的提供硬件图形加速,输入设备处理和抽象的图形库,它集成了支持半透明的视窗系统以及在 LinuxFramebuffer 驱动之上的多层显示。它是一个用软件封装当前硬件无法支持的图形算法来完成硬件加速的层。DirectFB 是为嵌入式系统而设计。它是以最小的资源开销来实现最高的硬件加速性能。

DirectFB 是图形 API 存在于 Frame Buffer 层之上与高级图形管理层如 GTK+ 等之下的。它可以以很小的系统资源占用来提供图形硬件加速功能,提供类如多路 a 通道渲染模型等高级图像操作。它不修改 Linux 内核,除了标准 C 库没有其他库的依赖。应用在了基于 Linux 系统的 DTV 显示系统的研发和其他有关 Linux 显示界面的项目上。支持市面上绝大多数显示卡,支持键盘、鼠标、遥控器、游戏手柄、触摸屏等输入设备。支持 JPEG、PNG、GIF、mpeg1/2、AVI、MOV、Flash、Video4Linux、DirectFB bitmap font 和 TrueType 等音视频文件和字体。

DirectFB 在系统中的位置

DFB

DirectFB GUI 架构

DFB Modules

对于底层的驱动来说,DirectFB 里面负责和硬件打交道的显卡的驱动(gfxdriver)和显示系统(system),这里面 gfxdriver 是和各个硬件平台相关的,有可能需要自己写。 为了更易于理解 DirectFB,需要先介绍几个 DirectFB 里面的概念:

  • Layers:代表互相独立的图形缓存。大多数嵌入式设备都有多个 layer。多个 layer 根据对应的 alpha 值混合 在一起,从而显示出来。
  • Surface:代表一块预留的内存,来保存像素数据。DirectFB 中的 Drawing,Bilitting 操作就是基于 surface 的。Surface 的内存根据设定,可以从系统中分配,也可以从显卡的内存中分配。
  • Primary Surface:代表一个特殊 layer 的特殊 surface。如果 primary surface 是单缓冲的,任何对于 primary surface 的操作都会直接反应到显示屏上。
  • Subsurface:是一个 surfac 的子集,但是自身并不占有任何内存。
  • Window/Windowstack:控制一个 layer 中的 surface 该显示什么。Window 属于某个背景可以设定的 layer。 每个 window 有自己的 surface,window 用这个 surface 来组合图像。

Ref

  1. OpenGL 是什么?
  2. OpenGL 与 DirectX 比较
  3. SDL 介绍
  4. Linux framebuffer 的介绍和使用