GUI是如何绘制的?

4

人们如何制作GUI?我指的是用于在屏幕上绘制可视化组件的基本构建块或原则,例如KDE、Gnome等。是否有任何简单的示例可以直接通过处理硬件来绘制屏幕上的矩形之类的东西?

针对我的平台,我正在使用PC。


这完全取决于你的平台。 - EboMike
当你说“PC”时,你可能指的是“Windows”?好的,接下来 - 我们在谈论哪一层?你是要创建一个具有自己GUI的Windows应用程序吗?还是你正在编写自己的操作系统?! - EboMike
当我说PC时,我的意思是PC而不是Windows。我同时双启动Windows和Linux。给出Windows或Linux的示例将很有用,但我真正想要的是跨平台。我想直接处理硬件,我并不试图实现某种特定功能,而是想知道这样的事情是如何工作的。 - Lettuce
涉及到许多层面,详见我的帖子。底线是 - 你需要一个驱动程序来与显卡通信,而这个驱动程序是特定于你的内核的。 - EboMike
1
“内核”可以是“Linux 2.6.35”,或者“Windows 7”,或者“Windows 95”。每个内核都完全不同。之所以有所有这些层,是因为你不必担心所有这些。你正在编写应用程序吗? - EboMike
显示剩余3条评论
4个回答

8
好的,让我们从最基本的开始。您拥有一个显示图像的监视器。这个图像是一个像素矩阵,比如说1600x1200像素,深度为24位。
监视器从视频适配器知道要显示什么。视频适配器通过“帧缓冲区”知道要显示什么,它是一个大块内存,在这个例子中包含1600*1200像素,通常在现代卡中每个像素有32位。
帧缓冲区通常可以作为一个大块内存直接被CPU访问和修改,一些适配器有GPU,允许像渲染阴影纹理三角形这样的东西进入帧缓冲区,所以CPU只需通过“命令缓冲区”发送命令告诉它绘制什么和在哪里绘制。
然后您有操作系统,它加载与视频适配器通信的硬件驱动程序。
操作系统通常提供使用函数写入帧缓冲区的功能。例如,Win32有很多函数,如BitBlt、Line、Text等,这些函数最终会与驱动程序通信。
然后您有像Java这样的东西,它会渲染自己的图形,通常使用操作系统提供的函数。

那么学习任何可以处理帧缓冲区的工具都可以让我自由地制作自己的GUI,对吗? - Lettuce
2
这仍然取决于您要解决哪个层次的问题。您是在编写自己的操作系统吗?您是在编写自己的内核吗?除非您从头开始编写自己的内核,否则您无法实现平台无关性(祝您好运!)。这就是为什么我们有像Win32或Java或QT这样的东西-使您能够实现平台无关性,尽管您需要为每个图形适配器编写自定义驱动程序,并且每个操作系统都有其自己的方式向您公开驱动程序。 - EboMike

5
简单的答案是位图,实际上这也适用于早期终端上的字体。
最初的GUI,例如Xerox Parc's Alto GUI,是基于位图显示的,使用简单的位图绘图工具和图形库来绘制图形,使用简单的几何形状如圆形、正方形、矩形等,并将它们映射到显示像素上。
今天的GUI与以前相同,只不过增加了软件和硬件,加速和改进了这些GUI的过程和性能。
比特映射到像素的基本映射取决于显示硬件,但在简单的级别上,您将提供一个在内存中的显示缓冲区,并简单地填充其字节以显示数据。
因此,对于基本的单色位图,您可以通过提供表示所需绘制形状的位来进行绘制,您可以像这样定位这些位,例如简单的8x8像素按钮。
01111110
10000001
10000001
10111101
10111101
10000001
10000001
01111110

如果我使用#和空格而不是1和0进行渲染,您就可以更容易地看到。
 ###### 
#      #
#      #
# #### #
# #### #
#      #
#      #
 ###### 

如果将其作为位图图像来查看,它会像这样:http://i.stack.imgur.com/i7lVQ.png(我知道它有点小 :),但这是GUI开发初期我们开始的规模。)

如果您拥有更复杂的显示器(例如24位色彩显示器),您需要使用24位数字提供每个像素。

显然,有些位图无法手动绘制(例如窗口边框),就像我们上面所做的那样,这就是几何学派上用场的地方,我们可以使用简单的函数来确定绘制矩形或任何其他简单形状所需的像素值,然后从那里构建。

一旦您能够以这种方式在显示器上绘制图形,就可以将绘图循环挂接到系统中断上,以保持显示器的最新状态(根据系统性能不同,您需要经常重新绘制显示器)。这样,您就可以使其处理来自用户设备(例如鼠标)的交互。

在早期,甚至在施乐帕克/奥托之前,就有许多早期计算机系统采用了矢量显示器,通过在笛卡尔平面的CRT表示上绘制线条来组成图像。然而,这些显示器从未得到主流使用,除了一些早期的视频游戏,比如《小行星》和《暴风雨》。

那么你如何在计算机上实现这个呢?我的意思是,如果我想要在屏幕上真正地显示它,我该怎么做?任何语言的示例都可以。 - Lettuce
这可以使用汇编语言完成,在非常基本的层面上,您将分配一个缓冲区(内存区域),然后将其发送到显示系统(在我们的示例中是单色显示器),我们称之为显示缓冲区。- 然后,我们可以对显示缓冲区执行各种操作,以呈现形状或位图设计。 - ocodo
当然,现在你永远不需要接触到这么低层次的东西,而且有许多不同的方法可以构建GUI。从这些非常基本的级别构建完整的GUI是一件相当愚蠢的事情,但是你可以在这个低层次上做一些练习,以了解工作原理和机制。 - ocodo
如果你只是想尝试位图渲染,可以使用Python - http://pyx.sourceforge.net/examples/bitmap/index.html - 或者ActionScript3(使用flash.display.BitmapData和flash.display.Bitmap类,尽管我认为只支持24位) - 大多数编程语言都提供绘制位图的方法。 - ocodo
矢量图形显示器,如Tektronix终端(http://en.wikipedia.org/wiki/Tektronix_4010),在70年代至80年代初期,在科学市场上得到广泛应用。 - David Gelhar
是的,它们确实从未成为主流。 - ocodo

0

你可能需要一个图形库,例如OpenGL

如果要进行直接的硬件交互,你可能需要像汇编一样的操作,这是完全针对计算机的。


我知道有DirectX、OpenGL和其他的技术,但我想要理解图形用户界面的底层原理,也就是非常基础的原理。 - Lettuce
@Lettuce:这取决于平台。 - thyrgle
@给踩票者:请问,我很好奇您对我的回答有何不满意之处。 - thyrgle
我怀疑你不会在普通GUI中使用OpenGL。也许是现代的花哨界面,但不适用于简单的框、线和三角形。 - EboMike
@EboMike: 你可能会使用供应商提供的东西,但是,你认为他们是用什么做的呢?他们很可能编写了自己的类似OpenGL实现,然后在此基础上编写框架,以便我们可以使用它们来创建图形用户界面。 - thyrgle
@EboMike,图形库通常利用GPU,在OpenGL或DirectX的基础上构建。通过这种方式,你可以更快地绘制线条和矩形框。 - nos

0

如果你愿意查看大量的源代码,可以看看Mesa 3D,这是一个OpenGL规范的开源实现。


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