Dimitrios Menounos
Dimitrios Menounos

Reputation: 555

What exactly is a Graphic Context?

What exactly is encapsulated by a Graphic Context (or Device Context in Windows)?

The various definitions across the net agree that a context encapsulates the parameters for the various graphics operations. See: X11, Mac OS, Windows

What is not clear is whether a context also encapsulates the memory buffer upon which the graphics operations are performed.

In the X11 entry there is a mention about separate Drawable objects, Window and Pixmap, which represent the drawing surfaces. Going a bit further, into the OpenGL GLX documentation, there is a clear separation between Rendering Contexts and Drawing Surfaces. Interestingly it is also said that "applications can render into the same surface, using different contexts" and that "it is also possible to use a single context to render into multiple surfaces".

Upvotes: 12

Views: 4235

Answers (3)

Havoc P
Havoc P

Reputation: 8467

An X11 GC does not contain the memory buffer, both the Drawable and the GC are passed in to all the drawing operations, and the GC can be use with all "like" Drawables (drawables on the same screen with same bit depth).

However drawing in X11 these days is normally done client-side using a library such as Cairo, so the "real" answer depends on that library. In Cairo's case the Cairo context does include a current target surface, though you can change the target surface.

OpenGL also has a "current target" kind of concept, though again you can change the current target.

If you want to generalize I'd say that conceptually a context is separate from the buffer, though to save typing people may have a current buffer you can set on the context.

Upvotes: 7

Jerry Coffin
Jerry Coffin

Reputation: 490088

Looking specifically at a Windows Device Context, the answer to the primary question you're asking seems to be "yes and no".

A device context basically creates a mode in which drawing will be done -- i.e., at any given time, it'll have current settings for things like:

  1. Background color
  2. foreground color
  3. line width
  4. line pattern
  5. font

(and so on for quite a few more things).

Now, as far as there being a drawing surface: yes, I believe every device context always has a drawing surface attached to it. In the common case of a device context for a window, that drawing surface will be the part of the screen buffer where the window is displayed. In the case of a "compatible" device context (e.g., result from CreateCompatibleDC) it'll be a pretty useless drawing surface -- specifically, it's a single, monochrome pixel. It'll be set to either black or white, depending on whether the overall brightness level of whatever you draw to the DC exceeds a certain threshold or not (and no, offhand I don't remember the exact threshold).

This does have a (sort of) useful purpose though: in particular, it means that a DC is always "usable" -- there's never a situation in which drawing to a DC will fail just because there's no drawing surface attached. As an aid in maintaining this, there's no DeselectObject function -- you can use SelectObject to select a different bitmap into the device context (which will also deslect the original one) but there's no way to deselect one bitmap from the device context without selecting another into it -- so it always has a drawing surface attached.

At the same time, the default drawing surface for a compatible device context is so close to useless that it almost counts as not having a drawing surface attached at all.

Edit: I should also add that the default drawing surface that's selected into a compatible device context is a source of quite a few problems. In particular, when you're creating a compatible DC to do double-buffered drawing, you have to do something like this:

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

If, however, you screw up ever so slightly and do this instead:

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

...everything will succeed, and to some extent it'll all even work -- except that everything you draw via the compatible DC will end up in monochrome. This goes back to that one-pixel monochrome bitmap. Since the compatible DC has a monochrome bitmap selected into it by default, when you ask for a compatible bitmap, you'll get a monochrome bitmap of the specified size. In the first version you're asking for a bitmap compatible with the bitmap selected into the original DC, which will normally be the screen, so what you create will have the full color your screen is set for.

Upvotes: 6

Praetorian
Praetorian

Reputation: 109119

Not sure about other platforms, but on Windows a Device Context (or DC) is simply an opaque pointer. The internal structure is maintained by GDI and contains information about stuff being drawn to the screen.

To manipulate the objects being drawn you pass this opaque pointer (or Handle) to GDI functions. This is the same in concept as HWND handles that manage a window's attributes, except an HDC manages graphics.

Upvotes: 1

Related Questions