究竟什么是图形上下文?

时间:2011-07-25 15:27:52

标签: c opengl gdi x11 quartz-2d

完全是由图形上下文(或Windows中的设备上下文)封装的?

网上的各种定义都同意上下文封装了各种图形操作的参数。请参阅:X11Mac OSWindows

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

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

3 个答案:

答案 0 :(得分:4)

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

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

  1. 背景颜色
  2. 前景色
  3. 线宽
  4. 线条图案
  5. 字体
  6. (以及其他更多内容)。

    现在,只要有一个绘图表面:是的,我相信每个设备上下文总是附加一个绘图表面。在窗口的设备上下文的常见情况下,该绘图表面将是显示窗口的屏幕缓冲区的一部分。在“兼容”设备上下文(例如,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中的位图兼容,通常是屏幕,因此您创建的将具有屏幕设置的全彩色。

答案 1 :(得分:3)

X11 GC不包含内存缓冲区,Drawable和GC都传入所有绘图操作,GC可用于所有“类似”Drawables(同一屏幕上具有相同位深度的drawable) )。

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

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

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

答案 2 :(得分:1)

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

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