DirectX study notes (2)
Happyfire 2002/8/11
How to talk to the surface to the surface, including the display palette, set the palette to the surface, transparent color, page loss, etc.
2. Use DirectDraw map
Let us recall the contents of the next time. In order to initialize DirectDraw, we first created a DirectDraw object, then
Set collaboration mode (full screen exclusive), set the display mode, then create the main surface, extract the background buffer surface pointer. At this time
Operation on the surface, then FLIP is displayed on the front desk. Release all DirectDraw objects before the end of the program. Ok, let's talk now.
Sample to the background surface map, that is, let the screen display pictures.
Step 1: Create a remote surface surface
The surface of the remote screen is the surface you can't see forever (so-called remote screen), which is usually used to store bitmaps. The usual practice is to remove the surface surface
The bitmap is attached to the background surface with a BLT method, and the background surface is re-flip to the front surface. Take a look at its creation method:
// Declare to store the display surface surface of the image (declared for global variable)
LPDIRECTDRAWSURFACE LPDDSPIC;
/ / Create a deputy surface surface of the saved image in InItDDraw ()
DDSD.DWFLAGS = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
DDSD.DDSCAPS.DWCAPS = DDSCAPS_OFFSCREENPLAIN
DDSD.DWHEIGHT = 480;
Ddsd.dwwidth = 640;
IF (LPDD-> CreateSurface (& DDSD, & LPDDSPIC, NULL)! = DD_OK)
Return False;
First, a surface is required to populate the DDSurfaceDesc surface describe the structure. DWFLAGS fills DDSD_CAPS indicates that the DDSCAPS domain is valid.
DDSD_HEIGHT and DDSD_WIDTH indicate the size of the page to specify. DDSCAPS.DWCAPS fills DDSCAPS_OFFSCREENPLAIN to create
It is from the surface of the screen. Dwheight and DWWidth are in size in size, and the unit is pixel. Then you can use the DirectDraw object's CreateSurface
Method Creates LPDDSPIC. Note that the third parameter of CreateSurface must be filled with NULL, which will allow compatibility with future COM collection features.
The entire creation process is very similar to the creation of the main surface, just the fill of DDSD. Talk later about the size of the surface surface.
In DirectX 5.0, the maximum value of the width of the slave surface cannot be exceeded from the width of the main surface. Start from DirectX 5.0, you
You can create any width remote page, as long as your memory and memory are large enough. By default, the left surface is created in the memory, but if
Not enough, it will be placed in memory, of course, you can specify only create a surface in the memory (available in DDSCAPS)
Contains DDSCAPS_SYSTEMMORY or DDSCAPS_VIDEMEMORY flags to clearly indicate where you want to put the surface), if
In this case, when the surface is too large and the memory is exceeded, it will create failed.
In addition, the pixel format of the off-screen surface (which can be simply understood as a few digits) is the same as the main surface, of course
You can also create a remote surface surface that is different from the main surface. However, in this case, the off-screen surface will be restricted to the system memory. specific
It is a bit annoying, you can check the manual, :).
Step 2: Read the palette and set up
Our main surface is set based on a palette (8-bit color depth). A palette-based surface is a collection of numbers,
Each of these numbers represent a pixel. Every number of values correspond to items in a color table, telling DirectDraw
What color is used for this pixel. This table is a palette (Palette). Using the palette is to try to reduce the demand for the memory, it uses one
Color Index to represent the color of each pixel point instead of directly with red, green, blue three-base color luminance to determine the color of each pixel point.
The palette contains several color indexes and the true color values corresponding to the index. The color index of the palette is mainly used in depth of 4 or 8. To be on the surface
Normal display image must set the palette of the surface to the palette of the image. As of the following code segment:
// Declare the palette object (actually the type of pointer, let's say this, all the objects mentioned above)
LPDIRECTDRAWPALETTE LPDDPAL;
// Set the palette from the bitmap
LPDDPAL = DDLOADPALETTE (LPDD, SZBITMAP);
IF (LPDDPAL)
LPDDSPRIMARY-> SetPalette (LPDDPAL);
Else
Return False;
DDLoadPalette is a function in ddutil.cpp, and HappyFire is not understanding. It is used as an initiator to use it.
Step 3: Read bitmap files into the screen that has been created
This step we implements a function DDLoadBitmap in DirectDraw Apis, and the specific usage is:
LPDDSPIC = DDLOADBITMAP (LPDD, SZBITMAP, 0, 0); // szbitmap is a bitmap file name, such as "./pic//background.bmp"
This step using DDLoadBitmap is very simple, but you have to add DDUTIL.CPP and DDUTIL.H to the project. You can have a look
The implementation of this function in ddutil.cpp, which calls the API LoadImage for Windows, and used as a DirectDraw object that is passed.
Created a surface and returned its pointer.
Step 4: Use the blit method to transfer the images on the surface of the screen to the background buffer
What is BLIT? Bit Block Transfer (Bit Block Transfer), the data blocks in memory are transferred from one place to another. DirectDraw
Two methods, BLT and BLTFAST are provided. The BLT is powerful, and the BLTFAST speed is faster. Here we don't discuss BLT first, only BLTFAST. See how to implement:
Rect rcRect;
RcRect.Left = 0;
RcRect.top = 0;
RcRect.Right = 640;
RcRect.bottom = 480;
LPDDSBACK-> BLTFAST (0, 0, LPDDSPIC, & RCRECT, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
RECT is the rectangular structure of Windows (so to include Windows.h), the RcRect This rectangle is used to determine which source surface (here is the surface of the surface)
An area is to be transferred to the target surface (here is the background buffer surface). The first two parameters of Bltfast are two DWORD values that represent the coordinates X and Y of a point on the target surface, which determines the location where the passed graphics is located on the target surface. You can change the effect of x, y, and rcRect.
The last parameter is the type of transmission:
DDBLTFAST_DESTCOLORKEY
Specifies the transparent bit block transfer, using the key color of the target surface.
DDBLTFAST_NOCOLORKEY
Specifies a normal replication, without a transparent component.
DDBLTFAST_SRCCOLORKEY
Specifies the key colors that perform a transparent bit block transfer and use the source surface.
DDBLTFAST_WAIT
If the bit block transmitter is busy, delay the sending of the DDERR_WASSTILLDRAWING message until the bit block transmitter is ready to return or other errors.
Take a look at this color key, this is very useful! The so-called key colors, that is, the transparent color we said, if a color is specified on the source surface,
So in the blit operation, it will be transparent to the area with this color and will not be transferred to the target page. In this case, although it is transmitted
The rectangle, but the portion of the key colors is not transmitted, thereby appearance, such as a wizard.
Of course, you must first set key colors for a surface. In InITDDRAW, we use DDSETCOLORKEY (LPDDSPIC, RGB (255, 0, 255));
Create a good pair of LPDDSPICs set the key colors of the purple colors. You can draw a wizard in the picture, then use a purple part of all nonvulsions
filling. The last parameter of Bltfast is then set to DDBLTFAST_SRCCOLORKEY. This is the way to pass the past is a wizard.
With DDBLTFAST_DESTCOLORKEY, you can set key colors for the target surface. It is different that the color on the target surface can be covered by key colors.
dyeing.
Finally, the difference between the target surface and the original surface. In fact, they are all relative. Call BLTFAST as the target surface, as the source surface of the parameters. General
Usage, the background surface calls BLTFAST, the parameter is the slave surface.
The problem of the map is so much, in fact, it is quite very much. There is also a 16-bit, 24-bit, 32-bit RGB format of non-palette mode, and 16-bit RGB corresponds to
Different graphics cards have 555,565 models. But we are beginners, these things ... :) to be studied. (If you are really generous to make a game, huh,
Prepare the compilation, you will have to deal with the MMX processor's instructions.)
Finally, what is the fourth step is to be placed in mainloop, so that it keeps the BLT and then flip, if you design a key to different maps in the program and change
The location of the map can be made, and the basic principle is like this.
Three. Talking about the treatment of surface loss
If your program cuts out with Alt Tab from full screen mode, then cut back, you may find that the picture is gone. Because it is representative page memory
The DirectDrawSurface object is not released, the page memory associated with the object will be released. When a DirectDrawSurface object is lost
When the page memory, many of its functions will return DDERR_SURFACELOST and do not perform any other operations. Let's take a look at this piece:
While (1) {
HRST = LPDDSPRIMARY-> FLIP (NULL, 0);
IF (HRST == DD_OK)
Break; if (hrst == DDERR_SURFACELOST) {
IF (RestoreAllDDS ()! = DD_OK)
Break;
}
IF (HRST! = DDERR_WASSTILLDRAWING) {
Break;
}
}
Did not mention the possibility of FLIP in FLIP, the above piece is a solution. If FLIP returns DDERR_WASSTILDRAWING, it is due to the last FLIP
The operation has not been completed (the FLIP instruction has been issued, but DirectX has not completed the operation), we can only make the While loop until
HRST! = DDERR_WASSTILLDRAWING. If FLIP returns DD_OK, that means that the FLIP operation is complete, you can go out. If FLIP returns
DDERR_SURFACELOST, indicating that the surface failed, when we need to handle it. See how my restorealds () function works:
HRESULT RESTOREALLDDS (VOID)
{
HRESULT HRST;
HRST = LPDDSPRIMARY-> restore ();
IF (HRST)
HRST = LPDDSBACK-> restore ();
IF (HRST)
HRST = LPDDSPIC-> Restore ();
DDRELOADBITMAP (LPDDSPIC, SZBITMAP);
Return HRST;
}
In this function, we call the main surface, the background surface, the Restore method of the slave surface. Restore methods can be re-re-filed for these lost memory
Allocate memory and contact these memory with the DirectDrawSurface object. However, reconstructing memory does not re-emerge image that previously exists on this page,
Therefore, after calling the RESTORE function reconstruction, you must re-draw all the images. Here I use the DDRELOADBITMAP function, this function is also
DDUTIL.CPP. It should be noted that if DDLoadBitmap is not available! You can look at the implementation of these two functions, compare it.