Fourth, using the overlay surface This example will use the DirectX SDK's MOSQUITO sample program to explain how to use DirectDraw and hardware support coverage surfaces in the program step by step. MOSQUITO uses the flip chain override the surface of the surface without bit blocks to the main surface to display the motion bitmap on the desktop. The MOSquito program adjusts the feature of the cover surface to accommodate hardware.
1. Creating a main surface To use the overlay surface, you must first initialize a major surface, the overlay surface will be displayed on the main surface. MOSQUITO creates a master surface with the following code: // Zero-Out The Structure and Set The DWSIZE Member. ZeromeMory (& DDSD, SIZEOF (DDSD)); DDSD.DWSIZE = SizeOf (DDSD);
. // Set flags and create a primary surface ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddrval = g_lpdd-> CreateSurface (& ddsd, & g_lpddsPrimary, NULL); DDSURFACEDESC initialized program configuration to be used, then set The appropriate logo calls the IDirectdraw2 :: CreateSurface method to create the main surface. In the call to the method, the first parameter is a pointer to the DDSurfaceDesc structure that will be created; the second parameter is a pointer to a variable, and if the call is successful, the variable will receive the pointer of the IDirectdrawSurface interface; third The parameter is set to NULL indicates that there is no COM collection.
2. After detecting the support of the overlay to initialize DirectDraw, you need to detect whether the device supports the cover surface. Because DirectDRAW cannot simulate overwritten, if the hardware does not support overwriting, you cannot continue the following work. You can get the ability to detect overlay support for hardware device drivers with iDirectDraw2 :: getCaps. After calling the method, check whether DWFlags members in the DDCaps structure contains the DDCaps_overlay flag. If there is, it indicates that support coverage, otherwise it will not be supported. The following code is part of the Mosquito program that shows how to detect hardware coverage support capabilities: Bool Areoverlayssupported () {DDCAPS Capsdrv; HRESULT DDRVAL;
// Get Driver Capabilities To Determine Overlay Support. ZerMemory (& CapsDRV); Capsdrv.dwsize = SizeOf (CapsDRV);
DDRVAL = g_lpdd-> getCaps (& CapsDRV, NULL); if (Failed (DDRVAL) RETURN FALSE;
// Does the driver support overlays in the current mode? // (Currently the DirectDraw emulation layer does not support overlays. // Overlay related APIs will fail without hardware support). If (! (CapsDrv.dwCaps & DDCAPS_OVERLAY)) return FALSE ;
Return True;} The program first calls the IDirectDraw2 :: getCaps method to get the ability to get the device driver. The first parameter is the address pointer of the DDCAPS structure; because the program does not need to shut down simulation information, the second parameter is set to NULL. After obtaining the driver's ability, the program uses logic "and" to check if the dwflags member contains the DDCaps_overlay flag. If not, the program returns FALSE indicates that failed. If so, returns True to indicate that the display device supports the cover surface. 3. Create an overlay surface If you know that the display device supports the overlay surface, you can create one. Since there is no specification that the device supports the standards that covers the surface, it is not expected to create a surface of any pixel format. Also, do not expect the first time to create a coverage surface will succeed. Therefore, it is necessary to prepare an attempt to create multiple creating until there is a work. The MOSQUITO program follows the principle of "Best Case to Worst Case" when you create a surface, first try to create a three buffer flip-flush complex coverage surface. If the attempt fails, the program changes the method to configure it with other universal rapid formats. The following code is the performance of this idea: ZeromeMory (& DDSDOVERLAY, SIZEOF (DDSDOVERLAY)); DDSDOVERLAY.DWSIZE = SizeOf (DDSDoverlay);
ddsdOverlay.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT; ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY; ddsdOverlay.dwWidth = 320; ddsdOverlay.dwHeight = 240; ddsdOverlay.dwBackBufferCount = 2;
// Try to create an overlay surface using one of the pixel formats in our // global list i = 0;. Do {ddsdOverlay.ddpfPixelFormat = g_ddpfOverlayFormats [i]; // Try to create the overlay surface ddrval = g_lpdd-> CreateSurface (& DDSDOVERLAY, & G_LPDDSOVERLAY, NULL);} WHILE (Failed (DDRVAL) && ( i
// We couldn't create an overlay surface. EXIT, RETURNING FAILURE. IF (Failed (DDRVAL)) Return False;} The above code is the logo and value of the DDSurfaceDesc structure reflects a single non-flip cover surface, then Create a surface through a loop in a pixel format. If the created surface is successful, the loop stops. If it is not successful, the program returns false indicates that the creation surface failed. After successfully created the overlay surface, the bitmap can be displayed in it.
4. Display the overlay surface can display it after the overlay surface is created. Typically, the hardware adds alignment constraints on the location and pixel format of the covered rectangle. In addition, it is also necessary to explain the minimum required tensile factor to successfully display the cover surface by adjusting the width of the destination rectangle. The MOSQUITO program is prepared and display the overlay surface as follows. 4.1: The minimum requirement display of the display is constrained in the display hardware when the overlay is displayed. You must take care of the overlay to satisfy these constraints. Information about these constraints can be obtained by calling the IDirectDraw2 :: getCaps method. The structure filling structure DDCAPS contains information about coverage and use constraints. Different hardware constraints are different, so you must always look at the flag contained in the DWFlags member to determine which constraint is. The MOSQUITO program begins to get hardware capabilities, and then use the minimum tensile factor, as shown below: // Get Driver Capabilities DDRVAL = G_LPDD-> GetCaps (& CapsDRV, NULL); if (Failed (DDRVAL) RETURN FALSE ;
.? // Check the minimum stretch and set the local variable accordingly if (capsDrv.dwCaps & DDCAPS_OVERLAYSTRETCH) uStretchFactor1000 = (capsDrv.dwMinOverlayStretch> 1000) capsDrv.dwMinOverlayStretch: 1000; else uStretchFactor1000 = 1000; The above code calls IDirectDraw2 :: GetCaps Methods The ability to get hardware. In this example, the first parameter is a pointer to the DDCAPS structure; the second parameter is NULL, indicating that there is no need to obtain information about simulation. The program retains the minimum tensile factor in a temporary variable for use. If the tensile factor reported in the driver is greater than 1000, it indicates that the driver requires all the destination rectangles to stretch along the direction of the X axis. For example, if the tensile factor is 1.3, the source rectangle is 320 pixels, and the destination rectangle must have at least 416 (320 x 1.3 = 416) pixels wide. If the tensile factor reported in the driver is less than 1000, it indicates that the driver can display smaller coverage than the source rectangle, but cannot be extended. The following description of the driver code size measuring alignment constraint value: // Grab any alignment restrictions and set the local variables acordingly uSrcSizeAlign = (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) capsDrv.dwAlignSizeSrc:.? 0; uDestSizeAlign = (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC)? Capsdrv.dwalignsizedest: 0; More temporary variables are used to save the size alignment constraints obtained from DwalIgnsizesRC and Dwalignsizedest members. These values provide information about the pixel width alignment constraint, and need to be used in the later set source rectangle and the destination rectangle. The source rectangles and destination rectangles must be multiple multiple of these values. Finally, the program determines the value of the destination rectangular boundary alignment: // set the "Destination Position Alignment" Global So We Won't Have to // Keep Calling getCaps () Every Time We move The overlay Surface. If (Capsdrv.dwcaps & DDCAPS_ALIGNBOUNDARYDEST) g_dwOverlayXPositionAlignment = capsDrv.dwAlignBoundaryDest; else g_dwOverlayXPositionAlignment = 0; the above code uses a global variable to hold the value of the destination rectangle boundary constraints, the value is from a member of the dwAlignBoundaryDest come again when the cover is placed after the program Will be used. You must set the X coordinates in the upper left corner of the destination rectangle to align in the pixel format. That is, if the value is 4, it can only specify the destination rectangle of the X coordinates of the upper left corner of 0, 4, 8, 12. The MOSQUITO program is first displayed at 0,0, so it is not necessary to obtain constraint information before the first display overlay is displayed. But because the implementation of different applications may be different, you may need to check this information before displaying overrides to adjust the destination rectangle.
2. Setting the source rectangle and the destination rectangle After obtaining the overlay constraint of the driver, the value of the source rectangle and the destination rectangle should be set to ensure that the overlay can be displayed correctly. The following code sets the feature of the source rectangle: // set initial value in the source Rect. Rs.Left = 0; rs.top = 0; rs.right = 320; rs.bottom = 240; // Apply Size Alignment Restrictions, if Necessary. if (Capsdrv.dwcaps & DDCAPS_ALIGNSIZESRC & DDCSIGN) rs.right - = rs.right% usrcsizEalign; the above code sets the initial value of the entire surface size. If the device driver requires size alignment, the program adjusts the source rectangle to ensure. The program is adjusted to the width of the source rectangle, which is less than the initial value, because if it is not completely recreated, it is not possible to extend the width. After setting the source rectangle, you need to set and adjust the size of the destination rectangle. This process needs a little more work because the destination rectangle may need to be stretched first to comply with the size alignment constraint. The following code sets and adjusts the size of the destination rectangle according to the minimum stretching factor: // set up the destination review, starting with the source rect Dimensions INSTEAD OF THE SURFACE DIMENSIONS INSTETEAD OF THE SURFACE DIMENSIONS INSTED of THE SURFACE DIMENSIONS INSTER Differ. rd.Left = 0; rd.top = 0; rd.right = (rs.right * uStretchFactor1000 999) / 1000; // (Add 999 Avoids Integer Truncation Problems.)
// (this isn't Required by DDRAW, But We'll Stretch The /// Height, TOO, TO Maintain Aspect Ratio). Rd.Bottom = rs.bottom * uStretchFactor1000 / 1000; The front code first sets the top left of the objective rectangle The angular position, then set the width of the destination rectangle according to the minimum tensile factor. When adjusting the rectangle according to the tensile factor, the payment is added in the product of the width and tensile factor, which is to avoid the interception of the integer, and the cutting of the integer causes the rectangle as the minimum tensile factor. The program also stretched the height of the rectangle after the stretch width. However, the stretching of the height is not necessary, here is just to maintain the phenomenon of distortion in order to maintain the growth rate of the bitmap. After the stretching rectangle, the program is adjusted to keep and sizes alignment constraints. The following is the corresponding code: // adjust the destination rect's width to comply with any imposed // alignment rest (Capsdrv.dwcaps & DDCAPS_ALIGNSISIZEDEST & D) UDESTSIAALIGN) RD.right = (int) ((RD.right UDestsizeAlign-1) / udestsizealign) * udestsizEalign; program detects the logo of hardware capabilities, check whether the driver is added alignment constraints. If so, the width of the increase in the rectangle is increased to satisfy the size alignment constraint. Here, the adjustment of the rectangle is extended its width without reducing its width, as the width may result in a small destination rectangle than the minimum tensile factor, thereby causing the display coverage surface failure. 3. When the cover surface is displayed, it can be displayed after setting the source rectangle and the destination rectangle. If the preparation date before the overlay is displayed correctly, the display coverage will be simple. Mosquito program with the following code to display the cover:? // Set the flags we'll send to UpdateOverlay dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; // Does the overlay hardware support source color keying // If so, we can hide the black background around The image. // this probably Won't work with yuv formats if (capsdrv.dwckeycaps & ddckeycaps_srcover) dwupdateflags | = DDOVER_KEYSRCOVERRIDE
// Create an overlay FX structure so we can specify a source color key // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag is not set ZeroMemory (& ovfx, sizeof (ovfx));.. Ovfx.dwSize = sizeof (ovfx);
Ovfx.dcksrccolorKey.dwcolorspaceLowValue = 0; // specify black as the color key ovfx.dcksrcolorty.dwcolorspacehighValue = 0;
. // Call UpdateOverlay () to displays the overlay on the screen ddrval = g_lpddsOverlay-> UpdateOverlay (& rs, g_lpddsPrimary, & rd, dwUpdateFlags, & ovfx); if (FAILED (ddrval)) return FALSE; program begins in temporary variable dwUpdateFlags in DDOVER_SHOW and DDOVER_DDFX flags indicate that the overlay is displayed for the first time, and the hardware should be done using the effect information contained in the DDOverLayFX structure. Then, the program checks the DDCAPS structure to determine if the override supports the source color Key. If so, the DDOVER_KEYSRCOVERRIDE flag is included in the dwupdateflags variable, and the program also sets the Color Key accordingly. After the preparation is completed, the program calls IDirectDrawSurface3 :: updateoverlay method to display overwriting. In the call to the method, the first parameter and the third parameter are the address that has been adjusted source rectangles and destination rectangles. The second parameter is to override the address of the main surface displayed thereon. The fourth parameter is a flag included in the DWUPDATEFLAGS variable placed in previously prepared. The fifth parameter is the address of the DDOVERLAYFX structure, and the members in this structure will match the same flag. If the hardware only supports a coverage surface and the surface is being used, the UpdateoverLay method will fail and return DDERR_OUTOFCAPS. In addition, it is possible that the minimum tensile factor of hardware report is too small. After the UpdateoverLay method fails, you need to try to reduce the width of the destination rectangle to cope with this possibility. However, this situation rarely occurs, but only simply returns an error message in Mosquito. 5. Update the overwritten display location Show After the cover is covered, it may sometimes do not need to operate the left left. However, some software also needs to reset override, change the display position override. The MOSQUITO program uses the iDirectdrawsurface3 :: setoverlayPosition method to reset override, the code is as follows: // set x and y-coordinates. IF (g_dwoverlayxpositionalignment) dwxaligned = g_noverlayxpos - g_noverlayXPOS% g_dwoverlayXPositionalignment; else dwxaligned = g_noverlayXPOS;
// Set the overlay to its new position ddrval = g_lpddsOverlay-> SetOverlayPosition (dwXAligned, g_nOverlayYPos);. If (ddrval == DDERR_SURFACELOST) {if (! RestoreAllSurfaces ()) return;} program begins aligned rectangular to meet any possible Destination rectangular boundary alignment constraint. When the program previously calls the IDirectdraw2 :: getCaps method, the global variable g_dwoverlayXPositionAlignment has been set to the value reported by DWALIGNBOUNDARYDEST members in the DDCAPS structure. If there is a destination rectangle constraint, the program adjusts the new X coordinate as a pixel accordingly. If you do not meet the requirements, the cover cannot be displayed. After completing the adjustment of the X coordinate, the program calls IDirectDrawSurface3 :: setoverlayPosition method Re-placed overwrites. The first parameter in the call is the aligned new X coordinate, the new Y coordinate of the second parameter. These values indicate a new location in the upper left corner. There is no need to get width and height information here, because DirectDraw has obtained information on the surface size when it starts with the idirectdrawsurface3 :: updateoverLay method. If the failure caused by a reset overlay surface caused by one or more surfaces, the MOSQUITO program calls an application-defined function to restore these surfaces and reload their bitmaps. Note that do not use the coordinates of the right and lower boundaries of the target surface. Because IdirectDraw2 :: SETOVERLAYPOSITION method does not execute shear feature, uses those who may cause the coordinates that can cause the target surface boundary to cause the call to fail, and return DDERR_INVALIDPSITION. 6. Hide overwriting surface If you no longer need an overlay surface or just want the overlay, you can set the appropriate flag to call the IDirectDrawSurface3 :: Updateoverlay method to hide the overlay surface. Mosquito cover the surface with the following code to hide and is ready to close the application: void DestroyOverlay () {if (g_lpddsOverlay) {// Use UpdateOverlay () with the DDOVER_HIDE flag to remove an overlay // from the display g_lpddsOverlay-> UpdateOverlay (NULL,. g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); g_lpddsOverlay-> Release (); g_lpddsOverlay = NULL;}} when calling IDirectDrawSurface3 :: UpdateOverlay, the source and destination rectangles specify NULL, because the process does not require the cover to hide the source Rectangle and destination rectangles. Similarly, the fifth parameters are also designated as NULL because it does not use overlay. The second parameter is a pointer to the target surface. Finally, the program uses the DDOVER_HIDE flag in the fourth parameter to indicate that the overlay will be canceled from the viewport. After the program is hidden, it releases its IDirectdrawSurface3 interface and set the global variable to null to make it invalid. For MOSQUITO programs, overwriting is no longer needed. If you need to use it in the application, you just need to simply hide override, not to release it, and then redisplay it when you need it.