• <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++博客 :: 首頁(yè) :: 聯(lián)系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

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

            搜索

            •  

            積分與排名

            • 積分 - 399102
            • 排名 - 59

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

              歡迎來到第20課的教程,*.bmp圖像被給各種操作系統(tǒng)所支持,因?yàn)樗?jiǎn)單,所以可以很輕松的作為紋理圖片加載它。知道現(xiàn)在,我們?cè)诎褕D像加載到屏幕上時(shí)沒有擦除背景色,因?yàn)檫@樣簡(jiǎn)單高效。但是效果并不總是很好。
            大部分情況下,把紋理混合到屏幕,紋理不是太少就是太多。當(dāng)使用精靈時(shí),我不希望背景從精靈的縫隙中透出光來;但在顯示文字時(shí),你希望文字的間隙可以顯示背景色。

            由于以上原因,我們需要使用“掩模”。使用“掩模”需要兩個(gè)步驟,首先我們?cè)趫?chǎng)景上放置黑白相間的紋理,白色代表透明部分,黑色代表不透明部分。接著我們使用一種特殊的混合方式,只有在黑色部分上的紋理才會(huì)顯示在場(chǎng)景中。

            我只重寫那些改變的地方,如果你做好了學(xué)習(xí)的準(zhǔn)備,我們就上路吧。
             
              
              
             在這個(gè)程序里,我們使用7個(gè)全局變量。變量masking為一個(gè)布爾值,標(biāo)志是否使用“掩模”。變量mp標(biāo)志鍵M是否按下,變量sp標(biāo)志空格是否按下。
            接著我們創(chuàng)建保存5個(gè)紋理標(biāo)志的數(shù)組,loop為循環(huán)變量。變量roll使得紋理沿屏幕滾動(dòng)。
             
              

            bool    masking=TRUE;                    // 是否使用“掩模”
            bool    mp;                        // 鍵M是否按下
            bool    sp;                        // 空格是否按下
            bool    scene;                        // 繪制那一個(gè)場(chǎng)景

            GLuint    texture[5];                    // 保存5個(gè)紋理標(biāo)志
            GLuint    loop;                        // 循環(huán)變量

            GLfloat    roll;                        // 滾動(dòng)紋理

              
             加載紋理代碼基本沒變,只是這里我們需要加載5個(gè)紋理 
              

            int LoadGLTextures()                       
            {
                int Status=FALSE;                       
                AUX_RGBImageRec *TextureImage[5];                // 創(chuàng)建保存5個(gè)紋理的數(shù)據(jù)結(jié)構(gòu)
                memset(TextureImage,0,sizeof(void *)*5);            // 初始化

                if ((TextureImage[0]=LoadBMP("Data/logo.bmp")) &&        // 加載紋理0
                    (TextureImage[1]=LoadBMP("Data/mask1.bmp")) &&        // 加載掩模紋理1,作為“掩模”使用
                    (TextureImage[2]=LoadBMP("Data/image1.bmp")) &&        // 加載紋理1
                    (TextureImage[3]=LoadBMP("Data/mask2.bmp")) &&        // 加載掩模紋理2,作為“掩模”使用
                    (TextureImage[4]=LoadBMP("Data/image2.bmp")))        // 加載紋理2
                {
                    Status=TRUE;                       
                    glGenTextures(5, &texture[0]);                // 創(chuàng)建5個(gè)紋理

                    for (loop=0; loop<5; loop++)                // 循環(huán)加載5個(gè)紋理
                    {
                        glBindTexture(GL_TEXTURE_2D, texture[loop]);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
                            0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
                    }
                }
                for (loop=0; loop<5; loop++)                   
                {
                    if (TextureImage[loop])                   
                    {
                        if (TextureImage[loop]->data)           
                        {
                            free(TextureImage[loop]->data);       
                        }
                        free(TextureImage[loop]);           
                    }
                }
                return Status;                       
            }

              
             改變窗口大小和初始化OpenGL的函數(shù)沒有變化
             
              
              
             現(xiàn)在到了最有趣的繪制部分了,我們從清楚背景色開始,接著把物體移入屏幕2個(gè)單位。 
              

            int DrawGLScene(GLvoid)       
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);           
                glLoadIdentity();                           
                glTranslatef(0.0f,0.0f,-2.0f);                        // 物體移入屏幕2個(gè)單位
              
             下面一行,我們選擇'logo'紋理。我們將要通過四邊形把紋理映射到屏幕,并按照頂點(diǎn)的順序設(shè)置紋理坐標(biāo)。
            Jonathan Roy說OpenGL是一個(gè)基于頂點(diǎn)的圖形系統(tǒng),大部分你設(shè)置的參數(shù)是作為頂點(diǎn)的屬性而記錄的,紋理坐標(biāo)就是這樣一種屬性。你只要簡(jiǎn)單的設(shè)置各個(gè)頂點(diǎn)的紋理坐標(biāo),OpenGL就自動(dòng)幫你把多邊形內(nèi)部填充紋理,通過一個(gè)插值的過程。

            向前面幾課一樣,我們假定四邊形面對(duì)我們,并把紋理坐標(biāo)(0,0)綁定到左下角,(1,0)綁定到右下角,(1,1)綁定到右上角。給定這些設(shè)置,你應(yīng)該能猜到四邊形中間對(duì)應(yīng)的紋理坐標(biāo)為(0.5,0.5),但你自己并沒有設(shè)置此處的紋理坐標(biāo)!OpenGL為你做了計(jì)算。

            在這一課里,我們通過設(shè)置紋理坐標(biāo)達(dá)到一種滾動(dòng)紋理的目的。紋理坐標(biāo)是被歸一化的,它的范圍從0.0-1.0,值0被映射到紋理的一邊,值1被映射到紋理的另一邊。超過1的值,紋理可以按照不同的方式被映射,這里我們?cè)O(shè)置為它將回繞道另一邊并重復(fù)紋理。例如如果使用這樣的映射方式,紋理坐標(biāo)(0.3,0.5)和(1.3,0.5)被映射到同一個(gè)紋理坐標(biāo)。在這一課里,我們將嘗試一種無縫填充的效果。



             我們使用roll變量去設(shè)置紋理坐標(biāo),當(dāng)它為0時(shí),它把紋理的左下角映射到四邊形的左下角。當(dāng)它大于0時(shí),把紋理的左上角映射到四邊形的左下角,看起來的效果就是紋理沿四邊形向上滾動(dòng)。 
              

                glBindTexture(GL_TEXTURE_2D, texture[0]);                // 選擇Logo紋理
                glBegin(GL_QUADS);                            // 繪制紋理四邊形
                    glTexCoord2f(0.0f, -roll+0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);   
                    glTexCoord2f(3.0f, -roll+0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);   
                    glTexCoord2f(3.0f, -roll+3.0f); glVertex3f( 1.1f,  1.1f,  0.0f);   
                    glTexCoord2f(0.0f, -roll+3.0f); glVertex3f(-1.1f,  1.1f,  0.0f);   
                glEnd();       
              
             啟用混合和禁用深度測(cè)試 
              

                glEnable(GL_BLEND);                            // 啟用混合
                glDisable(GL_DEPTH_TEST);                            // 禁用深度測(cè)試

              
             接下來我們需要根據(jù)masking的值設(shè)置是否使用“掩模”,如果是,則需要設(shè)置相應(yīng)的混合系數(shù)。 
              

                if (masking)                                // 是否啟用“掩模”
                {

              
             如果啟用了“掩模”,我們將要設(shè)置“掩模”的混合系數(shù)。一個(gè)“掩模”只是一幅繪制到屏幕的紋理圖片,但只有黑色和白色。白色的部分代表透明,黑色的部分代表不透明。
            下面這個(gè)混合系數(shù)使得,任何對(duì)應(yīng)“掩模”黑色的部分會(huì)變?yōu)楹谏咨牟糠謺?huì)保持原來的顏色。
             
              

                    glBlendFunc(GL_DST_COLOR,GL_ZERO);                    // 使用黑白“掩模”混合屏幕顏色
                }

              
             現(xiàn)在我們檢查繪制那一個(gè)層,如果為True繪制第二個(gè)層,否則繪制第一個(gè)層 
              

                if (scene)   
                {

              
             為了不使它看起來顯得非常大,我們把它移入屏幕一個(gè)單位,并把它按roll變量的值進(jìn)行旋轉(zhuǎn)(沿Z軸)。 
              

                    glTranslatef(0.0f,0.0f,-1.0f);                    // 移入屏幕一個(gè)單位
                    glRotatef(roll*360,0.0f,0.0f,1.0f);                    // 沿Z軸旋轉(zhuǎn)

              
             接下我們檢查masking的值來繪制我們的對(duì)象 
              

                    if (masking)                            // “掩模”是否打開
                    {

              
             如果“掩模打開”,我們會(huì)把掩模繪制到屏幕。當(dāng)我們完成這個(gè)操作時(shí),將會(huì)看到一個(gè)鏤空的紋理出現(xiàn)在屏幕上。 
              

                        glBindTexture(GL_TEXTURE_2D, texture[3]);        // 選擇第二個(gè)“掩模”紋理
                        glBegin(GL_QUADS);                    // 開始繪制四邊形
                            glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);   
                            glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);   
                            glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.1f,  1.1f,  0.0f);   
                            glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.1f,  1.1f,  0.0f);   
                        glEnd();                       
                    }

              
             當(dāng)我們把“掩模”繪制到屏幕上后,接著我們變換混合系數(shù)。這次我們告訴OpenGL把任何黑色部分對(duì)應(yīng)的像素復(fù)制到屏幕,這樣看起來紋理就像被鏤空一樣帖子屏幕上。
            注意,我們?cè)谧儞Q了混合模式后在選擇的紋理。

            如果我們沒有使用“掩模”,我們的圖像將與屏幕顏色混合。
             
              

                    glBlendFunc(GL_ONE, GL_ONE);                // 把紋理2復(fù)制到屏幕
                    glBindTexture(GL_TEXTURE_2D, texture[4]);            // 選擇第二個(gè)紋理
                    glBegin(GL_QUADS);                        // 繪制四邊形
                        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);   
                        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);   
                        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.1f,  1.1f,  0.0f);   
                        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.1f,  1.1f,  0.0f);   
                    glEnd();                       
                }

              
             繪制第一層圖像 
              

                else                                   
                {

              
             如果“掩模打開”,我們會(huì)把掩模繪制到屏幕。當(dāng)我們完成這個(gè)操作時(shí),將會(huì)看到一個(gè)鏤空的紋理出現(xiàn)在屏幕上。 
              

                    if (masking)                            // “掩模”是否打開
                    {

              
             如果“掩模打開”,我們會(huì)把掩模繪制到屏幕。當(dāng)我們完成這個(gè)操作時(shí),將會(huì)看到一個(gè)鏤空的紋理出現(xiàn)在屏幕上。 
              

                        glBindTexture(GL_TEXTURE_2D, texture[1]);        // 選擇第一個(gè)“掩模”紋理
                        glBegin(GL_QUADS);                    // 開始繪制四邊形
                            glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);   
                            glTexCoord2f(roll+4.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);   
                            glTexCoord2f(roll+4.0f, 4.0f); glVertex3f( 1.1f,  1.1f,  0.0f);   
                            glTexCoord2f(roll+0.0f, 4.0f); glVertex3f(-1.1f,  1.1f,  0.0f);   
                        glEnd();                       
                    }

              
             當(dāng)我們把“掩模”繪制到屏幕上后,接著我們變換混合系數(shù)。這次我們告訴OpenGL把任何黑色部分對(duì)應(yīng)的像素復(fù)制到屏幕,這樣看起來紋理就像被鏤空一樣帖子屏幕上。
            注意,我們?cè)谧儞Q了混合模式后在選擇的紋理。

            如果我們沒有使用“掩模”,我們的圖像將與屏幕顏色混合。
             
              

                    glBlendFunc(GL_ONE, GL_ONE);                    // 把紋理1復(fù)制到屏幕
                    glBindTexture(GL_TEXTURE_2D, texture[2]);                // 選擇第一個(gè)紋理
                    glBegin(GL_QUADS);                            // 開始繪制四邊形
                        glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);   
                        glTexCoord2f(roll+4.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);   
                        glTexCoord2f(roll+4.0f, 4.0f); glVertex3f( 1.1f,  1.1f,  0.0f);   
                        glTexCoord2f(roll+0.0f, 4.0f); glVertex3f(-1.1f,  1.1f,  0.0f);   
                    glEnd();           
                }

              
             接下來啟用深度測(cè)試,禁用混合。 
              

                glEnable(GL_DEPTH_TEST);                            // 啟用深度測(cè)試
                glDisable(GL_BLEND);                            // 禁用混合

              
             最后增加roll變量,如果大于1,把它的值減1。 
              

                roll+=0.002f;                                // 增加紋理滾動(dòng)變量
                if (roll>1.0f)                                // 大于1則減1
                {
                    roll-=1.0f;                       
                }

                return TRUE;                                // 成功返回
            }

              
             函數(shù)KillGLWindow(), CreateGLWindow() 和 WndProc() 沒有改變。
             
              
              
             接下來在wWinMain,我們添加鍵盤控制函數(shù)。我們檢查空格是否按下,如果是則設(shè)置sp變量為TRUE,sp變量用來切換場(chǎng)景。 
              

                            if (keys[' '] && !sp)                // 空格鍵是否被按下?
                            {
                                sp=TRUE;               
                                scene=!scene;                // 是則切換場(chǎng)景
                            }

              
             如果空格鍵釋放,記錄下來 
              

                            if (!keys[' '])                    // 如果空格鍵釋放,記錄下來
                            {
                                sp=FALSE;               
                            }

              
             我們檢查M鍵是否按下,如果是則設(shè)置mp變量為TRUE,sp變量用來切換是否使用“掩模” 
              

                            if (keys['M'] && !mp)                // M鍵是否被按下
                            {
                                mp=TRUE;               
                                masking=!masking;                // 是則切換“掩模”
                            }

              
             如果M鍵釋放,記錄下來 
              

                            if (!keys['M'])                    // 如果M鍵釋放,記錄下來
                            {
                                mp=FALSE;               
                            }

              
             Eric Desrosiers指出,你也可以在載入的時(shí)候測(cè)試*.bmp圖像中的每一個(gè)像素,如果你你想要透明的結(jié)果,你可以把顏色的alpha設(shè)置為0。對(duì)于其他的顏色,你可以把a(bǔ)lpha設(shè)置為1。這個(gè)方法也能達(dá)到同樣的效果,但需要一些額外的代碼。
            在這課里,我們給你演示了一個(gè)簡(jiǎn)單的例子,它能高效的繪制一部分紋理而不使用alpha值。

            謝謝Rob Santa的想法和例子程序,我從沒想到過這種方法。

            我希望你喜歡這個(gè)教程,如果你在理解上有任何問題或找到了任何錯(cuò)誤,請(qǐng)我知道,我想做最好的教程,你的反饋是非常重要的。

             


            posted on 2007-12-17 16:49 sdfasdf 閱讀(1010) 評(píng)論(0)  編輯 收藏 引用 所屬分類: OPENGL
            欧美久久亚洲精品| 国产精品久久久久影视不卡| 久久―日本道色综合久久| 亚洲国产精品无码久久久不卡| 精品国产91久久久久久久a| 热re99久久精品国产99热| 97超级碰碰碰碰久久久久| 狠狠色丁香久久综合五月| 久久精品男人影院| 国产高清国内精品福利99久久| 国产精品VIDEOSSEX久久发布| 国产免费福利体检区久久| 香蕉99久久国产综合精品宅男自 | 人妻精品久久久久中文字幕69| 一本一道久久a久久精品综合| 色8激情欧美成人久久综合电| 久久精品国产精品亚洲人人 | 久久久噜噜噜久久| 久久伊人精品青青草原日本| 午夜精品久久久久| 99精品久久久久久久婷婷| 久久亚洲精品成人AV| 亚洲一本综合久久| 日日狠狠久久偷偷色综合免费| 欧美精品国产综合久久| 久久久久高潮毛片免费全部播放| 国产综合久久久久久鬼色| 国产日韩久久久精品影院首页| 久久久久久久91精品免费观看 | 久久香蕉国产线看观看99| 久久99精品久久久久久水蜜桃| 综合久久给合久久狠狠狠97色| 一本色综合网久久| 一级做a爰片久久毛片人呢| 久久夜色精品国产噜噜亚洲a| 久久精品无码专区免费东京热| 国产成人精品久久亚洲高清不卡 | 欧美日韩精品久久久免费观看| 久久婷婷五月综合国产尤物app | 久久久久成人精品无码| 欧美噜噜久久久XXX|