创建宽平面

DirectDraw允许在显存中创建一个比主平面更宽的屏下平面。但这只在显示设备支持得条件下才可用。

要检查是否支持宽平面,调用IDirectDraw4::GetCaps并查找在调用时的第一个DDCAPS 结构中的dwCaps2成员的DDCAPS2_WIDESURFACES标志。如果标志存在,你便可创建比主平面更宽的屏下平面。

如果你在DDCAPS2_WIDESURFACES标志不存在时试图在显存中创建一个宽平面, 尝试会失败并返回DDERR_INVALIDPARAMS。注意,如果尝试创建一个极端大的平面也可能失败, 即使驱动程序支持DDSAPS2_WIDESURFACES标志。

宽平面也在系统内存平面,视频端口平面及执行缓冲(Execute Buffer)中被支持。

创建委托内存平面

委托内存平面只不过是简单的DirectDrawSurface对象,使用系统内存, 你的程序已经用其来存放图象数据。创建该平面并不一样,但也没有很大区别, 它可以被需要在内存中要DirectDraw平面特性的程序来使用。

就象创建所有的平面,DirectDraw需要平面的尺度信息(通常基于像素)平面跨度信息 (通常基于字节),还有像素格式。不管怎样,不像创建其他类型的平面, 你无须告诉DirectDraw怎样创建平面,而告诉DirectDraw你是如何已经创建它的。 你设置这些特性,在调用IDirectDraw4::CreateSurface宏时在DDSURFACEDESC2结构中附上你已占用内存的地址。

委托内存平面工作起来就象普通的系统内存平面, 区别在于在不使用该平面后DirectDraw不会自动试图释放平面内存。释放占用内存是程序的责任。

以下例程演示你如何可以通过占用的内存来创建一个DIrectDrawSurface对象, 一个64' 64像素24-Bit RGB平面:

// For this example, g_lpDD4 is a valid IDirectDraw4 interface pointer.
// 在这个例子中,g_lpDD4是一个有效的IDirectDraw4界面的指针。
 
#define WIDTH  64 // in pixels 基于像素
#define HEIGHT 64
#define DEPTH  3  // in bytes (3bytes == 24 bits) 基于字节 (3个字节=24 Bits)
 
    HRESULT hr;
    LPVOID  lpSurface  = NULL;
    HLOCAL  hMemHandle = NULL;
    DDSURFACEDESC2 ddsd2;
    LPDIRECTDRAWSURFACE4 lpDDS4;
 
    // Allocate memory for a 64 by 64, 24-bit per pixel buffer.
    // 为64乘64,24位像素缓冲分配内存
    // REMEMBER: The application is responsible for freeing this
    //           buffer when it is no longer needed.
    // 记住:在不需要时应有程序来释放这个缓冲
    if (lpSurface = malloc((size_t)WIDTH*HEIGHT*DEPTH))
        ZeroMemory(lpSurface, (DWORD)WIDTH*HEIGHT*DEPTH);
    else
        return DDERR_OUTOFMEMORY;
 
    // Initialize the surface description.
    // 初始化平面信息
    ZeroMemory(&ddsd2, sizeof(DDSURFACEDESC2));
    ZeroMemory(&ddsd2.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
    ddsd2.dwSize = sizeof(ddsd2);
    ddsd2.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE |
                    DDSD_PITCH | DDSD_PIXELFORMAT;
    ddsd2.dwWidth = WIDTH;
    ddsd2.dwHeight= HEIGHT;
    ddsd2.lPitch  = (LONG)DEPTH * WIDTH;
    ddsd2.lpSurface = lpSurface;
 
    // Set up the pixel format for 24-bit RGB (8-8-8).
    // 为24-bit RGB(8-8-8)设置像素格式
    ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
    ddsd2.ddpfPixelFormat.dwFlags= DDPF_RGB;
    ddsd2.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8;
    ddsd2.ddpfPixelFormat.dwRBitMask    = 0x00FF0000;
    ddsd2.ddpfPixelFormat.dwGBitMask    = 0x0000FF00;
    ddsd2.ddpfPixelFormat.dwBBitMask    = 0x000000FF;
 
    // Create the surface
    // 创建平面
    hr = g_lpDD4->CreateSurface(&ddsd2, &lpDDS4, NULL);
    return hr;

切换平面(Flipping Surfaces)

任何DirectDraw的平面都能被建成为切换平面。 一个切换平面是由一些内存片被用来在前景缓冲及屏后缓冲中进行交换所组成。 (这个结构通常被归于切换链Flipping Chain)。通常,前景缓冲是主平面, 但也不一定一定要用主平面。

典型的,当你使用IDIrectDrawSurface4::Flip宏来进行一个切换操作, 主平面及屏后缓冲的平面内存指针被交换。切换就是交换显示设备用来联系内存的指针操作, 并不复制平面内存。(也有例外,就是当DirectDraw是在用模拟切换时, 它通过复制平面来完成该操作。只有在屏后缓冲无法装入显存或硬件不支持时DirectDraw 使用模拟切换)当一个切换链包含一个主平面及多于一个屏后缓冲,指针便在图形中循环切换, 就象以下说明:

Flip (4593字节)

其他附带于DirectDraw对象的平面,并不是切换链的一部分,在调用切换宏时不受影响。

记住,DirectDraw切换平面是通过改变DirectDrawSurface对象平面内存指针, 而不是改变对象本身。这意味着在往任何方案的屏后缓冲中移动信息, 你总是在使用同一个DirectDrawSurface对象---就是在创建切换链的那一个屏后缓冲。 相反,你始终通过调用前景平面的切换宏来进行切换操作。

当工作于可见的平面,如主平面切换链或一个可见的平面层的切换链, 切换宏是异步进行的,除非包含DDFLIP_WAIT标志。在这些可见的平面, 切换宏能在硬件实际进行操作前返回(因为硬件在没收到下一个垂直刷新指令时是不会进行切换的)。 当实际的操作进行前,在当前可见平面后的屏后缓冲不能通过调用IDirectDrawSurface4::Lock, IDirectDrawSurface4::Blt,IDirectDrawSurface4::BltFast或IDirectDrawSurface4::GetDC宏来被锁定, 移动。这些操作将失败并返回DDERR_WASSTILLDRAWING。不管怎样,如果你使用,三层缓冲 (Triple Buffer)方案,最后的缓冲仍然有效。


上篇|返回|下篇

Lucker 1999.4.17
E-Mail: fred_cai@kali.com.cn


云风工作室 制作