/ ************************************************** ********************** /
This article is purely translator to learn, do not use any it. Translator respects all the powers owned by the original author!
Reprint, please tell, e-mail: LinuxSunshen@163.com
/ ************************************************** ********************** /
16-bit Pixels
By Sam Christiansen
After learning DirectX, I decided that I should learn about 16-bit Surfaces more deeply, more precisely, should be a routine to plot a pixel. After some search, I found two different from different. Angle helps me understand the article about 16-bit Pixels foundation. As a reference, the first article is written by the Chris Barnes of Angelic-coders.com, the title is "16 bit pixel plotting", the second is written by Hugh Hunkin, title "16 Bit with DirectDraw". I am very grateful to Mr. Barnes and Mr. Hunkin, thank you for allowing me to use their source code in this article. The reason I decided to write this new article about 16-bit Pixels, is Because I found that Mr. Barnes and Mr. Hunkin are very easy to understand.
Pixel Formats
First of all, I have to briefly describe the 16-bit DirectDraw Surfaces. Each 16-bit Pixel on the Surface has RED (red), Green (green), Blue (blue) three properties (Value), because 16 cannot be 3 3. The most common method is to divide pixel information into a format of 5-6-5. This means that red value is the top 5 (BIT), followed by 6 green values, The last 5 is blue value. Use 5-6-5 format, we can get 65536 (2 ^ 16) different colors .we Have 32 Shades of Red, 64 Shades of Green, And 32 Shades of Blue. If 5 The -6-5 format does not exist, things may become easier. No matter what, we have to face the existence of different pixel formats.
A Word About Bitmasks and Shifting
Many readers may already know Bitmask and Shifting. If so, skip the following part. If you feel doubtful or don't know if BitMask, please look at it. A bitmask is a variable (Variable), it makes us Our 16-bit values are extracted from the relevant part of red, green, and blue value. We use the logical operator (or (|) and and (&)) by a new part of the color value by the two variables. Variables. For example, if we have a 5-6-5 color value arrangements:
Red: 5 Bits, 00011Green: 6 bits, 001011BLUE: 5 BITS, 00101
It is a format that combines them together.
0001 1001 0110 0101
(Note the spacing is just to make it uasier to read)
They look very confused, we can see where the color value is. But how do we extract them? Right, this is the place where Bitmask works. Because the red value is the top 5, so we use the following binary BINARY NUMBER
1111 1000 0000 000 00
Logical and (and) operations can extract 5 bits representing the red value, see the following:
0001 1001 0110 0101 & 1111 1000 0000 0000 --------------------- 0001 1000 0000 0000
Now we can see that the 16-bit value is clearly included in the red value we want, but you see it, its location is not correct. If we read this value now, it will not be the 1 to we hope to get The value between 31. We also have to move it to the right place in the right side with shift operators (>> or <<). You see 11 0 on the right side of our red value, below: 0001 1000 0000 0000 >> 11 = 0000 0000 000011
In this way, we get our red value, we can read him. The following code is what we want:
// suppose "Pixel" Contains the value AbovebyTe Red; Red = ((Pixel & 0xF800) >> 11);
Now the variable RED gets the red value in the variable Pixel. Please pay attention to our BitMask's value, 0xF800 is a hexadecimal number. We don't have to write the nasty 11 0. ;-)
In this section we have to pay attention to: We can use BitMask to extract our pixel value. The relevant source code is shown.
How do we find out the pixel format?
Chris Barnes recommended a getRGB16 function he wrote in his article. I modified this function to make it easier to understand. Basically, this function process takes a DirectDraw Surface as an input and call DirectDraw function getSurfaceDesc () Get a SURFACE description information and return the value of the image format. An important point of attention: The following code process assumes the structure of the image is red-green-blue format. Of course, many video display cards are using RGB format, but It is also possible to use other forms of RGB combination (such as BGR, GRB, BRG, etc.). If you want to make the following code can work 100% under different video display cards, you must modify getRGB16 () Functions and plot_pixel () functions for them.
Here is my getRGB16 function:
// you need this struct for the getrgb16 proc // note: you could even yank the bitmask variables out of this // if you find you are not using them in any functions of your owntypedef struct {DWORD dwRBitMask, dwGBitMask, dwBBitMask; RGBQUAD Position; // RGBQUAD is a data structure included with MSVC 5.0} RGB16; BOOL GetRGB16 (LPDIRECTDRAWSURFACE Surface, RGB16 * rgb16) {DDSURFACEDESC ddsd; // get a surface description ddsd.dwSize = sizeof (ddsd); ddsd. dwFlags = DDSD_PIXELFORMAT; if (! Surface-> GetSurfaceDesc (& ddsd) = DD_OK) return FALSE; // will increment r, g, or b for each 1 in it's bitmask, which will give // us the number of bits used for each Color char R = 0, g = 0, b = 0; for (int N = 1; n <65536; n << = 1) {if (ddsd.ddpfpixelformat.dwrbitmask & n) R; if (DDSD. Ddpfpixelformat.dwrbitmask & n) g; if (ddsd.ddpfpixelformat.dwrbitmask & n) b;} // this is the part ass assumes t HE FORMAT IS RGB rgb16-> dwRBitMask = ddsd.ddpfPixelFormat.dwRBitMask; rgb16-> Position.rgbRed = g b; rgb16-> dwGBitMask = ddsd.ddpfPixelFormat.dwGBitMask; rgb16-> Position.rgbGreen = b; rgb16-> dwBBitMask = ddsd.ddpfpixelformat.dwbbitmask; rgb16-> position.rgbblue = 0; return true;} // getrbg16 Now we get our format, the following is my PLOT_PIXEL function:
// Must have the surface locked, pass the surface description // that gets returned from the lock callvoid PlotRGB (int x, int y, int r, int g, int b, DDSURFACEDESC * ddsd, RGB16 * rgb16) {WORD Pixel; Pixel = (r << rgb16-> position.rgbred) | (g << rgb16-> position.rgbgreen) | (b); // overce again, assuming format is RGB WORD * PIXELS = (word *) DDSD-> L 23; dword pitch; pixels [y * pitch x] = Pixel;} This Plotpixel function assumes dwwidth equal to Pitch of the Surface. Barnes Mr. Barnes use DWORD PITCH = DDSD-> LPITCH >> 1;
Instead
DWORD PITCH = DDSD-> DWWIDTH;
To extract any value of the Surface we want, I think dwwidth is easier to understand in this example. When you use this example, you must remember!
Optimizations?
(Untrained .................)