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

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 400062
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

            這篇文章是有Andreas Lffler所寫的,它寫了一份原始的教程。過了幾天,Rob Fletcher發(fā)了封郵件給我,他重新改寫了所有的代碼,我在它的基礎(chǔ)上把glut的框架變換為Win32的框架。
            現(xiàn)在讓我們開始吧!
             
              
              
             下面是一個保存圖像數(shù)據(jù)的結(jié)構(gòu) 
              

            typedef struct Texture_Image
            {
             int width;         // 寬
             int height;         // 高
             int format;         // 像素格式
             unsigned char *data;        // 紋理數(shù)據(jù)
            } TEXTURE_IMAGE;

              
             接下來定義了兩個指向這個結(jié)構(gòu)的指針 
              

            typedef TEXTURE_IMAGE *P_TEXTURE_IMAGE;       

            P_TEXTURE_IMAGE t1;         // 指向保存圖像結(jié)構(gòu)的指針
            P_TEXTURE_IMAGE t2;         // 指向保存圖像結(jié)構(gòu)的指針

              
             下面的函數(shù)為w*h的圖像分配內(nèi)存 
              

            P_TEXTURE_IMAGE AllocateTextureBuffer( GLint w, GLint h, GLint f)
            {
             P_TEXTURE_IMAGE ti=NULL;       
             unsigned char *c=NULL;        
             ti = (P_TEXTURE_IMAGE)malloc(sizeof(TEXTURE_IMAGE));     // 分配圖像結(jié)構(gòu)內(nèi)存

             if( ti != NULL ) {
              ti->width  = w;        // 設(shè)置寬度
              ti->height = h;        // 設(shè)置高度
              ti->format = f;        // 設(shè)置格式
              // 分配w*h*f個字節(jié)
              c = (unsigned char *)malloc( w * h * f);
              if ( c != NULL ) {
               ti->data = c;
              }
              else {
               MessageBox(NULL,"內(nèi)存不足","分配圖像內(nèi)存錯誤",MB_OK | MB_ICONINFORMATION);
               return NULL;
              }
             }

             else
             {
              MessageBox(NULL,"內(nèi)存不足","分配圖像結(jié)構(gòu)內(nèi)存錯誤",MB_OK | MB_ICONINFORMATION);
              return NULL;
             }
             return ti;         // 返回指向圖像數(shù)據(jù)的指針
            }

              
             下面的函數(shù)釋放分配的內(nèi)存 
              

            // 釋放圖像內(nèi)存
            void DeallocateTexture( P_TEXTURE_IMAGE t )
            {
             if(t)
             {
              if(t->data)
              {
               free(t->data);       // 釋放圖像內(nèi)存
              }

              free(t);         // 釋放圖像結(jié)構(gòu)內(nèi)存
             }
            }

              
             下面我們來讀取*.raw的文件,這個函數(shù)有兩個參數(shù),一個為文件名,另一個為保存文件的圖像結(jié)構(gòu)指針。 
              

            // 讀取*.RAW文件,并把圖像文件上下翻轉(zhuǎn)一符合OpenGL的使用格式。
            int ReadTextureData ( char *filename, P_TEXTURE_IMAGE buffer)
            {
             FILE *f;
             int i,j,k,done=0;
             int stride = buffer->width * buffer->format;     // 記錄每一行的寬度,以字節(jié)為單位
             unsigned char *p = NULL;

             f = fopen(filename, "rb");       // 打開文件
             if( f != NULL )        // 如果文件存在
             {

              
             如果文件存在,我們通過一個循環(huán)讀取我們的紋理,我們從圖像的最下面一行,一行一行的讀取圖像。 
              

              for( i = buffer->height-1; i >= 0 ; i-- )    // 循環(huán)所有的行,從最下面以行開始,一行一行的讀取
              {
               p = buffer->data + (i * stride );
               for ( j = 0; j < buffer->width ; j++ )   // 讀取每一行的數(shù)據(jù)
               {

              
             下面的循環(huán)讀取每一像素的數(shù)據(jù),并把alpha設(shè)為255 
              

                for ( k = 0 ; k < buffer->format-1 ; k++, p++, done++ )
                {
                 *p = fgetc(f);     // 讀取一個字節(jié)
                }
                *p = 255; p++;      // 把255存儲在alpha通道中
               }
              }
              fclose(f);        // 關(guān)閉文件
             }

              
             如果出現(xiàn)錯誤,彈出一個提示框 
              

             else      
             {
              MessageBox(NULL,"不能打開文件","圖像錯誤",MB_OK | MB_ICONINFORMATION);
             }
             return done;         // 返回讀取的字節(jié)數(shù)
            }

              
             下面的代碼創(chuàng)建一個2D紋理,和前面課程介紹的方法相同 
              

            void BuildTexture (P_TEXTURE_IMAGE tex)
            {
             glGenTextures(1, &texture[0]);
             glBindTexture(GL_TEXTURE_2D, texture[0]);
             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
             gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tex->width, tex->height, GL_RGBA, GL_UNSIGNED_BYTE, tex->data);
            }

              
             現(xiàn)在到了blitter函數(shù)的地方了,他運行你把一個圖像的任意部分復制到另一個圖像的任意部分,并混合。
            src為原圖像
            dst為目標圖像
            src_xstart,src_ystart為要復制的部分在原圖像中的位置
            src_width,src_height為要復制的部分的寬度和高度
            dst_xstart,dst_ystart為復制到目標圖像時的起始位置
            上面的意思是把原圖像中的(src_xstart,src_ystart)-(src_width,src_height)復制到目標圖像中(dst_xstart,dst_ystart)-(src_width,src_height)
            blend設(shè)置是否啟用混合,0為不啟用,1為啟用
            alpha設(shè)置源圖像中顏色在混合時所占的百分比  
              

            void Blit( P_TEXTURE_IMAGE src, P_TEXTURE_IMAGE dst, int src_xstart, int src_ystart, int src_width, int src_height,
                int dst_xstart, int dst_ystart, int blend, int alpha)
            {
             int i,j,k;
             unsigned char *s, *d;        

             // 掐斷alpha的值
             if( alpha > 255 ) alpha = 255;
             if( alpha < 0 ) alpha = 0;

             // 判斷是否啟用混合
             if( blend < 0 ) blend = 0;
             if( blend > 1 ) blend = 1;

             d = dst->data + (dst_ystart * dst->width * dst->format);     // 要復制的像素在目標圖像數(shù)據(jù)中的開始位置
             s = src->data + (src_ystart * src->width * src->format);   // 要復制的像素在源圖像數(shù)據(jù)中的開始位置

             for (i = 0 ; i < src_height ; i++ )      // 循環(huán)每一行
             {

              s = s + (src_xstart * src->format);     // 移動到下一個像素
              d = d + (dst_xstart * dst->format);    
              for (j = 0 ; j < src_width ; j++ )     // 循環(huán)復制一行
              {

               for( k = 0 ; k < src->format ; k++, d++, s++)   // 復制每一個字節(jié)
               {
                if (blend)      // 如果啟用了混合
                 *d = ( (*s * alpha) + (*d * (255-alpha)) ) >> 8; // 根據(jù)混合復制顏色
                else       
                 *d = *s;      // 否則直接復制
               }
              }
              d = d + (dst->width - (src_width + dst_xstart))*dst->format;  // 移動到下一行
              s = s + (src->width - (src_width + src_xstart))*src->format;  
             }
            }

              
             初始化代碼基本不變,我們使用新的函數(shù),加載*.raw紋理。并把紋理t2的一部分blit到t1中混合,接著按常規(guī)的方法設(shè)置2D紋理。 
              

            int InitGL(GLvoid)
            {
             t1 = AllocateTextureBuffer( 256, 256, 4 );      // 為圖像t1分配內(nèi)存
             if (ReadTextureData("Data/Monitor.raw",t1)==0)     // 讀取圖像數(shù)據(jù)
             {          // 失敗則彈出對話框
              MessageBox(NULL,"不能讀取 'Monitor.raw' 文件","讀取錯誤",MB_OK | MB_ICONINFORMATION);
              return FALSE;
             }

             t2 = AllocateTextureBuffer( 256, 256, 4 );      // 為圖像t2分配內(nèi)存
             if (ReadTextureData("Data/GL.raw",t2)==0)      // 讀取圖像數(shù)據(jù)
             {          // 失敗則彈出對話框
              MessageBox(NULL,"不能讀取 'GL.raw' 文件","讀取錯誤 ",MB_OK | MB_ICONINFORMATION);
              return FALSE;
             }

              
             把圖像t2的(127,127)-(256,256)部分和圖像t1的(64,64,196,196)部分混合 
              

             // 把圖像t2的(127,127)-(256,256)部分和圖像t1的(64,64,196,196)部分混合
             Blit(t2,t1,127,127,128,128,64,64,1,127);     

              
             下面的代碼和前面一樣,釋放分配的空間,創(chuàng)建紋理 
              

             BuildTexture (t1);        // 把t1圖像加載為紋理

             DeallocateTexture( t1 );       // 釋放圖像數(shù)據(jù)
             DeallocateTexture( t2 );      

             glEnable(GL_TEXTURE_2D);       // 使用2D紋理

             glShadeModel(GL_SMOOTH);       // 使用光滑著色
             glClearColor(0.0f, 0.0f, 0.0f, 0.0f);     // 設(shè)置背景色為黑色
             glClearDepth(1.0);        // 設(shè)置深度緩存清楚值為1
             glEnable(GL_DEPTH_TEST);       // 使用深度緩存
             glDepthFunc(GL_LESS);       // 設(shè)置深度測試函數(shù)

             return TRUE;
            }

              
             下面的代碼繪制一個盒子 
              

            GLvoid DrawGLScene(GLvoid)
            {
             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清楚顏色緩存和深度緩存
             glLoadIdentity();       
             glTranslatef(0.0f,0.0f,-5.0f);

             glRotatef(xrot,1.0f,0.0f,0.0f);
             glRotatef(yrot,0.0f,1.0f,0.0f);
             glRotatef(zrot,0.0f,0.0f,1.0f);

             glBindTexture(GL_TEXTURE_2D, texture[0]);

             glBegin(GL_QUADS);
              // 前面
              glNormal3f( 0.0f, 0.0f, 1.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
              // 后面
              glNormal3f( 0.0f, 0.0f,-1.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
              // 上面
              glNormal3f( 0.0f, 1.0f, 0.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
              // 下面
              glNormal3f( 0.0f,-1.0f, 0.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
              // 右面
              glNormal3f( 1.0f, 0.0f, 0.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
              // 左面
              glNormal3f(-1.0f, 0.0f, 0.0f);
              glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
              glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
              glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
              glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
             glEnd();

             xrot+=0.3f;
             yrot+=0.2f;
             zrot+=0.4f;
             return TRUE; // 一切 OK
            }

              
             KillGLWindow() 函數(shù)沒有變化 
              
              
             CreateGLWindow函數(shù)沒有變化 
              
              
             WinMain() 沒有變化 
              
              
             好了,現(xiàn)你可以很輕松的繪制很多混合效果。如果你有什么好的建議,請告訴我。
             

            posted on 2007-12-20 11:57 sdfasdf 閱讀(752) 評論(1)  編輯 收藏 引用 所屬分類: OPENGL

            Feedback

            # re: NEHE的OPENGL中文教程 第29課 Blitter 函數(shù): 2007-12-20 20:40 sun
            頂一下  回復  更多評論
              

            99精品久久久久久久婷婷| 四虎影视久久久免费观看| 久久国产亚洲高清观看| 亚洲日韩中文无码久久| 国产精品久久久久无码av | 97视频久久久| 久久久久无码精品国产不卡| 国产精品一区二区久久精品无码 | 久久人人爽爽爽人久久久| 久久久久四虎国产精品| 区久久AAA片69亚洲| 久久99热国产这有精品| 久久精品国产亚洲av麻豆图片| 久久99国产精品99久久| 久久婷婷色香五月综合激情| 久久久久久久综合日本亚洲| 亚洲精品国产第一综合99久久 | 亚洲中文字幕久久精品无码APP | 久久青草国产精品一区| 国产成人综合久久精品红| 伊人色综合久久| 久久综合亚洲欧美成人| 久久亚洲精品国产亚洲老地址 | 免费一级欧美大片久久网| 97久久超碰成人精品网站| 中文字幕乱码人妻无码久久| 久久精品成人欧美大片| 97久久精品人人澡人人爽| 国内精品久久久久影院日本| 久久人人爽人人爽人人爽| 午夜精品久久久久久影视777| 99久久免费国产精品| 久久亚洲精品视频| 久久国产精品久久久| 国产麻豆精品久久一二三| 久久人人爽人人爽人人AV| 99久久国产精品免费一区二区| 2021国内久久精品| 波多野结衣久久一区二区| 精品多毛少妇人妻AV免费久久| 精品伊人久久久|