DirectDraw 学习:

 一、创建Primary Surface

Primary Surface是当前可视的设备表面,它通过DDSAPS_PRIMARYSURFACE属性来标识。对于每一个DirectDraw对象,你只能拥有一个Primary Surface。

创建Primary Surface时要注意,尺寸和像素格式都隐性地匹配了当前的显示模式,所以,这里就不需要你去设置这些了;如果你一定要设置的话,程序将创建失败并返回DDERR_INVALIDPARAMS,即使你提供的信息与当前的显示模式相匹配。

下面这段代码展示了当创建primary surface时如何填充相应的 DDSURFACEDESC结构体成员的:

1 DDSURFACEDESC ddsd; 
2 ddsd.dwSize = sizeof(ddsd); //便于后续此结构体的扩展
3  
4 // Tell DirectDraw which members are valid. 
5 ddsd.dwFlags = DDSD_CAPS; 
6  
7 // Request a primary surface. 
8 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 


当你创建primary surface后,你就可以通过method( IDirectDrawSurface::GetSurfaceDesc)来获取此主surface的尺寸和像素格式等信息。

 

这里有必要说一下这个结构体DDSUFACEDESC,它呢是用来描述一张surface属性信息的,为什么首先要填充此结构体的大小呢?因为后续可能此结构体会增加成员也说不定,便于成员的扩充;而配置下面的那个dwFlags成员用来表明现在起作用的是那些成员用的。

 

二、创建离屏表面(Off-Screen Surface)

它就常用来缓存那些稍后将要位传到primary surface或者back buffer上面的bitmap图片用的。创建这种表面就需要明确的声明它的尺寸,这里一定要记得先设置成员dwFlags包含到DDSD_WIDTH 和 DDSD_HEIGHT,然后再相应的设置成员dwWidth 和 dwHeight .

默认DirectDraw创建的表面都用的是显存,除非不合适,才会使用系统内存,但是我们也可指明,这就要设置成员dwCapsDDSCAPS_SYSTEMMEMORY 和DDSCAPS_VIDEOMEMORY二者之一;

 1 //创建前的准备工作
 2 DDSURFACEDESC ddsd; 
 3 ddsd.dwSize = sizeof(ddsd); 
 4  
 5 // Tell DirectDraw which members are valid. 
 6 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; 
 7  
 8 // Request a simple off-screen surface, sized 
 9 // 100 by 100 pixels. 
10 //
11 // (This assumes that the off-screen surface that is about 
12 // to be created will match the pixel format of the 
13 // primary surface.)它这里的假设分辨率是和primary surface的像素格式相匹配的
14 ddsd.dwHeight = 100; 
15 ddsd.dwWidth = 100; 

也可以不相匹配,但是有一个缺点:你使用系统内存时将被限制;

 1 //这里就是在一个显示模式不是8bit每像素的设备上创建一个8-bit调色板
 2 //表面所要做的准备工作
 3 memset(&ddsd, 0, sizeof(ddsd));
 4 ddsd.dwSize  = sizeof(ddsd);
 5 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
 6 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
 7 ddsd.dwHeight = 100;
 8 ddsd.dwWidth  = 100;
 9 ddsd.ddpfPixelFormat.dwSize  = sizeof(DDPIXELFORMAT);
10 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
11  
12 // Set the bit depth for an 8-bit surface, but DO NOT 
13 // specify any RGB mask values. The masks must be zero
14 // for a palettized surface.
15 ddsd.ddpfPixelFormat.dwRGBBitCount = 8;

 

三、复合表面和翻转链(Complex Surfaces and Flipping Chains)

何为复合表面?通过单一调用CreateSurface创建的一系列表面就是复合表面。怎么说呢,举个例吧

1     int i = 0;
2     do {
3         ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];
4         hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
5     } while (hRet != DD_OK && (++i < PF_TABLE_SIZE));

上面呢就是基于不用像素格式创建了多个surface的实例,这样创建出来的就是complex surfaces;

而且使用CreateSurface时一旦指定DDSCAPS_FLIP,除了你明确指定,不然DirectDraw会隐式创建一到多个表面;

你可以把复合表面就当作一张表面来处理,所以处理起来也没什么特别之处;

那现在来说到翻转链,复合表面就是被用于翻转链的。通常一个primary surface和一到多个back buffers来组成一条翻转链。而且有DDSCAPS_FLIP标识创建出来的表面就表明了它也是翻转链的一组成部分;

 1 //这里是创建一个主表面翻转链时先要配置的参数
 2 DDSURFACEDESC ddsd; 
 3 ddsd.dwSize = sizeof(ddsd); 
 4  
 5 // Tell DirectDraw which members are valid. 
 6 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
 7  
 8 // Request a primary surface with a single 
 9 // back buffer 
10 ddsd.ddsCaps.dwCaps = DDSCAPS_FLIP | 
11 DDSCAPS_PRIMARYSURFACE; 
12 ddsd.dwBackBufferCount = 1; 

创建成功后就可以翻转了(primary surface和back buffer之间):

1 hRet = g_pDDSPrimary->Flip(NULL, 0);

如果上面的ddsd.dwBackBufferCount = 2;那么每调用一次上面的flip,就在这三个surface之间循环,这就是a triple-buffered flipping environment。下面要讲到。。。

 

四、Flipping Surfaces

这个就更有意思了。。。

posted on 2011-09-09 20:38  EmbeddedBoy_jsu_xtw  阅读(2040)  评论(0编辑  收藏  举报

导航