• <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)系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 400065
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

             OpenGL中 的絕大多數(shù)特效都與某些類型的(色彩)混合有關(guān)。混色的定義為,將某個(gè)象素的顏色和已繪制在屏幕上與其對應(yīng)的象素顏色相互結(jié)合。至于如何結(jié)合這兩個(gè)顏色則 依賴于顏色的alpha通道的分量值,以及/或者所使用的混色函數(shù)。Alpha通常是位于顏色值末尾的第4個(gè)顏色組成分量。前面這些課我們都是用 GL_RGB來指定顏色的三個(gè)分量。相應(yīng)的GL_RGBA可以指定alpha分量的值。更進(jìn)一步,我們可以使用glColor4f()來代替 glColor3f()。
               絕大多數(shù)人都認(rèn)為Alpha分量代表材料的透明度。這就是說,alpha值為0.0時(shí)所代表的材料是完全透明的。alpha值為1.0時(shí)所代表的材料則是完全不透明的。

            8.1、混色的公式
               若您對數(shù)學(xué)不感興趣,而只想看看如何實(shí)現(xiàn)透明,請?zhí)^這一節(jié)。若您想深入理解(色彩)混合的工作原理,這一節(jié)應(yīng)該適合您吧。(譯者: 其實(shí)混合的基本原理是就將要分色的圖像各象素的顏色以及背景顏色均按照RGB規(guī)則各自分離之后,根據(jù) — 圖像的RGB顏色分量*alpha值+背景的RGB顏色分量*(1-alpha值) — 這樣一個(gè)簡單公式來混合之后,最后將混合得到的RGB分量重新合并。)公式如下:

            (Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)

            OpenGL按照上面的公式計(jì)算這兩個(gè)象素的混色結(jié)果。小寫的s和r分別代表源象素和目標(biāo)象素。大寫的S和D則是相應(yīng)的混色因子。這些決定了您如何對這些 象素混色。絕大多數(shù)情況下,各顏色通道的alpha混色值大小相同,這樣對源象素就有(As, As, As, As),目標(biāo)象素則有(1, 1, 1, 1) - (As, As, As, As)。上面的公式就成了下面的模樣:

            (Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As + Ad (1 - As))

              這個(gè)公式會(huì)生成透明/半透明的效果。

            8.2、OpenGL中的混色
              在OpenGL中實(shí)現(xiàn)混色的步驟類似于我們以前提到的OpenGL過程。接著設(shè)置公式,并在繪制透明對象時(shí)關(guān)閉寫深度緩存。因?yàn)槲覀兿朐诎胪该鞯膱D形背后繪制 對象。這不是正確的混色方法,但絕大多數(shù)時(shí)候這種做法在簡單的項(xiàng)目中都工作的很好。
              Rui Martins的補(bǔ)充: 正確的混色過程應(yīng)該是先繪制全部的場景之后再繪制透明的圖形。并且要按照與深度緩存相反的次序來繪制(先畫最遠(yuǎn)的物體)。考慮對兩個(gè)多邊形(1和2)進(jìn)行 alpha混合,不同的繪制次序會(huì)得到不同的結(jié)果。(這里假定多邊形1離觀察者最近,那么正確的過程應(yīng)該先畫多邊形2,再畫多邊形1。正如您再現(xiàn)實(shí)中所見 到的那樣,從這兩個(gè)“透明的”多邊形背后照射來的光線總是先穿過多邊形2,再穿過多邊形1,最后才到達(dá)觀察者的眼睛)。 在深度緩存啟用時(shí),您應(yīng)該將透明圖形按照深度進(jìn)行排序,并在全部場景繪制完畢之后再繪制這些透明物體。否則您將得到不正確的結(jié)果。我知道某些時(shí)候這樣做是 很令人痛苦的,但這是正確的方法。
              我們將使用第七課的代碼。一開始先在代碼開始處增加兩個(gè)新的變量。出于清晰起見,我重寫了整段代碼。

              #include <windows.h>                    // Windows的頭文件
              #include <stdio.h>                     // 標(biāo)準(zhǔn)輸入/輸出庫的頭文件
              #include <gl\gl.h>                     // OpenGL32庫的頭文件
              #include <gl\glu.h>                    // GLu32庫的頭文件
              #include <gl\glaux.h>                   // GLaux庫的頭文件

              HGLRC hRC=NULL;                      // 永久著色描述表
              HDC hDC=NULL;                       // 私有GDI設(shè)備描述表
              HWND hWnd=NULL;                      // 保存我們的窗口句柄
              HINSTANCE hInstance;                    // 保存程序的實(shí)例

              bool keys[256];                      // 用于鍵盤例程的數(shù)組
              bool active=TRUE;                     // 窗口的活動(dòng)標(biāo)志,缺省為TRUE
              bool fullscreen=TRUE;                   // 全屏標(biāo)志缺省設(shè)定成全屏模式

              BOOL light;                        // 光源的開/關(guān)
              bool blend;                        // Blending 開/關(guān) ( 新增 )
              BOOL lp;                          // L鍵按下了么?
              BOOL fp;                          // F鍵按下了么?

              GLfloat xrot;                       // X 旋轉(zhuǎn)
              GLfloat yrot;                       // Y 旋轉(zhuǎn)
              GLfloat xspeed;                      // X 旋轉(zhuǎn)速度
              GLfloat yspeed;                      // Y 旋轉(zhuǎn)速度

              GLfloat z=-5.0f;                      // 深入屏幕的距離

              GLfloat LightAmbient[]= { 0.5f };             // 環(huán)境光參數(shù)
              GLfloat LightDiffuse[]= { 1.0f };              // 漫射光參數(shù)
              GLfloat LightPosition[]= { 0.0f };             // 光源位置

              GLuint filter;                       // 濾波類型
              GLuint texture[3];                     // 3種紋理的儲存空間
              LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   // WndProc定義

              然后往下移動(dòng)到LoadGLTextures()這里。找到“if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))”這一行。我們現(xiàn)在使用有色玻璃紋理來代替上一課中的木箱紋理。

                  if (TextureImage[0]=LoadBMP("Data/glass.bmp"))   // 載入玻璃位圖 (已修改)

              在InitGL()代碼段加入以下兩行。第一行以全亮度繪制此物體,并對其進(jìn)行50%的alpha混合(半透明)。當(dāng)混合選項(xiàng)打開時(shí),此物體將會(huì)產(chǎn)生50%的透明效果。第二行設(shè)置所采用的混合類型。Rui Martins的補(bǔ)充:alpha通道的值為0.0意味著物體材質(zhì)是完全透明的。1.0則意味著完全不透明。

                  glColor4f(1.0f,1.0f,1.0f,0.5f);          // 全亮度, 50% Alpha 混合(新增)
                  glBlendFunc(GL_SRC_ALPHA,GL_ONE); // 基于源象素alpha通道值的半透明混合函數(shù) (新增)

              在接近第七課結(jié)尾處的地方找到下面的代碼段。

                  if (keys[VK_LEFT])                // Left方向鍵按下了么?
                  {
                      yspeed-=0.01f; 
                         // 若是,減少yspeed
                  }

              接著上面的代碼,我們增加如下的代碼。這幾行監(jiān)視B鍵是否按下。如果是的話,計(jì)算機(jī)檢查混合選項(xiàng)是否已經(jīng)打開。然后將其置為相反的狀態(tài)。

                  if (keys[VK_LEFT])                // Left方向鍵按下了么?
                  if (keys[’B’] && !bp)               // B 健按下且bp為 FALSE么?
                  {
                      bp=TRUE;
                             // 若是, bp 設(shè)為 TRUE
                      blend = !blend;              // 切換混合選項(xiàng)的 TRUE / FALSE
                      if(blend)                 // 混合打開了么?
                      {
                          glEnable(GL_BLEND);
                    // 打開混合
                          glDisable(GL_DEPTH_TEST);    // 關(guān)閉深度測試
                      }
                      else
                               // 否則
                      {
                          glDisable(GL_BLEND);
                   // 關(guān)閉混合
                          glEnable(GL_DEPTH_TEST);     // 打開深度測試
                      }
                  }
                  if (!keys[’B’])
                             // B 鍵松開了么?
                  {
                      bp=FALSE;
                            // 若是, bp設(shè)為 FALSE
                  }

            但是怎樣才能在使用紋理貼圖的時(shí)候指定混合時(shí)的顏色呢?很簡單,在調(diào)整貼圖模式時(shí),文理貼圖的每個(gè)象素點(diǎn)的顏色都是由alpha通道參數(shù)與當(dāng)前地象素顏 色相乘所得到的。比如,繪制的顏色是(0.5, 0.6, 0.4),我們會(huì)把顏色相乘得到(0.5, 0.6, 0.4, 0.2)(alpha參數(shù)在沒有指定時(shí),缺省為1.0)。
              就是如此。OpenGL實(shí)現(xiàn)Alpha混合的確很簡單。

              原文注11/13/1999
            我(NeHe)混色代碼進(jìn)行了修改,以使顯示的物體看起來更逼真。同時(shí)對源象素和目的象素使用alpha參數(shù)來混合,會(huì)導(dǎo)致物體的人造痕跡看起來很明 顯。會(huì)使得物體的背面沿著側(cè)面的地方顯得更暗。基本上物體會(huì)看起來很怪異。我所用的混色方法也許不是最好的,但的確能夠工作。啟用光源之后,物體看起來很 逼真。感謝Tom提供的原始代碼,他采用的混色方法是正確的,但物體看起來并不象所期望的那樣吸引人。
              代碼所作的再次修改是因?yàn)樵谀承╋@卡上glDepthMask()函數(shù)存在尋址問題。這條命令在某些卡上啟用或關(guān)閉深度緩沖測試時(shí)似乎不是很有效,所以我已經(jīng)將啟用或關(guān)閉深度緩沖測試的代碼轉(zhuǎn)成老式的glEnableglDisable

            8.3、紋理貼圖的Alpha混合
              用于紋理貼圖的alpha參數(shù)可以象顏色一樣從問題貼圖中讀取。方法如下,您需要在載入所需的材質(zhì)同時(shí)取得其的alpha參數(shù)。然后在調(diào)用glTexImage2D()時(shí)使用GL_RGBA的顏色格式。
            posted on 2007-12-11 18:12 sdfasdf 閱讀(2409) 評論(0)  編輯 收藏 引用 所屬分類: OPENGL
            久久综合久久综合亚洲| 久久精品成人免费国产片小草| 亚洲国产精品无码成人片久久| 久久人人爽人人爽人人av东京热 | 久久性精品| 亚洲狠狠婷婷综合久久久久| 亚洲综合日韩久久成人AV| 久久被窝电影亚洲爽爽爽| 青青青青久久精品国产h久久精品五福影院1421| 中文字幕精品久久| 国产精品99久久久久久猫咪 | 久久亚洲高清综合| 亚洲国产精品无码久久98| 国产成人久久激情91| 伊人久久亚洲综合影院| 香蕉久久av一区二区三区| 久久99精品久久久久久动态图| 久久精品国产只有精品66 | 国产精品成人无码久久久久久 | 久久综合伊人77777麻豆| 精品熟女少妇AV免费久久 | 青青青青久久精品国产h| 久久久久高潮毛片免费全部播放 | 青青热久久国产久精品| 狠狠综合久久综合88亚洲| 粉嫩小泬无遮挡久久久久久| 精品久久久久久无码国产| 亚洲va久久久噜噜噜久久| 久久精品蜜芽亚洲国产AV| 狠狠人妻久久久久久综合| 麻豆成人久久精品二区三区免费 | 蜜臀av性久久久久蜜臀aⅴ| 日本精品久久久久久久久免费| 久久久久久狠狠丁香| 日日狠狠久久偷偷色综合0| 久久99国产精一区二区三区| 亚洲综合伊人久久大杳蕉| 亚洲精品午夜国产va久久| 精品久久久久久无码人妻热 | 久久夜色精品国产欧美乱| 亚洲伊人久久综合影院|