上一章中说了可以用16位的色彩深度,但是16位的色彩深度的数据表示模式可以有两种:Alpha.5.5.5(or X.5.5.5) 和 5.6.5(这是16位色彩最常用的)。对于使用哪种16位的色彩模式这个是由硬件决定的,我们不能决定。但是我们可以查询,然后按照硬件支持的模式来填写。我们可以调用方法IDIRECTDRAWSURFACE7::GetPixelFormat(),同时这个函数需要一个LPDDPIXELFORMAT的结构,其中的dwFlags 和 dwRGBBitCount成员记录着像素格式(8位索引或者RGB模式)示例代码如下:DDPIXELFORMAT ddpixel;memset(&ddpixel, 0, sizeof(ddpixel) );ddpixel.dwSize = sizeof(ddpixel);lpddsprimary->GetPixelFormat(&ddpixel);if (ddpixel.dwFlags & DDPF_RGB) // RGB Mode{switch(ddpixel.dwRGBBitCount)
{
case 15: // 5.5.5
break;
case 16: // 5.6.5
break;
case 24:
break;
case 32:
break;
default:
break;
}}else // ddpixel.dwFlags & DDPF_PALETTEINDEXED8 == TRUE{
}对于32位的模式也可以用以上判断代码,并且将填写颜色的代码写在case 32:里面。32位色彩的两种模式为:Alpha.8.8.8 和 X.8.8.8。对于后面的一种,建议将X的8位置为0。
现在我们已经可以对表面进行修改了。这样也就是通过视频控制器直接将每一帧都光栅化。这对于静态图像来说已经很好了。但是如果是动画呢?可能就不是非常平滑。我们就需要使用双缓冲技术。即先申请一个和主表面同样大小的数组(或者数据块),将色彩数据填写进这个数组中,最后再复制进加锁的表面中。在复制的时候我们需要注意表面是否线形的问题。如果是线性的,那么我们可以把整个数据块一并复制;如果不是,那么我们只能一行行来复制。(其中这种技术我们并不会真正的用到,除非数据块很小。因为DirectDraw提供给我们更好的动态表面)
离屏表面一——后备缓冲。创建后备缓冲的目的是用DirectDraw的方式来实现对双缓冲功能的仿真。如果创建了DirectDraw后备缓冲(通常在VRAM中),读写会非常快。你可以将它和主表面进行页面切换,这比双缓冲方案下所需做的内存复制要快得多。创建一个关联有后备缓冲的主表面步骤:
首先,你要将DDSD_BACKBUFFERCOUNT加到dwFlags标志字段,向DirectDraw表明DDSURFACEDESC2结构的dwBackBufferCount字段有效,其中含有后备缓冲的数目。 其次,将控制标志DDSCAPS_COMPLEX 和 DDSCAPS_FLIP加到DDSURFACEDESC2结构的特性描述字段ddsCaps.dwCaps上。 最后,像通常一样创建主表面。从它调用IDIRECTDRAWSURFACE7::GetAttachedSurface() 以得到后备缓冲。示例代码:
LPDIRECTDRAWSURFACE7 lpddsback;
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback);注意其中红色属性。
这样一来,以后只要每次都在后备缓冲绘图,然后调用Flip方法进行表面切换,就可以实现快速的翻页。
示例代码:
lpddsprimary->Flip(NULL, DDFLIP_WAIT);
需要注意两点,1.翻页总是由主表面执行的。2.翻页前主表面或者后备缓冲表面都必须解锁。