什么是图形上下文?

Dim*_*ris 8 c x11 opengl gdi quartz-2d

究竟什么是图形上下文(或Windows中的设备上下文)封装?

网上的各种定义同意上下文封装了各种图形操作的参数.请参阅:X11,Mac OS,Windows

目前尚不清楚的是,上下文是否也封装执行图形操作的内存缓冲区.

在X11条目中提到了单独的Drawable对象,Window和Pixmap,它们代表了绘图表面.更进一步,在OpenGL GLX文档中,渲染上下文绘图表面之间有明显的区别.有趣的是,也有人说"应用程序可以使用不同的上下文渲染到同一个表面",并且"也可以使用单个上下文渲染到多个表面".

Jer*_*fin 6

专门查看 Windows 设备上下文,您提出的主要问题的答案似乎是“是和否”。

设备上下文基本上创建了一种完成绘图的模式——即,在任何给定时间,它将具有以下内容的当前设置:

  1. 背景颜色
  2. 前景色
  3. 行宽
  4. 线条图案
  5. 字体

(等等还有很多事情)。

现在,只要有一个绘图表面:是的,我相信每个设备上下文总是有一个绘图表面附加到它。在窗口的设备上下文的常见情况下,绘图表面将是显示窗口的屏幕缓冲区的一部分。在“兼容”设备上下文(例如,来自 CreateCompatibleDC 的结果)的情况下,它将是一个非常无用的绘图表面——特别是,它是一个单色像素。它将设置为黑色或白色,具体取决于您绘制到 DC 的任何内容的整体亮度级别是否超过某个阈值(不,我不记得确切的阈值)。

不过,这确实有一个(某种)有用的目的:特别是,这意味着 DC始终“可用”——永远不会出现仅仅因为没有附加绘图表面而绘制到 DC 就会失败的情况。作为维护这一点的帮助,没有任何DeselectObject功能 - 您可以使用SelectObject将不同的位图选择设备上下文中(这也将取消选择原始位图)但无法从设备上下文中取消选择一个位图而不选择另一个位图- 所以它总是有一个绘图表面。

同时,兼容设备上下文的默认绘图表面几乎毫无用处,几乎可以算作根本没有附加绘图表面。

编辑:我还应该补充一点,选择到兼容设备上下文中的默认绘图表面是很多问题的根源。特别是,当你创建一个兼容的 DC 来做双缓冲绘图时,你必须做这样的事情:

DC memDC = CreateCompatibleDC(windowDC);
BITMAP bmp = CreateCompatibleBitmap(WindowDC, sizeX, sizeY);
SelectObject(memDC, bmp);
Run Code Online (Sandbox Code Playgroud)

但是,如果你稍微搞砸了,而是这样做:

DC memDC = CreateCompatibleDC(windowDC);
BITMAP bmp = CreateCompatibleBitmap(memDC, sizeX, sizeY);
SelectObject(memDC, bmp);
Run Code Online (Sandbox Code Playgroud)

...一切都会成功,并且在某种程度上它甚至会起作用——除了您通过兼容 DC 绘制的所有内容都将以单色结束。这可以追溯到那个单像素单色位图。由于默认情况下兼容 DC 已选择单色位图,因此当您要求兼容位图时,您将获得指定大小的单色位图。在第一个版本中,您要求与选择到原始 DC 中的位图(通常是屏幕)兼容的位图,因此您创建的内容将具有您的屏幕设置的全色。


Hav*_*c P 5

X11 GC 不包含内存缓冲区,Drawable 和 GC 都被传递给所有绘图操作,并且 GC 可以与所有“类似”的 Drawables(同一屏幕上具有相同位深度的 drawable)一起使用。

然而,如今在 X11 中绘制通常是在客户端使用诸如 Cairo 之类的库完成的,因此“真正”的答案取决于该库。在 Cairo 的情况下,Cairo 上下文确实包括当前目标表面,但您可以更改目标表面。

OpenGL 也有一个“当前目标”的概念,不过你也可以改变当前目标。

如果你想概括一下,我会说概念上上下文与缓冲区是分开的,但为了节省打字,人们可能有一个当前缓冲区,你可以在上下文中设置。