CxImage与OpenGL结合

//使用CxImage来为OpenGL读入多种格式的纹理 
//CxImage是一个开源的图片处理函数库,支持的文件格式有: 
//CXIMAGE_FORMAT_BMP 
//CXIMAGE_FORMAT_GIF 
//CXIMAGE_FORMAT_ICO 
//CXIMAGE_FORMAT_JP2 
//CXIMAGE_FORMAT_JPC 
//CXIMAGE_FORMAT_JPG 
//CXIMAGE_FORMAT_PCX 
//CXIMAGE_FORMAT_PGX 
//CXIMAGE_FORMAT_PNG 
//CXIMAGE_FORMAT_PNM 
//CXIMAGE_FORMAT_RAS 
//CXIMAGE_FORMAT_TGA 
//CXIMAGE_FORMAT_TIF 
//CXIMAGE_FORMAT_UNKNOWN 
//CXIMAGE_FORMAT_WBMP 
//CXIMAGE_FORMAT_WMF 
//们知道OpenGL自带有读取图形文件作纹理的函数,但功能很弱,只支持BMP图片 
//如果要读取其它格式的纹理,就需要用到第三方函数库了。这里我们介绍CxImage 
//CxImage下载:www.xdp.it 
//以下代码是用来读取JPG文件的,紧供参考。 

//读入纹理,支持读入一个alpha纹理,alpha纹理的大小必须与原图一至。 
//LoadTexture("pic.jpg",NULL,resultID); //读入单个JPG图片作纹理 
//LoadTexture("pic.jpg","pic_alpha.jpg",resultID); //读入一个纹理图,及一个用于透明过滤的alpha图 
//LoadTexture("pic.png",NULL,resultID) //读入一个自身带有透明信息的图片作纹理。 

None.gif bool CCxImage_GLView::LoadTexture( const  char *tex_name,  const  char *alpha_name, unsigned  int &texID) 
ExpandedBlockStart.gif
InBlock.gif   // TODO: Add your command handler code here 
InBlock.gif
   CxImage image ,alpha,blendTex;// 
InBlock.gif

InBlock.gif
InBlock.gif   unsigned char *pImage_RGBA = NULL; 
InBlock.gif
InBlock.gif
InBlock.gif   // Load the bitmap using the aux function stored in glaux.lib 
InBlock.gif   
//pImage = auxDIBImageLoad(tex_name); 
InBlock.gif
   image.Load(tex_name); 
InBlock.gif   // Make sure valid image data was given to pImage, otherwise return false 
InBlock.gif
   if(!image.IsValid()) 
InBlock.gif      return false
InBlock.gif
InBlock.gif   int sizeX,sizeY; 
InBlock.gif   sizeX = image.GetWidth(); 
InBlock.gif   sizeY = image.GetHeight(); 
InBlock.gif
InBlock.gif   float texAspectRatio = (float)sizeX / (float)sizeY; 
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif   if(alpha_name && strlen(alpha_name) > 0 ) 
ExpandedSubBlockStart.gif   { 
InBlock.gif         int imageSize_RGB  = sizeX * sizeY * 3; 
InBlock.gif         int imageSize_RGBA = sizeX * sizeY * 4; 
InBlock.gif         alpha.Load(alpha_name);    
InBlock.gif         if(!alpha.IsValid()) 
ExpandedSubBlockStart.gif         { 
InBlock.gif            return false
ExpandedSubBlockEnd.gif         } 
InBlock.gif         // allocate buffer for a RGBA image 
InBlock.gif
         pImage_RGBA = new unsigned char[imageSize_RGBA]; 
InBlock.gif       
InBlock.gif
InBlock.gif         RGBQUAD col_image,col_alpha; 
InBlock.gif          
InBlock.gif      for(int y=0;y<sizeY;y++) 
InBlock.gif         for(int x=0;x<sizeX;x++) 
ExpandedSubBlockStart.gif            { 
InBlock.gif               col_image = image.GetPixelColor(x,y,false); 
InBlock.gif               col_alpha = alpha.GetPixelColor(x,y,false); 
InBlock.gif               pImage_RGBA[(x+y*sizeX)*4 +0] = col_image.rgbRed; 
InBlock.gif               pImage_RGBA[(x+y*sizeX)*4 +1] = col_image.rgbGreen; 
InBlock.gif               pImage_RGBA[(x+y*sizeX)*4 +2] = col_image.rgbBlue; 
InBlock.gif               pImage_RGBA[(x+y*sizeX)*4 +3] = col_alpha.rgbRed; 
ExpandedSubBlockEnd.gif            } 
InBlock.gif
InBlock.gif
InBlock.gif          
InBlock.gif
InBlock.gif         glGenTextures(1, &texID); 
InBlock.gif         glBindTexture(GL_TEXTURE_2D, texID); 
InBlock.gif
InBlock.gif         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
InBlock.gif         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
InBlock.gif         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);    
InBlock.gif         // Don't forget to use GL_RGBA for our new image datadot.gif we support Alpha transparency now! 
InBlock.gif      
// Build Mipmaps (builds different versions of the picture for distances - looks better) 
InBlock.gif
         gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX, 
InBlock.gif            sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA);    
InBlock.gif      if(pImage_RGBA) 
ExpandedSubBlockStart.gif      { 
InBlock.gif         delete [] pImage_RGBA; 
ExpandedSubBlockEnd.gif      } 
InBlock.gif
ExpandedSubBlockEnd.gif   } 
InBlock.gif   else if(image.AlphaIsValid()) 
ExpandedSubBlockStart.gif   { 
InBlock.gif         int imageSize_RGB  = sizeX * sizeY * 3; 
InBlock.gif         long imageSize_RGBA = sizeX * sizeY * 4; 
InBlock.gif         // allocate buffer for a RGBA image 
InBlock.gif      
//   pImage_RGBA = new unsigned char[imageSize_RGBA]; 
InBlock.gif

InBlock.gif      image.Encode2RGBA(pImage_RGBA,imageSize_RGBA); 
InBlock.gif       
InBlock.gif      // Generate a texture with the associative texture ID stored in the array 
InBlock.gif
      glGenTextures(1, &texID); 
InBlock.gif       
InBlock.gif      // This sets the alignment requirements for the start of each pixel row in memory. 
InBlock.gif      
//   glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 
InBlock.gif       
InBlock.gif      
// Bind the texture to the texture arrays index and init the texture 
InBlock.gif
      glBindTexture(GL_TEXTURE_2D, texID); 
InBlock.gif       
InBlock.gif
InBlock.gif      //Assign the mip map levels and texture info 
InBlock.gif      
//   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
InBlock.gif
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
InBlock.gif      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
InBlock.gif      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
InBlock.gif      // Build Mipmaps (builds different versions of the picture for distances - looks better) 
InBlock.gif
      gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX, 
InBlock.gif            sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA);    
InBlock.gif       
InBlock.gif      image.FreeMemory( pImage_RGBA); 
ExpandedSubBlockEnd.gif   } 
InBlock.gif   else 
ExpandedSubBlockStart.gif   { 
InBlock.gif      // Generate a texture with the associative texture ID stored in the array 
InBlock.gif
      glGenTextures(1, &texID); 
InBlock.gif       
InBlock.gif      // This sets the alignment requirements for the start of each pixel row in memory. 
InBlock.gif      
//   glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 
InBlock.gif       
InBlock.gif      
// Bind the texture to the texture arrays index and init the texture 
InBlock.gif
      glBindTexture(GL_TEXTURE_2D, texID); 
InBlock.gif       
InBlock.gif
InBlock.gif      //Assign the mip map levels and texture info 
InBlock.gif      
//   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
InBlock.gif
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
InBlock.gif      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
InBlock.gif      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
InBlock.gif      // Build Mipmaps (builds different versions of the picture for distances - looks better) 
InBlock.gif
      gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sizeX, 
InBlock.gif         sizeY, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.GetBits()); 
InBlock.gif       
ExpandedSubBlockEnd.gif   } 
InBlock.gif   //glEnable(GL_TEXTURE_2D); 
InBlock.gif   
// Now we need to free the image data that we loaded since openGL stored it as a texture 
InBlock.gif

InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif   return true
ExpandedBlockEnd.gif
None.gif

//用来保存屏幕到图像文件。
None.gif void CCxImage_GLView::OnSaveScene() 
ExpandedBlockStart.gif
InBlock.gif
InBlock.gif
InBlock.gif   // TODO: Add your command handler code here 
InBlock.gif
   static char BASED_CODE szFilter[] = "jpg Files (*.jpg)|*.jpg|bmp Files (*.bmp)|*.bmp|tga Files (*.tga)|*.tga|All Files (*.*)|*.*||"; 
InBlock.gif  
InBlock.gif
InBlock.gif   CString filename; 
InBlock.gif    
InBlock.gif   CString ext = ""; 
InBlock.gif
InBlock.gif   if(filename.IsEmpty()) 
InBlock.gif      filename = "NoName"; 
InBlock.gif
InBlock.gif   CFileDialog dlg(false, "jpg",filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); 
InBlock.gif
InBlock.gif   if(dlg.DoModal() == IDOK) 
ExpandedSubBlockStart.gif   { 
InBlock.gif
InBlock.gif   ext = dlg.GetFileExt(); 
InBlock.gif   filename = dlg.GetPathName(); 
InBlock.gif
InBlock.gif
InBlock.gif      //CDC* m_pDC;                  // Windows设备描述表 
InBlock.gif      
//HGLRC m_hRC;               // OpenGL渲染描述表 
InBlock.gif
InBlock.gif      
// TODO: Add your command handler code here 
InBlock.gif
      wglMakeCurrent(m_pDC->m_hDC,m_hRC); 
InBlock.gif      //这里要注意,如果就面渲染完毕的时候,调用了wglMakeCurrent(NULL,NULL);上面一行就一定要加上。 
InBlock.gif

InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif      int expand = 0; 
InBlock.gif      if((m_width *3)%4) 
InBlock.gif         expand = 4 - (m_width*3)%4;   //保证位图宽度能被4整除 
InBlock.gif
       
InBlock.gif      int mapSize = (m_width*3 +expand) * (m_height); 
InBlock.gif
InBlock.gif      if(mapSize == 0) 
InBlock.gif         return
InBlock.gif
InBlock.gif      //hDIB = (HGLOBAL) ::GlobalAlloc(GHND,mapSize); 
InBlock.gif
      unsigned char * pTmp = new BYTE[mapSize]; 
InBlock.gif
InBlock.gif      if(!pTmp) 
InBlock.gif         return ; 
InBlock.gif      // 读取屏幕像素 
InBlock.gif
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
InBlock.gif      glReadPixels(0, 0, m_width, m_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, pTmp); 
InBlock.gif   //   glPixelStorei(GL_PACK_ALIGNMENT, 1); 
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif      
// BMP信息头 
InBlock.gif
      CxImage image; 
InBlock.gif      //image.CreateFromHBITMAP(hbit); 
InBlock.gif
      image.CreateFromArray(pTmp,m_width,m_height,24,m_width*3 + expand,false); 
InBlock.gif      image.SetJpegQuality(98);      //指定JPG文件的质量(0-100) 
InBlock.gif
       
InBlock.gif      if(ext == "jpb") 
InBlock.gif         image.Save(filename,CXIMAGE_FORMAT_JPG); 
InBlock.gif      else if(ext == "bmp") 
InBlock.gif         image.Save(filename,CXIMAGE_FORMAT_BMP); 
InBlock.gif      else if(ext == "tga") 
InBlock.gif         image.Save(filename,CXIMAGE_FORMAT_TGA); 
InBlock.gif
InBlock.gif      //pFile->Write(pTmp,mapSize*3); 
InBlock.gif

InBlock.gif
InBlock.gif
InBlock.gif      delete[] pTmp; 
InBlock.gif
ExpandedSubBlockEnd.gif   } 
InBlock.gif
InBlock.gif    
ExpandedBlockEnd.gif}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值