青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁(yè) :: 聯(lián)系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

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

搜索

  •  

積分與排名

  • 積分 - 402530
  • 排名 - 59

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

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

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

  
 接下來(lái)定義了兩個(gè)指向這個(gè)結(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個(gè)字節(jié)
  c = (unsigned char *)malloc( w * h * f);
  if ( c != NULL ) {
   ti->data = c;
  }
  else {
   MessageBox(NULL,"內(nèi)存不足","分配圖像內(nèi)存錯(cuò)誤",MB_OK | MB_ICONINFORMATION);
   return NULL;
  }
 }

 else
 {
  MessageBox(NULL,"內(nèi)存不足","分配圖像結(jié)構(gòu)內(nèi)存錯(cuò)誤",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)存
 }
}

  
 下面我們來(lái)讀取*.raw的文件,這個(gè)函數(shù)有兩個(gè)參數(shù),一個(gè)為文件名,另一個(gè)為保存文件的圖像結(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 )        // 如果文件存在
 {

  
 如果文件存在,我們通過(guò)一個(gè)循環(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ù),并把a(bǔ)lpha設(shè)為255 
  

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

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

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

  
 下面的代碼創(chuàng)建一個(gè)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ù)的地方了,他運(yùn)行你把一個(gè)圖像的任意部分復(fù)制到另一個(gè)圖像的任意部分,并混合。
src為原圖像
dst為目標(biāo)圖像
src_xstart,src_ystart為要復(fù)制的部分在原圖像中的位置
src_width,src_height為要復(fù)制的部分的寬度和高度
dst_xstart,dst_ystart為復(fù)制到目標(biāo)圖像時(shí)的起始位置
上面的意思是把原圖像中的(src_xstart,src_ystart)-(src_width,src_height)復(fù)制到目標(biāo)圖像中(dst_xstart,dst_ystart)-(src_width,src_height)
blend設(shè)置是否啟用混合,0為不啟用,1為啟用
alpha設(shè)置源圖像中顏色在混合時(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);     // 要復(fù)制的像素在目標(biāo)圖像數(shù)據(jù)中的開始位置
 s = src->data + (src_ystart * src->width * src->format);   // 要復(fù)制的像素在源圖像數(shù)據(jù)中的開始位置

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

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

   for( k = 0 ; k < src->format ; k++, d++, s++)   // 復(fù)制每一個(gè)字節(jié)
   {
    if (blend)      // 如果啟用了混合
     *d = ( (*s * alpha) + (*d * (255-alpha)) ) >> 8; // 根據(jù)混合復(fù)制顏色
    else       
     *d = *s;      // 否則直接復(fù)制
   }
  }
  d = d + (dst->width - (src_width + dst_xstart))*dst->format;  // 移動(dòng)到下一行
  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ù)
 {          // 失敗則彈出對(duì)話框
  MessageBox(NULL,"不能讀取 'Monitor.raw' 文件","讀取錯(cuò)誤",MB_OK | MB_ICONINFORMATION);
  return FALSE;
 }

 t2 = AllocateTextureBuffer( 256, 256, 4 );      // 為圖像t2分配內(nèi)存
 if (ReadTextureData("Data/GL.raw",t2)==0)      // 讀取圖像數(shù)據(jù)
 {          // 失敗則彈出對(duì)話框
  MessageBox(NULL,"不能讀取 'GL.raw' 文件","讀取錯(cuò)誤 ",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è)置深度測(cè)試函數(shù)

 return TRUE;
}

  
 下面的代碼繪制一個(gè)盒子 
  

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ù)沒(méi)有變化 
  
  
 CreateGLWindow函數(shù)沒(méi)有變化 
  
  
 WinMain() 沒(méi)有變化 
  
  
 好了,現(xiàn)你可以很輕松的繪制很多混合效果。如果你有什么好的建議,請(qǐng)告訴我。
 

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

Feedback

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

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久国产欧美精品| 亚洲精品免费网站| 亚洲一区二区日本| 免费不卡在线观看| 国产精品多人| 欧美精品一区视频| 欧美人成免费网站| 99精品国产在热久久婷婷| 欧美.日韩.国产.一区.二区| 91久久线看在观草草青青| 亚洲蜜桃精久久久久久久| 亚洲第一精品久久忘忧草社区| 久久av一区二区| 欧美激情中文字幕一区二区| 久久夜色精品国产欧美乱极品| 久久国产日韩欧美| 国产一区二区看久久| 久久精品观看| 亚洲美女中文字幕| 欧美福利视频在线| 国产精品极品美女粉嫩高清在线| 正在播放亚洲一区| 一本色道精品久久一区二区三区 | 亚洲精品乱码久久久久久蜜桃91| 亚洲国产日日夜夜| 亚洲免费精彩视频| 国产美女精品视频免费观看| 欧美一区二区三区的| 一区二区精品国产| 欧美色精品天天在线观看视频 | 性欧美在线看片a免费观看| 久久久久久久一区| 久久精品水蜜桃av综合天堂| 亚洲视屏一区| 欧美激情在线免费观看| 亚洲美女精品成人在线视频| 欧美激情综合色| 宅男精品视频| 久久久国产一区二区三区| 国产亚洲精品一区二区| 99热这里只有成人精品国产| 久久手机免费观看| 一区二区高清视频在线观看| 久久综合久久综合久久综合| 国产精品国产a| 亚洲第一区中文99精品| 一本色道久久| 亚洲高清自拍| 久久久国产视频91| 海角社区69精品视频| 亚洲天堂网站在线观看视频| 国产日韩一区二区三区在线| 欧美激情1区2区3区| 国产一区二区久久久| 亚洲欧美在线观看| 欧美成人三级在线| 亚洲国产精品免费| 国产精品揄拍一区二区| 日韩午夜视频在线观看| 亚洲欧美日韩在线观看a三区| 欧美激情综合色| 欧美精品18+| 欧美成人一区在线| 国产日韩欧美在线播放不卡| 久久xxxx精品视频| 又紧又大又爽精品一区二区| 亚洲国产免费| 最新高清无码专区| 麻豆精品在线视频| 亚洲精品一区二| 久久久久久久成人| 国产精品一区二区女厕厕| 亚洲在线中文字幕| 欧美一区二区视频97| 韩曰欧美视频免费观看| 欧美日韩大片| 国产三区精品| 亚洲欧美日韩一区在线观看| 亚久久调教视频| 伊人久久综合97精品| 国产精品美女久久久久aⅴ国产馆| 久久久久久欧美| 欧美午夜精品电影| aa级大片欧美三级| 亚洲高清激情| 欧美一区不卡| 亚洲婷婷综合久久一本伊一区| 国产欧美日韩在线| 久久精品视频在线免费观看| 亚洲精品极品| 亚洲专区在线| 一区二区成人精品| 日韩视频永久免费| 久久久久99精品国产片| 国产偷自视频区视频一区二区| 欧美韩日一区| 免费日韩av| 国产精品嫩草久久久久| 欧美日韩国产在线看| 欧美不卡视频一区发布| 久久漫画官网| 亚洲视频在线观看视频| 亚洲精品男同| 欧美激情亚洲一区| 最新国产成人在线观看| 久久久国产一区二区三区| 日韩一级在线| 国产精品久久77777| 亚洲国产成人91精品| 亚洲天堂av综合网| 欧美在线综合视频| 国产精品99久久久久久久久| 夜夜嗨av一区二区三区四季av| 欧美在线日韩| 亚洲精品久久在线| 久久久.com| 国产精品女人毛片| 亚洲人成精品久久久久| 欧美激情视频一区二区三区免费 | 欧美+亚洲+精品+三区| 亚洲一区网站| 一区二区精品国产| 久久男女视频| 亚洲每日在线| 欧美日韩在线大尺度| 韩曰欧美视频免费观看| 激情欧美一区二区| 欧美一级午夜免费电影| 欧美一区二区大片| 国产日韩一区二区三区在线播放| 亚洲裸体在线观看| 欧美成人一区二区三区片免费| 久久国产天堂福利天堂| 久久精品国产亚洲精品| 亚洲片国产一区一级在线观看| 午夜日韩福利| 国产精品美女诱惑| 99国产精品国产精品毛片| 亚洲电影免费在线观看| 亚洲天堂成人在线观看| 亚洲欧美视频在线观看| 亚洲精品日韩在线观看| 国产欧美精品日韩精品| 久久久国产午夜精品| 久久久久久网| 亚洲欧美第一页| 欧美亚州韩日在线看免费版国语版| 国产在线麻豆精品观看| 久久美女艺术照精彩视频福利播放| 猛干欧美女孩| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲精品永久免费| 欧美理论片在线观看| 欧美伊人久久久久久久久影院| 麻豆成人小视频| 久久成人免费| 亚洲国产另类久久久精品极度| 欧美成人精精品一区二区频| 亚洲美女色禁图| 老**午夜毛片一区二区三区| 欧美麻豆久久久久久中文| 久久国产精品一区二区三区| 国产精品成人一区二区三区吃奶| 久久一本综合频道| 国产精品av免费在线观看| 久久综合给合久久狠狠色 | 国产精品夫妻自拍| 久久久久久欧美| 久久久91精品国产一区二区三区 | 国产精品第一页第二页第三页| 中国女人久久久| 久久国产精品亚洲va麻豆| 国内自拍一区| 老司机精品导航| 久久精品国产一区二区三区免费看| 国产欧美日韩精品在线| 亚洲视频在线观看视频| 亚洲精选大片| 欧美日韩一二区| 久久精品国产77777蜜臀| 免费看亚洲片| 亚洲电影免费观看高清完整版在线观看 | 久久国产欧美| 午夜亚洲伦理| 久久精品女人的天堂av| 黄色国产精品| 亚洲欧美日韩国产综合在线| 亚洲自拍三区| 欧美性感一类影片在线播放| 亚洲欧美日本国产有色| 亚洲高清视频在线观看| 老妇喷水一区二区三区| 亚洲黄色高清| 亚洲欧美视频在线观看视频| 国产一区二区精品在线观看| 国产精品a久久久久| 午夜精品免费| 久久中文欧美| 亚洲欧美日韩天堂| 欧美日本一区二区三区|