(C) 1994 Metagraphics Software Corporation Metagraphics Software Corporation 269 Mt. Hermon Rd., Ste. 104 Scotts Valley, CA 95066 (408) 438 - 1550 Sales (408) 438 - 6750 Support (408) 438 - 5379 FAX (408) 438 - 5368 BBS support@metagraphics.com June 20, 1994 This document explains how to use 16 bit per pixel color modes with MetaWINDOW, as well as a rudimentary explanation of how color palettes work in 16 and 256 color modes. Sixteen bit per pixel modes, also known as HiColor modes, allow either 32k or 64k different colors to be used on the screen at any time, assuming your hardware and software support it. The thing to be aware of is that there is no color palette in these modes. If you already know what a color palette is and how to read/write it then skip the next section. The Color Palette ====================================================================== Let's take a look at the way in which 16 (4 plane) and 256 (8 bit per pixel) color modes work. We'll start at the hardware level and work our way out to the software interface. Cathode Ray Tubes (CRT's) have 3 electron guns, one each for Red, Green and Blue. Each one can be turned on to different intensities, giving us almost infinite color variations visible on the screen. The RAM that is physically on the graphics board is called the frame buffer. All drawing operations to and from the screen happen by reading or writing to this memory. The memory may be arranged in different ways for different color modes. For instance, in monochrome modes each bit is a single pixel, and in 256 color modes each byte is a pixel. Finally, in 16 color modes it takes 4 bits to make up a pixel or 2 pixels per byte. With the introduction of the VGA the concept of analog color monitors was introduced. You still have the Red Green and Blue (RGB) wires coming out of the monitor, but instead of being binary signals like they were in EGA monitors they are now analog (infinitely variable, like the control on a gas stove): Red (off to full on) Green (off to full on) Blue (off to full on) The physical device (a single chip usually) which actually functions as the palette is called a RAMDAC (Random Access Memory, Digital to Analog Converter). This is a lot to remember, so we'll talk about what it does first, and then you'll know why it's called that. The VGA 640x480 mode has a limit of 16 maximum displayable colors at a time, because the frame buffer uses 4 bits to describe each pixel, but each of those sixteen colors can be any of 262,144 colors. Confused? Don't worry, we'll explain that next. Think of the VGA RAMDAC as being an array of type: gun = 6 bits // We didn't make this up, we just report it. struct palette: { gun RED; gun BLUE; gun GREEN; }; struct palette RAMDAC [16]; Remember, this is just a model, in real life it's not this simple. Now lets put this together with the numbers that you pass PenColor() to use while drawing. Let's use PenColor(2) as an example. In VGA mode it's the second entry into the array: RAMDAC[2]; which can have any of 64 different colors for each color gun. For instance: RAMDAC[2].RED = 0; RAMDAC[2].GREEN = 60; RAMDAC[2].BLUE = 12; or any other values you may wish to use when you set it via WritePalette(). Note that MetaWINDOW will automatically set the color palette for colors 0 through 15 and the last color to match the default EGA colors in 16 and 256 color modes to make life easy on you. All the other colors will be set randomly and you can change any palette entry at any time. The same mechanism is used in 256 color modes. The only difference is that the frame buffer holds a byte per pixel, so instead of having RAMDAC[16] you get RAMDAC[256]. Now that you know all this it's easier to explain the meaning of the word RAMDAC. RAM is for the memory on the RAMDAC which holds the values for each RAMDAC entry (16 or 256 of them). The DAC (Digital to Analog Converter) takes the various entries of gun RED; gun BLUE; gun GREEN; and converts them into actual voltages fed to the monitor. The more bits on in the entry, the higher the voltage and therefore the brighter the color of that gun. So whenever you call the MetaWINDOW functions ReadPalette() or WritePalette() you are reading or writing the values stored in the hardware RAMDAC. For this reason, Read/WritePalette() won't work on an offscreen bitmap, there simply is no such device, it's just RAM. Color Values in 16 Bit Modes ====================================================================== Now that we know what a RAMDAC is (or hardware palette) there is just one thing to know about HiColor modes. They don't have a palette. Functions like Read/WritePalette() won't work because there is no palette. There still has to be a DAC to convert the values stored in the frame buffer to a voltage for each color gun though, but instead of relying on the color palette to map each number to a particular RGB combination it reads the RGB values directly from the frame buffer. The reason most programmers have trouble understanding 16 bit per pixel modes is because the color values are interpreted differently than in the color modes which have a palette (i.e. 16 and 256 color modes). In HiColor modes each pixel on the frame buffer is stored as a double byte (int) which encodes the RGB values like this: |<---- 16 bits ---->| |1|<-5->|<-5->|<-5->| x RRRRR GGGGG BBBBB MSB-^ ^- LSB x = not used in 32k modes. MSB = Most significant bit. LSB = Least significant bit. As you can see, in 32k color modes only 15 bits are actually used. Look towards the end for an explanation of 64k color modes. Take a look at the prototype of PenColor(): void PenColor (int mwCOLOR); Notice that it takes an int? In the HiColor modes the number that you pass to PenColor will be the actual RGB value used to draw with. Let's pick a random color, like 5120 for an example. x Red Green Blue 0 00101 00000 00000 = 5120 decimal So PenColor(5120) is a shade of red. Going back to our original example, PenColor(2) is: x Red Green Blue 0 00000 00000 00010 = 2 decimal which is a very dim shade of blue. In fact, one of the symptoms of using HiColor modes by accident is that all your menus turn shades of blue. Take a look at what happens when you use the standard definitions for colors in a HiColor mode: #define White 15 PenColor (White); which is interpreted as: x Red Green Blue 0 00000 00000 01111 = 15 decimal As you can see, PenColor (White) is really 50% blue in a HiColor mode. What you _can_ do instead is define the following: #define hcBlack 0x0000 #define hcBlue 0x000F #define hcGreen 0x01E0 #define hcCyan 0x01EF #define hcRed 0x3C00 #define hcMagenta 0x3C0F #define hcBrown 0x3DE0 #define hcLtGray 0x3DEF #define hcGray 0x4210 #define hcLtBlue 0x001F #define hcLtGreen 0x03E0 #define hcLtCyan 0x03FF #define hcLtRed 0x7C00 #define hcLtMagenta 0x7C1F #define hcYellow 0x7FE0 #define hcWhite 0x7FFF and use PenColor() with these constants instead when you are in 16 bit per pixel mode. By the way, in 64k color modes Green gets the extra bit: |<--- 16 bits ---->| |<-5->|<-6-->|<-5->| RRRRR GGGGGG BBBBB MSB-^ ^- LSB but don't be fooled, Green gets an extra bit for a finer color resolution, but it's still only as bright as Red or green. Grey Scales ====================================================================== In order for colors to be true shades of grey the following must be true: Red = Green = Blue Because of this the number of greys is limited to the number of bits of the smallest gun register. So in VGA mode, 6 bits is your limit, or 64 grey scales. In 32k or 64k color modes it's actually less than that, it's only 5 bits, or 32 grey colors. There are some cards out which have 8 bit per gun DAC's, which allow true 256 color grey scale. Usually these are the ATI graphics cards, and of course the 24 bit per pixel color cards.