两个小时学会DirectDraw编程

2008-02-23 05:35:54来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

这并非哗众取宠, 通常学习一种电脑技术有两种方法. 一种是自己摸索, 在错误的方向上一错再错, 屡战屡败, 但是最后得道成功. 另一种是有人 或好的材料指导, 因而事半功倍, 在正确的方向上走了速成的捷径. 就象KFC 的鸡相同. 第一种学法能学出电脑天才, 因为所谓电脑高手, 其实就是排错试错的高手. 而第二种则出电脑专才. 这个两小时(?)的学习, 不能使您深入的掌控DD, 但是能够给您编制DD的框架. 能给您 一个起始点, 这个教程就算成功了.


DirectDraw编程需要一些背景知识:

DirectDraw是为在 Windows95/NT 下实现高速图像显示所写的程式库.


高速图像显示的基本方法是用一种叫做 Page Flipping的技术. 关于什么是 Page Flipping, 参见古技介绍.假如您 不急的话, 看到下面, 您也会看到.


在 Windows95/NT下做 Page Flipping 分为全屏的和窗口的两种. 在全屏下Page Flipping 叫做Flip, 在窗口下叫做 Blit.


知道了这些背景知识, 我们能够开始写程式了.


写任何 DirectDraw的程式, 差不多都有以下几个步骤,

1. 初始化, 这是每个程式都需要的劳什子.
2. 配置显示模式.
3. 在内存里建立PageFlipping所需要的两个页, 前页和后页.
4. 给显示的区域加个画框以免画到外面来.
5. 在后页画图, 然后"刷"的一下子换到前页来.


步骤一: 初始化

DirectDraw 是个面向对象的函数库. "面向对象"的意思并不是指面对著您的女朋友, "对象" 在这里, 您能够简单地想象成是个模板, 比方说,"政府", 一旦您说:"我成立了一个政府". 别人 就会立即把您套入"政府模板", 自然而然地认为您有印钞票的功能. 在我们的程式里, 您一旦声明 一个变量(比如 myDD)是 DirectDraw对象 (DirectDraw对象的正式名为 LPDIRECTDRAW) , 这个myDD就有了 DirectDraw对象的任何的功能和特性. 定义 的语法是:

LPDIRECTDRAW pMyDD;
除了 DD的对象外, 更有几个重要的对象, "页面", "裁剪板" 和 "调色板". "页对象"用来定义"前页"和"后页". 定义如下:

LPDIRECTDRAWSURFACE pMyDDSFront;
LPDIRECTDRAWSURFACE pMyDDSBack;
一个"裁剪板对象", 在窗口模式下用来剪去画出窗口边界的部份.

LPDIRECTDRAWCLIPPER pMyClipper;
"调色板"设定屏幕的颜色表, 在读取256色的 Bitmap时要用到.
LPDIRECTDRAWPALETTE myDDPal;
最最重要的"对象"就是这些了. 当然 DirectX更有很多复杂晦涩的对象. 这是速成不起来的.

编制 Windows 程式有一大堆变量和对象是 Windows所需要的, 这也是我最烦 Microsoft的地方. Microsoft 似乎知道这点. 所以在 VC4.0后的版本有了 Wizard的功能帮您自动生成代码. 尽量地去用他的 Wizard使我们的生活变得容易.

由于我们的程式可能会占用一个窗口, 就给这个窗口一个 handle:

HWND myWnd
初始化的工作还没有完, 我们要把这些对象指向一个安全的地方 Null.

pMyDD = NULL;
pMyDDSFront = NULL;
pMyDDSBack = NULL;
pMyClipper = NULL;
pMyDDPal=NULL;

最后, 在 Windows系统为我们的 myDD对象开辟相应的区域:

DirectDrawCreate( NULL, //用当前的显示驱动
&pMyDD, NULL))
Okay, 烦人的初始化总算完了.


步骤二: 配置屏幕的显示方式.

DirectDraw 有自己的配置屏幕的方式, 而且他的屏幕模式分为"全屏"( exclusive mode)和"窗口"( normal mode). 各有各的配置方法. 配置的主要区别在于 SetCooperativeLeve的参数.

SetCooperativeLeve 在"窗口"模式下这样配置:
pMyDD->SetCooperativeLevel(AfxGetMainWnd()->GetSafeHwnd(),DDSCL_NORMAL);
而在"全屏"模式下这样配置:

pMyDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
假如他们的返回值为 DD_OK表示成功. 我们就能够把屏幕调节成我们想要的样子, 例如 640x480x8. 也就是256色. 究竟有那些屏幕模式可用取决于您的显示卡

pMyDD->SetDisplayMode( 640, 480, 8 );
现在, 我们已有了一个屏幕, 但是还不能在上面画画, 我们需要步骤三来 替我们建立一个可供画画涂涂用的画板.


步骤三: 建立前后页(两块画板).

两块画板的好处是能够一边在一块上面画, 一边给别人看已画好的另一块. 等这块画好了, 两块板就对调一下, 让别人看新画好的这块. 假如画的足够快, 换的足够快. 看的人就会看到动画了, 就象电影的效果相同. 我们把这叫做 Page Flipping.
这里先要介绍的是怎样在系统中建立两块画板( double buffering), 但是您也能够根据需要建立三块,四块画板.
DDSURFACEDESC ddsd; //这个结构描述"页"的特徵.
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;//指定我们用的是前页.

ddsd.dwSize = sizeof(ddsd); //尺寸


// 做前页:
HRESULT result;
result = pMyDD->CreateSurface(&ddsd, &pMyDDSFront, NULL);
当发生错误时, 要记得 Release对象.

if (result!=DD_OK)
{
pMyDD->Release();
pMyDD = NULL;

}


ddsd.dwWidth = scr_width; //设定后页的大小,
ddsd.dwHeight = scr_height;

//指定 我们要后页
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

//做后页
result = pMyDD->CreateSurface(&ddsd, &pMyDDSBack, NULL);

}


步骤四: 给显示区加一个画框(裁剪板).

在窗口下. 为了防止 DirectDraw 画到窗口外面去. 需要加一个画框(裁剪板). 能够用 CreateClipper来 创建剪贴板.
result = pMyDD->CreateClipper(0, &pMyClipper, NULL);

创建后,把他套到窗口上去, 所以要知道是那一个窗口( Handle).

myWnd = AfxGetMainWnd()->GetSafeHwnd();// 从系统中拿到窗口的 Handle
result = pMyClipper->SetHWnd(0, myWnd);

// 把剪贴板加到窗口上去
result = pMyDDSFront->SetClipper(myClipper);


步骤五: 在后页画图, 前后页互换.

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 全屏幕OpenGL程式

下一篇: 将位图旋转90度