【问题标题】:What exactly is a Graphic Context?究竟什么是图形上下文?
【发布时间】:2011-10-12 16:56:35
【问题描述】:

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

网络上的各种定义一致认为上下文封装了各种图形操作的参数。见:X11Mac OSWindows

不清楚的是上下文是否也封装了内存缓冲区,在该缓冲区上执行图形操作。

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

【问题讨论】:

  • 您为什么认为所有这些不同的 API 在“上下文”中意味着完全相同的东西? ;)
  • 内存缓冲区不必一开始就存在(想想笔式绘图仪)。

标签: c opengl gdi x11 quartz-2d


【解决方案1】:

具体查看 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);

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

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

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

【讨论】:

  • 谢谢,写的很详细!但是,我将不得不把它交给 Havoc,因为它更切中要害。
【解决方案2】:

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

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

OpenGL 也有“当前目标”类型的概念,不过您也可以更改当前目标。

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-09-26
      • 2012-07-30
      • 2017-11-28
      • 2014-10-28
      • 2012-08-27
      • 2010-11-12
      • 2011-03-18
      • 2011-01-22
      相关资源
      最近更新 更多