⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directdraw.txt

📁 一个DirectDraw的学习文档推荐给大家希望对需要的人有所帮助
💻 TXT
📖 第 1 页 / 共 2 页
字号:
}
//设置ddsCaps.dwCaps
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
//连接主页面及后台缓冲
if (FAILED(lpDDprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpDDback)))
{
    MessageBox(NULL,TEXT("DirectDraw Create back Surface error!"),
    TEXT("Wrong!"),MB_OK);
    return(0);
}

在这里,我们要定义几个全局变量:
extern LPDIRECTSURFACE7 lpDDprimary;
extern LPDIRECTSURFACE7 lpDDback;
extern DDSURFACEDESC2 ddsd;

这是一个指向主页面的指针,一个指向后台缓冲的指针,和一个页面描述结构。不用说,这些定义你可以放在MyDirectDraw.h中。通过填充ddsd结构的成员来申明你所想创建的页面的类型。这里我们没创建离屏页面。用主页面及后台缓冲可以完成一些相对简单,数据不是很多的图形显示,数据过于复杂,就应该创建离屏页面了。

相应的,在结束时,除了释放DirectDraw7接口外,还要依次释放后台缓冲指针和主页面指针。还是提醒一下,先创建的一定要后释放,不然你会死的很难堪的。怎么去Release这些东西,看看code1中的代码,很容易明白的。

顺便我们看一下如何创建离屏页面,看下面代码:
DDSURFACEDESC2 ddsd;
LPDIRECTSURFACE7 lpDDopl; //这两个定义不用说了吧
memset(&ddsd,0,sizeof(ddsd)); //清空结构内容
ddsd.dwSize=sizeof(ddsd); //设置大小
ddsd.dwFlags = DDSD_CAPS |DDSD_HEIGHT|DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;//指定页面类型 
ddsd.dwWidth=600;
ddsd.dwHeight=800; //设置离屏页面大小
if (FAILED(lpDDraw7->CreateSurface(&ddsd, &lpDDopl, NULL)))
{
    MessageBox(NULL,TEXT("DirectDraw Create offscreen plain error!"),
    TEXT("Wrong!"),MB_OK);
    return(0);
} //创建离屏页面

Okay!离屏页面就创建好了,说一下,因为离屏页面是个独立的页面,不隶属于任何其他页面,所以你必须指定它的大小。

关于页面的创建我们就说到这,到这儿,是不是有一种万事具备,只欠东风的感觉啊?

抬头一看,天亮了,该睡觉了,睡醒咱们再接着说,先去呼呼了。

……n小时后……

好了,既然只欠东风,我们就来说东风。

简单的画图,我们可以参看code1(在屏幕上打点)

  有关页面的运用的位图的操作(作图也就这两个东西)我还组织不起来,无法把理解到的东西组织到程序中(汗!还没真正理解,就好意思在这说)我也在学嘛,多理解几遍,说不定就能够组织了,那么,那么,我们只能像我看过的几本资料一样,来拆开来说了,开始照单全收的抄书。希望抄完后,能有点组织的眉目。

  从以前那个页面表,可以看出,这里的操作无非是载入位图,贴图,翻页显示,以及对画面进行剪贴。那我们一步步来说吧。这里就事论事,就模块论模块,代码段和以前的文件没多大关联了。大家看不明白了不要骂我,理解万岁。

先看载入位图,即将位图load到离屏页面中,要通过windows的HDC来进行存取,用windowsAPI配合DirectX来完成。我们看代码段:

HDC hdc,hdc1; //声明HDC对象,hdc用来存储位图,hdc1代表离屏页面的DC
HBITMAP bitmap; //声明HBITMAP对象
hdc=::CreateCompatatibleDC(NULL);//建立与目前显示模式兼容的DC(参数为null)
bitmap=(HBITMAP)::LoadImage(NULL,”bgroud.bmp”,IMAGE_BITMAP,640,480,LR_LOADFROMFILE);
//加载640*480的位图
::SelectObject(hdc,bitmap); //使用windows函数设置hdc中的内容为bitmap

现在把位图加载到了DC中,下面就要把DC中的位图贴到离屏页面中了

LPDIRECTSURFACE7 lpDDopl; //这个定义不用说了吧
HRESULT result;//干嘛用的?往下看
lpDDopl->GetSurfaceDesc(&ddsd);//ddsd和我们前面定义过的一样
result= lpDDopl->GetDC(&hdc1);//用GetDC()来取得离屏页面的DC
if(result!=DD_OK)
    MessageBox(“取得暂存区DC失败”);//是否取得成功,了解result做这个用
::Bitblt(hdc1,0,0,ddsd.dwWidth,ddsd.dwHeight,hdc,0,0,SRCCOPY);
//这个就是贴图用的windows函数
lpDDopl->releaseDC(hdc1);//释放离屏页面的DC,一定要释放

到此我们已经把位图贴到离屏页面中了,下面应该把离屏页面DC中的位图填充到back buffer中,然后通过换页显示出来。先来了解两个DirectDraw的贴图函数Blt和BltFast。这两个函数的原型在老王翻译的directx开发手册中有详细说明,在我主页上可以down到,你可以查阅一下。这里我简单说一下:

HRESULT Blt( LPRECT lpDestRect, //目标页面的区域,lpDestRect定义其左上右下点坐标
LPDIRECTDRAWSURFACE7 lpDDSrcSurface,//源页面指针
LPRECT lpSrcRect, //源页面的区域
DWORD dwFlags,//控制标志,详见老王的手册
LPDDBLTFX lpDDBltFx)//图形变换的信息结构,详情请自己查阅
HRESULT BltFast( DWORD dwX, //目的区域左上x坐标
DWORD dwY, //目的区域左上y坐标
LPDIRECTDRAWSURFACE7 lpDDSrcSurface,//源页面指针
LPRECT lpSrcRect, //源页面的区域
DWORD dwTrans,//转换参数,见老王手册

这两者的差别就是Blt多了图形放缩功能,但是BltFast效率较高,如何选用已经很清楚了。调用这两个函数中的一个就能够实现从离屏页面到back buffer的贴图,代码如下:

lpDDback->BltFast(0,0,lpDDopl,CRect(0,0,640,480),DDBLTFAST_WAIT);

//lpDDback是我们以前声明过的后台缓冲,CRect(…)是个CRect类的对象,如果我们已声明了一个CRect rect;这里就可用&rect来代替
单看贴图这步操作,还是很easy的。
看起来好像离显示只有一步之遥了啊,right,只要翻页(flip)一下就okay了

先看翻页函数:
HRESULT Flip( LPDIRECTDRAWSURFACE7 lpDDDestSurface,//你想翻到的目标页
DWORD dwFlags) //通常设为DDFLIP_WAIT

说明一下:第一个参数为null时,表示翻到目前页面的所连接的下一个页面。当换页对象是可见的页面,比如主页面换页链,进行换页的Flip函数与系统CPU是异步执行的。这就是说,在这些可见的页面上,调用Flip函数,它只是简单的告诉显示硬件该进行换页了,并不需要等待换页操作在硬件设备中实际完成后才返回。这是因为显示硬件(显示器)只有在完成一次垂直刷新后才能进行一次换页。所以,Flip函数调用成功,并不意味着换页已经完成,在实际的换页操作进行之前,对即将成为主页面的后台缓存是不能锁定和进行Blit操作的。要让Flip函数成为与系统CPU同步的操作,在调用时指定DDFLIP_WAIT标志即可

代码同样简单:
lpDDprimary->Flip(NULL,DDFLIP_WAIT);

  小功告成,到这儿我们已经把一个指定的位图bgroud.bmp在屏幕上显示出来了,这个就可以作为你的游戏的背景图,比如潜水艇游戏的那张大海图。

需要说明一下的是,如果我们要在哪个页面上操作(一般是back buffer),最好操作前先锁定,用完再解锁,防止其他GDI程序的干扰。举个例子:
lpDDback->Lock(NULL,&ddsd,DDLOCK-WAIT|DDLOCK_SURFACEMEMORYPTR, NULL); //锁定后台缓冲
lpDDback->Unlock(NULL);//解锁后台缓冲

把这两句代码分别添加到相应位置即可。

  再往下我们该做什么了?背景有了,应该引进我们的精灵了(精灵这个术语真是可爱),然后想想看如何能让我们的精灵动起来。老实说,到这,我快崩溃了。下面的内容应该属于陌生的部分吧(如果前面的内容我还有点熟悉的话)。好在我这个人是很执着的,所以只有继续硬着头皮往下写了,理解不到位的地方还请大家包涵,同时希望大家指教。

先做做准备工作,去吃饭先,休息一会再来…………

……又是n个小时……

有饭吃的日子真爽啊,珍惜吧,朋友们:)深吸一口气,let’s go on

运用DirectDraw来做动画,我们把不同的图片载入到离屏页面中,然后定时贴入到back buffer中,翻页显示就出现动画效果了。来看个例程 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -