• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              117 Posts :: 2 Stories :: 61 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(8)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜


                半透明在游戲中通常用來呈現(xiàn)若隱若現(xiàn)的特殊效果。事實上這種效果的運用相當頻繁,比如薄霧、鬼魂或隱形任務(wù)等,有時會以半透明的手法來表現(xiàn)。本篇隨筆就來介紹半透明效果的制作方法,下圖23是一張位圖經(jīng)過半透明處理后顯示在背景上的效果。

            1、半透明的制作原理
               
                 簡單地說,半透明效果就是前景圖案與背景圖案像素顏色的混合。從圖23中觀察半透明效果呈現(xiàn)的區(qū)域,可以看到背景圖案,也可看到前景的人物圖案。什么是前景圖案與背景圖案像素顏色的混合呢?這就要從位圖的基本結(jié)構(gòu)開始談起了。
                一張位圖是由許多的像素所組成的,每一個像素中都包含紅(R)、綠(G)、藍(B)三原色的色彩值,由這三種原色值來決定該像素的色彩。而要呈現(xiàn)半透明效果,必須將前景圖與背景圖彼此對應像素的顏色依某一比例來進行調(diào)配,這個比例就叫做“不透明度”。
                以沒有進行半透明處理,單純地將一張前景圖貼到背景圖上的一塊區(qū)域來說,前景圖的不透明度是100%,而背景圖在這一塊區(qū)域上的不透明度則是0%(完全透明,所以看不見背景),也就是說在這塊區(qū)域上,背景圖的色彩完全派不上用場。
                可是如果想要有半透明的效果,讓前景圖看起來稍微透明一點,那就需要確定不透明度的值。假設(shè)確定不透明度是70%,也就是說前景圖像素顏色按照一定的不透明度比例進行合成,那么最后整個區(qū)域所呈現(xiàn)出來的就是所要的半透明效果了。綜合上面的說明,可以整理出一個建檔的公式如下:
                半透明圖色彩 = 前景圖色彩 × 不透明度 + 背景圖色彩 ×(1 - 不透明度)

            2、半透明的操作步驟
               
                清楚了半透明制作的原理后,接下來說明程序產(chǎn)生半透明效果的實際步驟。
                步驟一:取得位圖結(jié)構(gòu)
                位圖結(jié)構(gòu)包含了一些位圖的基本信息,由于我們在制作半透明效果時會用到,因此在從文件加載位圖后,必須先取得該位圖的結(jié)構(gòu),而取的位圖結(jié)構(gòu)的函數(shù)如下:
            int GetObject(   HGDIOBJ GDI對象,  //取得GDI對象結(jié)構(gòu)
                                       
            int 結(jié)構(gòu)大小,
                                        LPVOID 結(jié)構(gòu)變量,);
                上面這個函數(shù)用于取得GDI對象的信息,包含這里所談的位圖,其中第3個參數(shù)是一個結(jié)構(gòu)變量,如果是用于取得位圖的信息,則輸入一個位圖結(jié)構(gòu)的地址,而Windows API所定義的位圖結(jié)構(gòu)(BITMAP)如下:
            typedef struct tagBITMAP{
                                                                            LONG bmType;  
            // 位圖類型,必須設(shè)為0
                                                                            
            LONG bmWidth;  // 位圖寬度
                                                                           
            LONG bmHeight; //位圖長度
                                                                            
            LONG bmWidthBytes;  //每一列像素所占Byte數(shù)
                                                                           
            WORD bmPlanes;  //顏色平面數(shù)
                                                                           
            WORD bmBitsPixel; //像素的位數(shù)
                                                                            
            LPVOID bmBits;  //位圖內(nèi)存指針
                                                                        
            }
            BITMAP;
                后面將會用到bmWidth、bmHeight、bmWidthBytes及bmBitsPixel這幾個結(jié)構(gòu)成員的信息。
                在此舉個例子來說明取得位圖結(jié)構(gòu)的方法,假設(shè)現(xiàn)在有一個位圖名稱為“bitmap”,位圖結(jié)構(gòu)變量名稱為“bm”,則使用GetObject()函數(shù)取得BITMAP結(jié)構(gòu)的程序代碼如下:
            GetObject(bitmap,sizeof(BITMAP),&bm);
                這樣,位圖結(jié)構(gòu)bm中的各個結(jié)構(gòu)成員便包含了位圖bitmap的基本信息。
                步驟二:建立暫存數(shù)組
                取得位圖的結(jié)構(gòu),接下來必須先建立一個暫存數(shù)組準備存儲位圖中所有像素的顏色值。這個暫存數(shù)組的大小是由前一個步驟中所取得位圖的bmHeight與bmWidthBytes信息來決定的,因此,必須利用指針來動態(tài)建立。延續(xù)前一個例子,若要建立一個可存儲bitmap所有像素顏色值的暫存數(shù)組,程序代碼如下:
            unsigned char *px = new unsigned char [bm.bmHeight * bm.bmWidthBytes];
                這里,因為unsigned char變量類型大小是1Byte,所以這個數(shù)組的每個元素大小也就是1Byte(8bits)。以一張24bits色彩的位圖來說,它的每個像素是以24bits來表示顏色的,其中B(藍)、G(綠)、R(紅)三原色各占8個bits。
                因此,在下面的步驟中,當取出位圖的所有顏色并存儲在這個數(shù)組中時,每一個像素會占用3個數(shù)組元素來存儲B、G、R的顏色值。
                步驟三:取得位圖位置
                建立了暫存數(shù)組之后,要取出位圖的所有顏色值存儲到數(shù)組中就簡單多了,有一個現(xiàn)成的API函數(shù)可以使用。
            LONG GetBitmapBits(  HBITMAP 位圖,  // 取得位圖位值
                                                    
            LONG 要取得的Byte數(shù),
                                                     LPVOID 存儲的數(shù)組指針);
                使用此函數(shù)取得位圖位值的程序代碼如下。
            GetBitmapBits(bitmap, bm.bmHeight * bm.bmWidthBytes, px);
                下面以圖來說明像素顏色值存儲在數(shù)組中的對應關(guān)系,如下圖所示:

                步驟四:合成像素顏色值
                取得了位圖的所有像素顏色值之后,接下來的工作就是按照不透明度來設(shè)定半透明區(qū)域內(nèi)每個像素的顏色了。
                此時應該會有兩個像素顏色數(shù)組,一個是前景圖的,一個則是背景圖的。根據(jù)實際要顯示半透明區(qū)域的坐標,將這兩個數(shù)組算出對應的元素進行簽名講過的顏色合成運算,再存回暫存數(shù)組中,anemia數(shù)組中所存儲的便是已經(jīng)完成半透明的顏色值了。這個步驟的實際處理過程,將在代碼中做詳細說明。
                步驟五:重設(shè)位圖顏色
                處理完暫存數(shù)組中半透明的顏色值之后,最后一個操作就是根據(jù)數(shù)組的內(nèi)容來重設(shè)位圖的顏色。這個操作同樣可以使用一個API的函數(shù)來完成。
            LONG SetBitmapBits(     HBITMAP 位圖, //設(shè)定位圖位值
                                                       
            DWORD 顏色數(shù)組大小, 
                                                       CONST VOID 數(shù)組指針 );
            //為什么是CONST VOID?

                以上5個步驟都完成之后,所要的半透明圖也就完成了,剩下的就只有貼圖操作了。


            范例ch2_7:取得前景圖與背景圖的顏色值,以前景圖的不透明度30%和背景圖的不透明度70%進行半透明處理,制作半透明效果。
            下載地址:ch2_7(上傳到windows live空間,可能需要MSN賬號登陸)
            說明:程序源代碼中有相關(guān)的注釋。
            程序運行結(jié)果如下圖:



            PS:如想獲得更多關(guān)于Visual C++游戲開發(fā)的內(nèi)容,可點擊隨筆:《Visual C++游戲編程基礎(chǔ)》學習筆記——索引隨筆
            posted on 2010-04-08 19:12 煙皚 閱讀(1365) 評論(0)  編輯 收藏 引用 所屬分類: 《Visual C++游戲編程基礎(chǔ)》學習筆記
            亚洲AV无码久久精品狠狠爱浪潮| 99久久人人爽亚洲精品美女| 欧美精品国产综合久久| 国产亚州精品女人久久久久久 | 无码人妻精品一区二区三区久久 | 久久最新精品国产| 青青热久久国产久精品| 久久久久人妻精品一区二区三区| 伊人热人久久中文字幕| 狠狠色丁香久久婷婷综合图片| 国内精品久久久久久99蜜桃| 久久伊人五月天论坛| 国内精品久久久久久99| 久久久亚洲欧洲日产国码是AV| 一本久道久久综合狠狠爱| 精品久久久无码中文字幕| 丰满少妇高潮惨叫久久久| 久久久这里有精品| 国产伊人久久| 久久综合综合久久97色| 亚洲国产精品无码久久一线| 久久亚洲国产精品五月天婷| 久久综合狠狠色综合伊人| 久久久久高潮毛片免费全部播放| 亚洲日本va午夜中文字幕久久| 99精品久久久久久久婷婷| 99久久精品国产高清一区二区| 国内精品伊人久久久久777| 久久久无码精品午夜| 久久精品国产只有精品66| 国产精品伦理久久久久久| 国产精品久久久久影院嫩草| 久久香蕉国产线看观看精品yw| 亚洲国产视频久久| 久久人人爽人人爽人人片AV麻烦| 三级韩国一区久久二区综合| 久久久久亚洲AV成人网| 日本欧美国产精品第一页久久| 国产日韩欧美久久| 日本加勒比久久精品| 久久99久久99精品免视看动漫|