What is the purpose of the bmPlanes member of the BITMAP structure?


Many bitmap-related structures in Windows have a field called "planes". For example the BITMAPINFOHEADER structure has a biPlanes member (which must be set to 1). The BITMAP structure has a field called bmPlanes. What's the deal with that field?

The EGA video adapter supported 16 simultaneous colors. This was an enormous improvement over the CGA, which supported only four colors. If you have 16 colors, then you need four bits per pixel. You would think that the encoding would be to have the each byte of video memory encode two pixels, one in the bottom four bits and one in the top four. But for technical reasons, the structure of video memory was not that simple.

Instead of putting the bits for a single pixel next to each other, the color channels were each split into their own monochrome bitmap. In other words, the pixels were sliced "the other way":

0 0 0 0 1 1 1 1 | 0F
0 0 1 1 0 0 1 1 | 33
0 1 0 1 0 1 0 1 | 55
0 1 1 0 0 1 1 0 | 66

0 3 5 6 8 B D E

Suppose you wanted to display eight pixels, with colors { 0, 3, 5, 6, 8 B, D, E } above. Instead of storing the nibbles in that order, slice the nibbles apart into their component bits and collect all the bits from the same position together. In other words, read the bits across rather than down.

In the default 16-color palette, the colors were assigned so that bit 0 was the blue channel, bit 1 was the green channel, bit 2 was the red channel, and bit 3 was the intensity channel. With this interpretation, the four slices can be interpreted as the "intensity plane", the "red plane", the "green plane" and the "blue plane". For the last three planes, you can imagine that each one represents what you would see if only the corresponding electron gun were firing.

Since this was the native color format for EGA, there needed to be a way to express this color format in the BITMAP structure so that device-dependent bitmaps could be represented by Windows.

Thus was born the planar color format. For 16-color planar bitmaps, the number of planes is four and the number of bits per pixel is one.

Comments (21)
  1. Ben Hutchings says:

    Bitplanes used to provide more flexibility than packed pixels – it’s easy to support, say, 3 or 5 planes whereas it would be impractical to pack groups of 3 or 5 bits into bytes. It also makes it easy to implement masked blitter operations, since the 1-bit mask will have the same format as the n-bit buffer. The real down-side is of course the difficulty of manipulating individual pixels. The Amiga only supported the planar format and part of the challenge of implementing fast 3D games was in limiting the need to rewrite a word of memory for the multiple pixels that shared it. One way to do this was to render to a "chunky" (byte-per-pixel) virtual frame buffer and convert that into bitplanes when each frame was complete. I implemented the conversion in assembler and got it down to 256 bytes which will just fit in the 68030 instruction cache. However it’s actually faster to offload part of the work to the blitter.

  2. Ben Watson says:

    A related concept is when creating mipmaps to store multiple resolutions for textures in graphics programming. A bitmap is created and split into four quadrants. Three of them hold the split R, G, and B values. The 4th quadrant is split again into 4 quadrants, etc. storing the texture at half-resolution. This process is repeated recursively until a single pixel is represented. This allows for very efficient storage of textures in multiple resolutions.

  3. alfons says:

    |this was an enormous improvement over the CGA

    <chuckle>

    Sorry.

  4. Ben Cooke says:

    Heh. This reminds me of graphics programming on Commodore Amiga systems. I didn’t realise that EGA worked that way too, as at that point I was only just starting to tinker with these "IBM Compatible PC" things.

  5. 8-bit Dinosaur says:

    And don’t forget about ZX Spectrum – which had display lines interleaved and separate memory for the fore/back color of each 8×8 square.

    I also have some vague memories of blitting data around B000:0000 on Hercules Monochrome (or compatible :)

  6. Mat Hall says:

    Bitplanes had other advantages — the Amiga’s "dual playfield" mode was great for scrolling things over static backgrounds, it made some "demoeffects" trivial (additive blends, etc.), saved RAM in the days when that mattered (why use a whole byte if you only want 8 colours?), the cunning Hold-and-Modify mode (producing an effective 24-bit display from 8-bits) and some others that escape me for the moment.

    The big drawback, as previously mentioned, was that when things progressed from 2D to 3D and drawing individual pixels became a neccessity it all got a bit complicated. However, one saving grave was using the Copper to adjust the palette of individual scan lines on the fly — you could swap the entire CLUT every 2? scanlines, so on an AGA machine (with a 256 colour mode) you could effectively produce a 256×128 "chunky" display. While this may sound terrible, it produced some reasonable DOOM clones that ran on a stock A500, a much lower spec than you needed for a PC to run DOOM reasonably…

    I could blither on and on about the Amiga, but even I must admit that it’s pretty much a dead platform. Sad, but true… (Although one day I’ll try to hold Bill Gates to his promise of porting MS Office to the Amiga once sales reached a million, which he conveniently forgot about when the time came. :)

  7. Dave says:

    Mat Hall: I know it was a typo but "saving grave" is appropos. The grave seems to be the only thing that will save programmers from backwards compatibility hacks and bits of cruft hanging off the API.

  8. Mike Dunn says:

    Wow, I haven’t heard the word "nibble" in years. Kids today just say "four bits" ;)

  9. doynax says:

    What always annoyed me (as a game coder) is that these planar bytes has a big endian bit order. This makes shifting graphics around horisontally a pain as you have to compensate for the fact that you’re actually using a little endian cpu.

    In other words you couldn’t just use the shift instructions for units larger than bytes but you had you also had to swap the bytes around before and after doing it.

  10. About the only reason I can see for bitplanes is that if you’re writing text to the display, you can write the same data to 3 or 4 different locations depending on the color you want to get, rather than doing any "complex math".

    Sad thing is, with a little ingenuity and wasting a bit of memory, you can get exactly the same speed of operation (if not faster) by using a combination of XORs and ANDs on a bitmap.

    I certainly can’t see any hardware reason people would want to split up colors that way.

  11. Raymond Chen says:

    "I certainly can’t see any hardware reason people would want to split up colors that way."

    Indeed the hardware is the reason for planarity. If you go planar, then you can use the same circuitry to control each of the four guns and run them in parallel. And the latching model lets you fit the entire aperture into 64K.

  12. Ben Cooke says:

    Mat,

    I remember playing a game called "The Citadel" late in my time as an Amiga person. I was quite impressed by it; it used the technique you described, I believe.

    It was a bit slow (on my A500+), but it worked pretty well. Its engine was a raycaster like Wolf3D.

    I didn’t see an A1200 until much later, and I’ve never developed for one. Consequently, I don’t know much about the AGA chipset.

  13. Btw, there was an indescribably clever idea that David Weise and Chuck Whittmer had w.r.t. the EGA that allowed writing an arbitrarily colored pixel in a single write that involved misusing the color select latch (IIRC) – this change allowed for tripling the redisplay speed of Windows (one other advantage of the EGA was that it used dual ported memory, which meant you could write to the display directly without flickering, but the disadvantage of htis is that memory writes are very slow).

    The coolest thing was that the IBM hardware engineers who had designed the card swore up and down that you couldn’t write arbitrarily colored pixels in a single write until we showed them how to do it :).

  14. Gene Hamilton says:

    Nintendo did something like on the NES. It also had another table that added another two bits but applied them to 32×32 regions of the screen.

  15. Blobby says:

    I remember discovering this EGA quirk when I was starting PC programming with QuickBasic… I was POKEing (was it POKE in QB? I can’t remember… I do remember I had to do some kind of segment selection first) bytes into video memory, and couldn’t understand why I kept changing the colour of one pixel instead of drawing new pixels side by side. Eventually I figured it out, but it made me regret not buying the EGA/VGA reference guide a lot sooner.

  16. Stuart Brockman says:

    So thats why GEM Desktop’s menus used to cycle through colours as they disappeared!

    They weren’t attempting a "fade" effect, they were just writing each colour seperately and being very slow about it… Odd that it still did it on a VGA setting though… it must have been designed for EGA.

  17. lowercase josh says:

    VGA used planes as well (sometimes), notably for its standard 640x480x16 color mode. There were some weirder modes you could get by programming the registers directly, some where each pixel was 2 bits wide and 4 planes deep.

  18. Richard Mulder says:

    Aah, this brings back memories of Michael Abrash and Mode-X.

    320x240x256, square pixels, double buffering, hardware smooth scrolling. And indeed, 2 bits wide, 4 planes deep. Which allowed you to draw 4 pixels at a time in unchained mode.

  19. Petr Kadlec says:

    IIANM the classic Mode 13h (320x200x256) had bitplanes, too. They were just "hidden in the logic", as the addressing mode made that transparent.

  20. Raymond wrote:

    > Indeed the hardware is the reason for

    > planarity. If you go planar, then you can

    > use the same circuitry to control each of

    > the four guns and run them in parallel. And

    > the latching model lets you fit the entire

    > aperture into 64K.

    Thinking about it, you may save yourself a few gates that way – not many.

    Gut feel tells me that I could do either one in the same number of gates – which means that it may have been a decision based on parts availability.

  21. It goes back to byte alignment.

Comments are closed.

Skip to main content