什么是图形上下文?

12

Graphic Context(或Windows中的Device Context)到底封装了什么?

网络上的各种定义都认为,上下文封装了各种图形操作的参数。X11Mac OSWindows。但不清楚上下文是否还封装了执行图形操作所需的内存缓冲区。

X11入口中提到了单独的Drawable对象,Window和Pixmap,它们代表了绘图表面。在深入研究OpenGL GLX文档时,可以清楚地看到渲染上下文绘图表面之间的明确区分。有趣的是,文档还指出:“应用程序可以使用不同的上下文将图像渲染到同一个表面,”以及“还可以使用单个上下文将图像渲染到多个表面”


3
为什么您认为所有这些不同的API都以“上下文”表示完全相同的含义呢? ;) - jalf
1
一个内存缓冲区不一定需要一开始就存在(比如钢笔绘图仪)。 - n. m.
3个回答

7

X11 GC不包含内存缓冲区,绘图操作需要同时传入Drawable和GC,GC可以与所有“类似”的Drawable(在相同屏幕上具有相同的位深度)一起使用。

然而,在现代X11中,绘图通常是通过像Cairo这样的库在客户端完成的,因此“真正”的答案取决于该库。在Cairo的情况下,Cairo上下文确实包括当前目标表面,尽管您可以更改目标表面。

OpenGL也有一种“当前目标”概念,虽然您可以更改当前目标。

如果您想概括,我会说概念上上下文是与缓冲区分离的,尽管为了节省输入,人们可能会在上下文上设置当前缓冲区。


6
看起来你主要在问关于Windows设备上下文的问题,答案是“是和否”。
设备上下文基本上创建了一种绘图模式——也就是说,在任何给定的时间,它将拥有当前设置的各种参数,例如:
1. 背景颜色 2. 前景颜色 3. 线条宽度 4. 线条样式 5. 字体
(还有其他很多参数)
至于是否存在绘图表面,我认为每个设备上下文都始终附带一个绘图表面。对于窗口的设备上下文的普通情况,该绘图表面将是窗口所显示的屏幕缓冲区的一部分。对于“兼容”设备上下文(例如CreateCompatibleDC的结果),它将是一个几乎无用的绘图表面——具体而言,它是一个单色像素。它将被设置为黑色或白色,具体取决于您在DC上绘制的整体亮度水平是否超过某个阈值(我不记得确切的阈值)。
尽管如此,这确实有一个(有点)有用的目的:特别是,它意味着DC始终“可用”——永远不会因为没有绘图表面附加而导致绘图失败。为了帮助维护这一点,没有DeselectObject函数——您可以使用SelectObject将不同的位图选择到设备上下文中(这也会取消选择原始位图),但是没有方法从设备上下文中取消选择一个位图而不将另一个选择到其中,因此它始终附带一个绘图表面。
同时,对于兼容设备上下文的默认绘图表面几乎毫无用处,几乎可以视为没有附加绘图表面。
编辑:我还应该补充说,选择到兼容设备上下文中的默认绘图表面是许多问题的根源。特别是,在创建兼容DC以执行双缓冲绘图时,您必须执行以下操作:
DC memDC = CreateCompatibleDC(windowDC);
BITMAP bmp = CreateCompatibleBitmap(WindowDC, sizeX, sizeY);
SelectObject(memDC, bmp);

然而,如果您稍微出了点差错,并做了以下操作:

DC memDC = CreateCompatibleDC(windowDC);
BITMAP bmp = CreateCompatibleBitmap(memDC, sizeX, sizeY);
SelectObject(memDC, bmp);

一切都将成功,甚至在某种程度上它们都能够正常工作,但是所有通过兼容的DC绘制的图形最终都会变成单色。这源于一个像素的单色位图。由于默认情况下,兼容的DC中选择了一个单色位图,因此当您请求一个兼容的位图时,您将获得一个指定大小的单色位图。在第一个版本中,您请求与原始DC所选位图兼容的位图,通常将是屏幕,因此您创建的内容将具有屏幕设置的全彩色。


谢谢,那很详细!不过,我还是得承认Havoc更加简洁明了。 - Dimitrios Menounos

1

对于其他平台不确定,但在Windows上,设备上下文(或DC)只是一个不透明指针。内部结构由GDI维护,并包含有关绘制到屏幕的内容的信息。

要操作正在绘制的对象,您需要将此不透明指针(或句柄)传递给GDI函数。这与管理窗口属性的HWND句柄的概念相同,只是HDC用于管理图形。


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