• <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)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜


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

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

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

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


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



            PS:如想獲得更多關于Visual C++游戲開發(fā)的內容,可點擊隨筆:《Visual C++游戲編程基礎》學習筆記——索引隨筆
            posted on 2010-04-08 19:12 煙皚 閱讀(1335) 評論(0)  編輯 收藏 引用 所屬分類: 《Visual C++游戲編程基礎》學習筆記
            一本色道久久99一综合| 国产精品无码久久四虎| 欧美亚洲国产精品久久| 色婷婷狠狠久久综合五月| 青青草原综合久久大伊人| 7777精品久久久大香线蕉| 国内精品久久久久影院优| 久久精品中文字幕久久| 久久久久久av无码免费看大片| 一本大道久久香蕉成人网| 亚洲国产美女精品久久久久∴| 国产成年无码久久久久毛片| 久久精品综合一区二区三区| 欧美一区二区三区久久综| 九九精品99久久久香蕉| 久久夜色撩人精品国产小说| 日本WV一本一道久久香蕉| 久久精品嫩草影院| 亚洲AV日韩AV永久无码久久| 精品国产91久久久久久久a| 久久天天躁狠狠躁夜夜avapp| 色婷婷狠狠久久综合五月| 国产精品久久自在自线观看| 性欧美大战久久久久久久| 久久精品国产秦先生| 亚洲国产精品无码久久久秋霞2| 久久九九免费高清视频| 国产V亚洲V天堂无码久久久| 一本色道久久HEZYO无码| 亚洲人成电影网站久久| 久久激情亚洲精品无码?V| 久久亚洲精品中文字幕三区| 无码人妻精品一区二区三区久久| 人人狠狠综合久久亚洲高清| 久久国产成人| 久久久亚洲精品蜜桃臀| 久久黄视频| 久久久久久国产a免费观看黄色大片| 久久久久国产| 亚洲欧洲中文日韩久久AV乱码| 久久久久久久国产免费看|