在Linux上快速高效地绘制像素数组

4
我怎样可以在中快速绘制像素数组?
我在stackoverflow上看到了很多类似的问题, 它们都被回答为:
- 使用gdi(Windows) - 使用OpenGL - ...
但是OpenGL一定有一种方法可以做到! 我正在编写一个小型光线追踪器,并需要绘制每个像素 每秒多次。OpenGL能够实现这一点, 跨平台快速,因此, 我如何实现不使用OpenGL的这一功能呢?
"不使用OpenGL"并不意味着
- 使用sdl(慢) - 使用这个/那个库
仅建议使用本地方法最接近本地方法的库。 如果可能(我知道肯定可以),如何实现呢? 跨平台的解决方案更可取
2个回答

4
在Linux上绘图,你必须使用X11或OpenGL。(未来的选项也可能是Wayland)。在Linux上没有“本地”完成图形处理的方法,因为Linux内核不关心图形API。它提供了一个接口(DRM),通过这个接口图形系统在用户空间中实现。如果您只想在屏幕上显示像素点,而不关心窗口,则还可以mmap /dev/fbdev - 但通常不建议这样做,因为没人希望他的屏幕被某些不能移动或隐藏的程序疯狂刷屏。
无论使用哪种API,绘制单个点都是低效的,因为需要协议开销。
因此,使用X11是最好的选择。所以最好的选择是使用MIT-SHM扩展,用它来修改缓冲区中的像素,并由X11服务器整体传输。当然,使用纯粹的X11 Xlib函数进行操作是非常麻烦的。所以SDL实际上很好地包装了这一点。
另一个选择是OpenGL。OpenGL不是库!它是一个系统级API,可以几乎直接访问GPU。并且它与X11很好地集成在一起。是的,API通过一个被加载的库提供,但从技术上讲,该库只是实际驱动程序的“包装器”或“接口”。使用OpenGL绘制单个点没有意义。但是,您可以将几个点“批处理”到一个列表中(使用顶点数组),然后处理该列表。所以,这个想法是在两个显示刷新间隔之间收集所有传入的点,并以一个批次绘制它们。
引用:
优先选择跨平台的解决方案。
如果定义为本机,则不能有跨平台本地API。要么你是本地的,要么你是跨平台的。
在您的特定场景中,我认为SDL是最好的解决方案,因为它为光线追踪器提供了恰当的抽象和程序侧接口。仅供参考:像QEmu这样的虚拟机使用SDL。
或者你可以使用OpenGL,它是一个真正的跨平台API,被广泛支持。

使用“本地”和“平台无关”的方法,我将实现几种本地方法以实现平台无关性。 目前我正在使用SDL,但它绝对太慢了。 用红色填充一个400*800的窗口,我只能得到5 fps,但我至少需要40 fps。所以我想你建议使用SDL和OpenGL来绘制包含我的图像的四边形,对吗? - bricklore
@Schnizel1337:您可能会遇到的问题是,绘制一个单独的点确实很慢。我建议您使用普通的SDL,并学习如何高效地操作帧缓冲中的像素。使用SDL_LockSurface,然后操作许多可通过surface->pixels访问的像素,并再次解锁它。并记住要批处理像素,不要为每个像素单独执行此操作。 - datenwolf
这正是我一直在做的,我从未打算设置单个像素,但无论如何速度都太慢了。 - bricklore
@Schnizel1337:你能发一些代码吗?你确定在帧缓冲区中设置像素确实是瓶颈,而不是你的光线追踪器吗?你知道实时光线追踪是一个非常困难的问题,实时性能很难获得。 - datenwolf
我可以在一张老旧的P233电脑上,搭配一张8兆PCI ATI显卡,以大约20FPS的速度执行640x480 32位RGB绘图。使用SDL,你也可以做到,只需要正确操作即可 ;) - Jubatian

4
在Linux上绘制图形,你需要使用X11或OpenGL。这是完全错误的! 举个反例:有些平台不运行X11,但它们显示像素(例如字体)。顺便说一下,OpenGL通常依赖于X11(尽管难度较大,可以在没有X11的情况下运行OpenGL)。正如@datenwork所说,还有至少两种其他绘制像素的方法:
  1. 帧缓冲设备(fbdev),是一种抽象接口,用于与图形硬件进行交互。非常老旧,由Martin Schaller设计,详见内核文档。源代码在这里。还可参见这里。这是最简单的帧缓冲驱动程序
  2. 直接渲染管理器(DRM),是一个内核子系统,提供了一个API,使用户空间应用程序能够直接向GPU发送命令/数据。(似乎与OpenGL做的事情非常相似,但我不确定!)。源代码在这里。这是一个DRM示例,它初始化了一个简单的显示管道。

这两者都是内核的一部分,所以它们比X11更低级,而X11不是内核的一部分。这两者都可以绘制任意像素(例如penguins)。我猜想这两者都是跨平台的(如OpenGL)。

有关如何在Linux上绘制内容的更多信息,请参见this


1
这里有损坏的链接。 - Bacco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接