zoukankan      html  css  js  c++  java
  • 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;
    }

    贴下成果

    image

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

    image

    本文由博主(YinaPan)原创或者转载,如若转载请务必注明出处,谢谢合作!
  • 相关阅读:
    技术面试之经验总结
    为何只有两篇文章?
    LOJ6364 烂柯
    mysql批量更新数据(性能优化)
    一个对象的key引发的血案
    总结与元素坐标相关的属性(再也搞不混了)
    利用nodejs搭建服务器,测试AJAX
    初探jquery之强大丰富的选择器
    Web前端开发规范手册
    IE8下标签float导致的bug。
  • 原文地址:https://www.cnblogs.com/YinaPan/p/4206517.html
Copyright © 2011-2022 走看看