• <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++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              117 Posts :: 2 Stories :: 61 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(8)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜


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

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

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

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

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


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



            PS:如想獲得更多關于Visual C++游戲開發的內容,可點擊隨筆:《Visual C++游戲編程基礎》學習筆記——索引隨筆
            posted on 2010-04-08 19:12 煙皚 閱讀(1336) 評論(0)  編輯 收藏 引用 所屬分類: 《Visual C++游戲編程基礎》學習筆記
            久久久久国产| 99精品国产在热久久| 国产成人AV综合久久| 亚洲国产综合久久天堂 | 欧美激情精品久久久久久久九九九 | 久久国产成人精品国产成人亚洲| 热久久最新网站获取| 国产精品久久久久久一区二区三区| 久久免费美女视频| 日韩乱码人妻无码中文字幕久久| 国产免费久久久久久无码| 2020国产成人久久精品| 久久免费视频6| 精品国产一区二区三区久久久狼| 亚洲AV无码久久精品狠狠爱浪潮 | 2021国产精品午夜久久| 国产ww久久久久久久久久| 久久人妻少妇嫩草AV无码专区| 亚洲国产成人久久综合一区77| 国产精品女同久久久久电影院| 日产久久强奸免费的看| 久久婷婷五月综合成人D啪 | 久久久久亚洲av毛片大| 国产一久久香蕉国产线看观看| 久久91精品国产91久久小草| 波多野结衣AV无码久久一区| 无码国内精品久久人妻蜜桃| 日韩久久久久中文字幕人妻| 99久久亚洲综合精品网站| 国产综合成人久久大片91| 99久久超碰中文字幕伊人| 久久棈精品久久久久久噜噜| 区久久AAA片69亚洲| 久久香综合精品久久伊人| 久久久久国产日韩精品网站| 久久无码人妻精品一区二区三区| 国产精品欧美久久久久无广告| 中文字幕亚洲综合久久| 精品国产91久久久久久久a | 久久免费的精品国产V∧ | 久久久久久精品免费看SSS |