2023年12月22日发(作者:)

游戏图像引擎 DirectX Draw

简要介绍

3EGame图形引擎独特的地方在于把DirectX中所有的工具封装成一个DirectX类,可以很轻松的调用里面的工具函数实现图形操作。引擎使用DirectX7.0 中的DirectDraw功能完成。引擎支持一种标准的图形格式BMP,另外还有相应的自定义格式支持(有附带工具),支持Alpha通道自动混合等。

DirectDraw用来处理所有和2D图形有关的显示操作。目前的显卡上大部分都已经内置了8~64M的显存,DirectDraw可以直接读写这些显存,并利用“切换页”的方式快速显示图象,实现动画,背景的卷动,而且像镂空、半透明等效果的制作,在DirectDraw中都能用更简单的方法来完成。

在这里我们主要介绍在这个图形引擎中我们是如何实现加载,绘制图形,并且实现一定的特效的(半透明效果即Alpha混合通道)。

绘制位图功能在引擎中的实现

我们是利用绘图页(Surface)配合(贴图)与翻页(flip)的方式来显示图形。绘图页是一块显象或者暂存位图的内存,按照其功能的不同,可将它分为如下三种类型:

·主绘图页(Primary Surface):显存,在主绘图页中的图形会显示在屏幕中。

·后缓冲区(Back Buffer):在后缓冲区中可以贴上位图数据,当利用翻页的方式切换至后缓冲区时,此绘图页就会变成主绘图页,显示其中的内容。

·幕后暂存区(Offscreen Plain):用来暂存要使用位图的绘图页。

通常不直接把位图贴到主绘图页中,而是先贴到后缓冲区,再利用翻页的方式,绘出要显示的位图的内容。如下图所示:

Primary Surface

Back Buffer

flip

Back Buffer

Primary Surface

flip

Primary Surface

Back Buffer

根据这一原理我们在DirectX类中封装了以下函数:

相关函数介绍:

1. void initDD(int width, int hight, HWND hwnd);

这个函数完成下列工作:建立DirectDraw对象,设定协调层级,设定屏幕显示模式,建立主绘图页,连结后缓冲区,建立幕后内存区。在要使用DirectXDraw之前,必须先建立DirectXDraw对象,DirectXDraw对象所代表的就是显示设备硬件,即计算机屏幕,通过此对象便可调用DirectXDraw中的方法来控制屏幕的显示。

2. void assignPla(int num, int width,int height);

这个函数主要完成分配幕后内存区,取得位图后把位图贴到幕后内存区中。要将位图加载到幕后内存区中,还是要通DC来进行存取,而这里所指的DC并非是MFC中的CDC,而是Windows的HDC。

参数:

Num :表示分配的幕后内存区的数量(游戏中需要多少不同类型的位图就有多少个幕后内存区)。

Width,height: 表示所加载的位图的长宽。

3.HBITMAP loadBMP(const char* PicName, int width, int height);

这是函数用于加载位图;

参数:

PicName: 位图的名字。 width,height: 位图的长宽。

4. void createDDPla(int width,int height,const char* PicName,int num, int

colorKey);

建立并分配幕后内存区,调用了assignPla(„„)函数。

5. void drawPic(int screenX, int screenY, int index, int picBeginX, int picBeginY,

int picEndX, int picEndY, int model);

直接的绘图函数,在一切就绪后,可以直接调用这个函数绘制所要加载的位图。

参数:

screenX,screenY:绘制(目标)位图在屏幕上的坐标。

index :位图所在幕后内存区的索引号。

picBeginX,picBeginY:幕后内存区中(源)位图左上角坐标。

picEndX, picEndY: 幕后内存区中(源)位图左下角坐标。

model: 是否为透明色。

6. void flip();

执行翻页功能的函数。

镂空技术在引擎中的实现

在DirectX中制作镂空的方法比起在MFC中利用蒙版简单得多,其关键就在于颜色键(color key)的使用。

在DirectX中只需要用到一张位图,其底色可为任意色,不过通常是使用白(RGB(255,255,255))、黑(RGB(0,0,0))、红(RGB(255,0,0))、绿(RGB(0,255,0))、蓝(RGB(0,0,255))。我们以底色作为颜色键,在将幕后绘图页的位图复制到其他绘图页时,设为颜色键的底色部分就会自动被镂空,这就是颜色键的功能。

在我们的图形引擎中我们设置了两个常用的颜色键,并通过这两个函数实现 void colorKeyWhite(int num);

void colorKeyBlack(int num);

动画在引擎中的实现

要运用DirectDraw来制作动画,就必须利用到主绘图页,后缓冲区和幕后暂存区这三种绘图页。

绘图页架构:

首先准备好连续的位图(比如人物的走动图,背景图)并且在程序中建立相应数量的幕后暂存区来储存位图。

程序流程:

利用已经设置好的颜色键对位图进行处理,设置一个定时器,每当发出WM_TIMER消息时就自动将下一个幕后暂存区的图案贴到后缓冲区中,再进行翻页进行显示,这样便产生镂空人物走动的动画效果。

利用这一原理我们在引擎中实现了人物绘制并走动

如图,我们将人物的上下左右走动的动作图合并到一个位图中,然后根据这些动作图在该位图中的位置来取得应该贴的图案。为了方便找到位图中的人物动

作图,我们为人物动作图设置了几组编号:

方向编号 索引值

1(向上) 0 1 2

2(向右) 0 1 2

3(向下) 0 1 2

4(向左) 0 1 2

在程序中我们声明变量manIndex来记录方向编号,变量rowIndex来记录索引值。在读取人物动作图时,只要知道变量manIndex的值就可以知道动作图的y坐标,同样道理,也可以通过变量rowIndex的值来获取动作x的坐标。这样只要控制变量manIndex,rowIndex的值就可以随心所欲地改变人物的动作了。

图形的碰撞检测在引擎中的实现

在引擎中我们通过范围检测来实现碰撞的检测的。我们封装了Utities这个工具类,其中设置了两个碰撞成员函数。

点和区域碰撞检测:static bool dotHitRect(int dotX, int dotY, int rectX, int rectY,

int rectWidth, int rectHeight);

矩形碰撞检测: static bool rectCollision(int rectAX,int rectAY,int rectAWidth,int

rectAHeight, int rectBX,int rectBY,int rectBWidth,int rectBHeight);

参数:

1. 点和区域的碰撞检测

dotX,dotY: 点的绝对坐标

rectX,rectY: 矩形的绝对坐标

rectWidth,rectHeight:矩形的长宽

2.矩形碰撞检测

rectAX,rectAY:矩形的绝对坐标

rectAWidth,rectAHeight:矩形的长宽

rectBX,rectBY: 另外一个矩形的绝对坐标

rectBWidth,rectBHeight:另外一个矩形的长宽