Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SSW_8_11.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
5 Мб
Скачать
☆

Step 4: Flipping the Surfaces. Flipping surfaces in the ddex2 sample is essentially the same process as that in the first example. Blitting from an Off-Screen Surface

The sample in Tutorial 2 (DDEX2) takes a bitmap and puts it in the back buffer, and then it flips between the back buffer and the primary buffer. This is not a very realistic approach to displaying bitmaps. The sample in this tutorial (DDEX3) expands on the capabilities of DDEX2 by including two off-screen buffers in which the two bitmaps—one for the even screen and one for the odd screen—are stored. It uses the IDirectDrawSurface::BltFast method to copy the contents of an off-screen surface to the back buffer, and then it flips the buffers and copies the next off-screen surface to the back buffer.

The new functionality demonstrated in considered below is shown in the following steps:

  • Step 1: Creating the Off-Screen Surfaces

  • Step 2: Loading the Bitmaps to the Off-Screen Surfaces

  • Step 3: Blitting the Off-Screen Surfaces to the Back Buffer

Step 1: Creating the Off-Screen Surfaces. The following code is added to the doInit function in ddex3 to create the two off-screen buffers:

// Create an offscreen bitmap.

ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;

ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

ddsd.dwHeight = 480;

ddsd.dwWidth = 640;

ddrval = lpDD->CreateSurface(&ddsd, &lpDDSOne, NULL);

if(ddrval != DD_OK)

{ return initFail(hwnd);

}

// Create another offscreen bitmap.

ddrval = lpDD->CreateSurface(&ddsd, &lpDDSTwo, NULL);

if(ddrval != DD_OK)

{ return initFail(hwnd);

}

The dwFlags member specifies that the application will use the DDSCAPS structure, and it will set the height and width of the buffer. The surface will be an off-screen plain buffer, as indicated by the DDSCAPS_OFFSCREEN flag set in the DDSCAPS structure. The height and the width are set as 480 and 640, respectively, in the DDSURFACEDESC structure. The surface is then created by using the IDirectDraw::CreateSurface method.

Because both of the off-screen plain buffers are the same size, the only requirement for creating the second buffer is to call IDirectDraw::CreateSurface again with a different pointer name.

You can also specifically request that the off-screen buffer be placed in system memory or display memory by setting either the DDSCAPS_SYSTEMMEMORY or DDSCAPS_VIDEOMEMORY capability in the DDSCAPS structure. By saving the bitmaps in display memory, you can increase the speed of the transfers between the off-screen surfaces and the back buffer. This will become more important when using bitmap animation. However, if you specify DDSCAPS_VIDEOMEMORY for the off-screen buffer and not enough display memory is available to hold the entire bitmap, a DDERR_OUTOFVIDEOMEMORY error value will be returned when you attempt to create the surface.

Step 2: Loading the Bitmaps to the Off-Screen Surfaces. After the two off-screen surfaces are created, DDEX3 uses the InitSurfaces function to load the bitmaps from the Frntback.bmp file onto the surfaces. The InitSurfaces function uses the DDCopyBitmap function located in Ddutil.cpp to load both of the bitmaps, as shown in the following example:

// Load the bitmap resource.

hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap,

IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);

if (hbm == NULL)

return FALSE;

DDCopyBitmap(lpDDSOne, hbm, 0, 0, 640, 480);

DDCopyBitmap(lpDDSTwo, hbm, 0, 480, 640, 480);

DeleteObject(hbm);

return TRUE;

If you look at the Frntback.bmp file in Microsoft Paint or another drawing application, you can see that the bitmap consists of two screens, one on top of the other. The DDCopyBitmap function breaks the bitmap in two at the point where the screens meet. In addition, it loads the first bitmap into the first off-screen surface (lpDDSOne) and the second bitmap into the second off-screen surface (lpDDSTwo).

Step 3: Blitting the Off-Screen Surfaces to the Back Buffer. The WM_TIMER message contains the code for writing to and flipping surfaces. In the case of DDEX3, it contains the following code to select the proper off-screen surface and to blit it to the back buffer:

rcRect.left = 0;

rcRect.top = 0;

rcRect.right = 640;

rcRect.bottom = 480;

if(phase)

{ pdds = lpDDSTwo;

phase = 0;

}

else

{ pdds = lpDDSOne;

phase = 1;

}

while(1)

{ ddrval = lpDDSBack->BltFast(0, 0, pdds, &rcRect, FALSE);

if(ddrval == DD_OK)

{

break;

}

The phase variable determines which off-screen surface will be blitted to the back buffer. The IDirectDrawSurface::BltFast method is then called to blit the selected off-screen surface onto the back buffer, starting at position (0, 0), the upper-left corner. The rcRect parameter points to the RECT structure that defines the upper-left and lower-right corners of the off-screen surface that will be blitted from. The last parameter is set to FALSE (or 0), indicating that no specific transfer flags are used.

Depending on the requirements of your application, you could use either the IDirectDrawSurface::Blt method or the IDirectDrawSurface::BltFast method to blit from the off-screen buffer. If you are performing a blit from an off-screen plain buffer that is in display memory, you should use IDirectDrawSurface::BltFast. Although you will not gain speed on systems that use hardware blitters on their display adapters, the blit will take about 10 percent less time on systems that use hardware emulation to perform the blit. Because of this, you should use IDirectDrawSurface::BltFast for all display operations that blit from display memory to display memory. If you are blitting from system memory or require special hardware flags, however, you have to use IDirectDrawSurface::Blt.

After the off-screen surface is loaded in the back buffer, the back buffer and the primary surface are flipped in much the same way as shown in the previous tutorials.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]