DX笔记之六------游戏画面绘图之透明特效的制作方法

原文链接:http://blog.csdn.net/zhmxy555/article/details/7338082

透明效果

由于所有的图文件都是以矩形来储存的,我们也许会需要把一张怪兽图片贴到窗口的背景图上,而这种情况下如果直接进行贴图,结果如下图:

这似乎不是我们想要的结果。

为了得到透明效果,我们需要运用到BitBlt()贴图函数以及其参数Raster的值来将图片中不必要的部分去掉(又称去背),使得图中的主题可以与背景完美融合。

我们以图中的恐龙为例子,首先准备一张位图,如下图。

图中的左边的图是要去背并贴到背景上的前景图。右边的黑白图称为“屏蔽图”,在透明的过程中会用到它。要把去背的位图与屏蔽图合并成同一张图,透明的时候再按照需要来进行裁切。可以把它分成两张图,但是这样程序必须运行两次图文件加载的操作。

有了屏蔽图就可以利用贴图函数来产生透明效果了,所需的贴图步骤如下:

<1>将屏蔽图与背景图做"AND"运算,Raster值为SRCAND,贴到目的地DC中。

<2>将前景图与背景图做"OR"运算,Raster值为SRCPAINT,贴到目的地DC中。

为什么经过上面两个操作就能产生透明的效果呢?看下图就理解了:

下面具体说明上面两个步骤所产生的图点色彩的变化。

1.屏蔽图与背景图做"AND"运算

<1>屏蔽图中的黑色部分与背景图做"AND"运算:

<2>屏蔽图中的白色部分与背景图做"AND"运算:

进过这一运算所产生的结果如下图

2.前景图与背景图做"OR"运算

<1>前景图中的彩色部分与图第一步得到的“黑色恐龙”图做"OR"运算:

<2>前景图中的黑色部分与第一步得到的“黑色恐龙”图做"OR"运算:

经过这一运算后所显示的画面就是所需的透明图了,如下图所示:

#include <windows.h>

//全局变量声明
HINSTANCE hInst;
HBITMAP bg,dra; //声明两个位图对象,分别存储背景图与前景恐龙图
HDC     mdc;       //声明一个内存DC"mdc",用来暂存位图

//全局函数声明
ATOM     MyRegisterClass(HINSTANCE hInstance);
BOOL     InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void     MyPaint(HDC hdc);
////****Winmain函数,程序入口点函数**************************************
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    MSG msg;
    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
    //消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
//****设计一个窗口类,类似填空题,使用窗口结构体*************************
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize            = sizeof(WNDCLASSEX);
    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = NULL;
    wcex.hCursor        = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = TEXT("canvas");
    wcex.hIconSm        = NULL;
    return RegisterClassEx(&wcex);
}
//****初始化函数*************************************
// 1.建立与窗口DC兼容的内存DC
// 2.从文件加载背景图与恐龙图
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    HDC hdc;
    hInst = hInstance;
    hWnd = CreateWindow(TEXT("canvas"), TEXT("绘图窗口") , WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
        return FALSE;
    }
    MoveWindow(hWnd,10,10,600,450,true);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    hdc = GetDC(hWnd);                     //获得窗口DC
    mdc = CreateCompatibleDC(hdc);           //创建与窗口兼容的内存DC(mdc)
    bg = (HBITMAP)LoadImage(NULL,TEXT("bg.bmp"),IMAGE_BITMAP,600,450,LR_LOADFROMFILE);
    //加载背景图到bg中;
    dra = (HBITMAP)LoadImage(NULL,TEXT("dra.bmp"),IMAGE_BITMAP,170,99,LR_LOADFROMFILE);
    //加载恐龙图到dra中;
    MyPaint(hdc);
    ReleaseDC(hWnd,hdc);
    return TRUE;
}
//****自定义绘图函数*********************************
//透明贴图
void MyPaint(HDC hdc)
{
    SelectObject(mdc,bg);
    BitBlt(hdc,0,0,600,450,mdc,0,0,SRCCOPY);    //先将背景图贴到显示窗口中
    SelectObject(mdc,dra);                      //选用恐龙图到"mdc"中
    BitBlt(hdc,280,320,85,99,mdc,85,0,SRCAND);    //进行制作贴图的第一步骤,即将屏蔽图与背景图做"AND"运算,屏蔽图在整张恐龙图中,最左上角起始位置点得坐标为(85,0),BitBlt()函数中最后一个Raster参数值设置为SRCAND。
    BitBlt(hdc,280,320,85,99,mdc,0,0,SRCPAINT);    //进行制作透明贴图的第二步骤,即将前景图与背景图做"OR"运算,前景图在整张恐龙图中,最左上角起始位置的坐标为(0,0),BitBlt()函数最后一个参数值设置为SRCPAINT。
}
//****消息处理函数**********************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    switch (message)
    {
        case WM_PAINT:     //窗口重绘消息
        hdc = BeginPaint(hWnd, &ps);
        MyPaint(hdc);
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:     //窗口结束消息
        DeleteDC(mdc);
        DeleteObject(bg);
        DeleteObject(dra);
        PostQuitMessage(0);
        break;
    default:     //其他消息
        return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

贴下成果

若是知识屏蔽图被背景图合并,效果如下:

时间: 2024-11-06 22:23:19

DX笔记之六------游戏画面绘图之透明特效的制作方法的相关文章

DX笔记之五------游戏画面绘图之绘制位图

本系列文章由zhmxy555编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7335103 共四步 步骤一:加载位图 步骤二:建立与窗口DC兼容的内存DC 步骤三:选用位图对象 步骤四:贴图 详细步骤 步骤一:加载位图 要从文件加载位图,常常使用LoadImage()函数. HANDLE LoadImage( HINSTANCE hinst,  //包含目标位图的DLL或exe文件的模块句柄 LPCTSTR lpszName,

游戏开发(三)——WIN32 黑白棋(三)——游戏画面的现实

整个游戏分3部分介绍. 1.棋局的现实 2.AI的现实 3.游戏画面的现实 提供一下完整项目下载 这是第三部分:画面的显示 这部分其实就比较简单的,说白了就是api的堆砌. 主要了解下windows的消息机制,以及怎么画图 主要是分别封装了下对棋盘,棋子,以及当前轮到谁,当前比分是多少,就是游戏画面上不同的部分的绘制. void DrawReversiBoard(); void DrawReversiPieces(EnumReversiPiecesType type, int row_y, in

DX笔记之一---Direct3D基础

一.预备知识 1.表面 表面就是Direct3D用于储存2D图像数据的一个像素矩阵.width和height以像素为单位,pitch以字节单位,用接口IDirect3DSurface来描述表面 LockRect:该方法用于获取指向表面存储区的指针,通过通过指针运算,可对每个像素进行读写操作: UnlockRect:配对使用,调用lock必须unlock,解除对表面存储区的锁定: GetDesc: 获取表面的描述信息,通过填充D3DSURFACE_DESC; //Assume _surface i

Python学习笔记之六:在VS中调用Python

1,安装配置好Python本身的运行环境,以能在命令行下运行py脚本为准 2,将Python的根目录下的include文件夹,添加到VS的项目属性->配置属性->C/C++->"附加包含目录"中 3,将Python的根目录下的libs文件夹,添加到VS的项目属性->配置属性->链接器->"附加库目录"中 4,在C++项目中添加Python头文件: #include <python.h> 5,添加必要的Python初始化

Citrix XenMobile学习笔记之六:XenMoble业务访问数据流程

总体访问流程图 终端设备注册流程 Android设备注册流程 到google Play或亚马逊应用商店或者豌豆荚.Citrix官网,下载思杰Worx Home应用.并在设备上安装. 当系统提示您安装该应用程序,单击下一步,然后单击安装. 安装Worx Home之后,点击启动. 输入您的认证信息,如设备管理器服务器名,用户主体名称(UPN),或电子邮件地址的名称,然后单击下一步. 在激活设备管理员屏幕上,点击激活. 输入您的账户密码,然后点击点登录. 根据XenMobile的配置方式,您可能会被要

linux网络编程学习笔记之六 -----I/O多路复用服务端

多进程和多线程的目的是在于最大限度地利用CPU资源,当某个进程不需要占用太多CPU资源,而是需要I/O资源时,可以采用I/O多路复用,基本思路是让内核把进程挂起,直到有I/O事件发生时,再把控制返回给程序.这种事件驱动模型的高效之处在于,省去了进程和线程上下文切换的开销.整个程序运行在单一的进程上下文中,所有的逻辑流共享整个进程的地址空间.缺点是,编码复杂,而且随着每个逻辑流并发粒度的减小,编码复杂度会继续上升. I/O多路复用典型应用场合(摘自UNP6.1) select的模型就是这样一个实现

cocos2d-x学习笔记(18)--游戏打包(windows平台)

cocos2d-x学习笔记(18)--游戏打包(windows平台) 之前做好的游戏,都是在vs2008下编译执行的.假设说想把游戏公布到网上或者和其它人一起分享游戏,那就得对游戏进行打包.以下我就向大家介绍一款程序打包工具 ----Enigma Virtual Box,这个软件的下载链接我就不提供了,大家在网上输入这个keyword,就有非常多下载链接了. 既然要执行游戏,就得找到.exe文件.有些人可能打开project文件夹下(我的是myGame01)的Debug.win32文件夹找.但没

contiki-main.c 中的process系列函数学习笔记 &lt;contiki学习笔记之六&gt;

说明:本文依然依赖于 contiki/platform/native/contiki-main.c 文件. ------------------------------------------------------------------------------------------------------------------------------------- 根据上一个笔记里面添加的printf()语句的打印信息提示,hello world 打印是在执行了 1 autostart_

Windows界面编程-背景图片、透明特效使用

Windows界面编程第一篇 位图背景与位图画刷 可以通过WM_CTLCOLORDLG消息来设置对话框的背景,MSDN上对这个消息的说明如下: The WM_CTLCOLORDLG message is sent to a dialog box before the system draws the dialog box. By responding to this message, the dialog box can set its text and background colors us