CxImage与OpenGL结合,用于读入多种格式的纹理以及用来把屏幕保存为各种格式的图像文件。

摘自:http://blog.csdn.net/huawenguang/article/details/1548888

最近要用到OpenGL纹理,读到此文章,堪觉有用,摘录如下:

关于CxImage的文章,网上有许多,这里只介绍如何把CxImage与OpenGL结合起来,用于读入多种格式的纹理以及用来把屏幕保存为各种格式的图像文件。

支持的格式有:BMP,GIF,ICO,JP2,FPC,FPG,PCX,PNG,PNM,RAS,TGA,TIF等等。

支持读入透明纹理。

CxImage官方网站:http://www.xdp.it/

// 使用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)      // 读入一个自身带有透明信息的图片作纹理。

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


 unsigned 
char *pImage_RGBA = NULL;


 
// Load the bitmap using the aux function stored in glaux.lib
 
//pImage = auxDIBImageLoad(tex_name);
 image.Load(tex_name);
 
// Make sure valid image data was given to pImage, otherwise return false
 if(!image.IsValid())
  
return false;

 
int sizeX,sizeY;
 sizeX 
= image.GetWidth();
 sizeY 
= image.GetHeight();

 
float texAspectRatio = (float)sizeX / (float)sizeY;





 
if(alpha_name && strlen(alpha_name) > 0 )
 
{
   
int imageSize_RGB  = sizeX * sizeY * 3;
   
int imageSize_RGBA = sizeX * sizeY * 4;
   alpha.Load(alpha_name); 
   
if(!alpha.IsValid())
   
{
    
return false;
   }

   
// allocate buffer for a RGBA image
   pImage_RGBA = new unsigned char[imageSize_RGBA];
  

   RGBQUAD col_image,col_alpha;
   
  
for(int y=0;y<sizeY;y++)
   
for(int x=0;x<sizeX;x++)
    
{
     col_image 
= image.GetPixelColor(x,y,false);
     col_alpha 
= alpha.GetPixelColor(x,y,false);
     pImage_RGBA[(x
+y*sizeX)*4 +0= col_image.rgbRed;
     pImage_RGBA[(x
+y*sizeX)*4 +1= col_image.rgbGreen;
     pImage_RGBA[(x
+y*sizeX)*4 +2= col_image.rgbBlue;
     pImage_RGBA[(x
+y*sizeX)*4 +3= col_alpha.rgbRed;
    }



   

   glGenTextures(
1&texID);
   glBindTexture(GL_TEXTURE_2D, texID);

   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
   
// Don't forget to use GL_RGBA for our new image data... we support Alpha transparency now!
  
// Build Mipmaps (builds different versions of the picture for distances - looks better)
   gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX, 
    sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA); 
  
if(pImage_RGBA)
  
{
   delete [] pImage_RGBA;
  }


 }

 
else if(image.AlphaIsValid())
 
{
   
int imageSize_RGB  = sizeX * sizeY * 3;
   
long imageSize_RGBA = sizeX * sizeY * 4;
   
// allocate buffer for a RGBA image
  
// pImage_RGBA = new unsigned char[imageSize_RGBA];

  image.Encode2RGBA(pImage_RGBA,imageSize_RGBA);
  
  
// Generate a texture with the associative texture ID stored in the array
  glGenTextures(1&texID);
  
  
// This sets the alignment requirements for the start of each pixel row in memory.
  
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  
  
// Bind the texture to the texture arrays index and init the texture
  glBindTexture(GL_TEXTURE_2D, texID);
  

  
//Assign the mip map levels and texture info
  
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  
// Build Mipmaps (builds different versions of the picture for distances - looks better)
  gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX, 
    sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA); 
  
  image.FreeMemory( pImage_RGBA);
 }

 
else
 
{
  
// Generate a texture with the associative texture ID stored in the array
  glGenTextures(1&texID);
  
  
// This sets the alignment requirements for the start of each pixel row in memory.
  
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  
  
// Bind the texture to the texture arrays index and init the texture
  glBindTexture(GL_TEXTURE_2D, texID);
  

  
//Assign the mip map levels and texture info
  
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  
// Build Mipmaps (builds different versions of the picture for distances - looks better)
  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sizeX, 
   sizeY, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.GetBits());
  
 }

 
//glEnable(GL_TEXTURE_2D);
 
// Now we need to free the image data that we loaded since openGL stored it as a texture





 
return true;
}



// 用来保存屏幕到图像文件。
void  CCxImage_GLView::OnSaveScene() 
{


 
// TODO: Add your command handler code here
 static char BASED_CODE szFilter[] = "jpg Files (*.jpg)|*.jpg|bmp Files (*.bmp)|*.bmp|tga Files (*.tga)|*.tga|All Files (*.*)|*.*||";
 

 CString filename;
 
 CString ext 
= "";

 
if(filename.IsEmpty())
  filename 
= "NoName";

 CFileDialog dlg(
false"jpg",filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);

 
if(dlg.DoModal() == IDOK)
 
{

 ext 
= dlg.GetFileExt();
 filename 
= dlg.GetPathName();


  
//CDC* m_pDC;      // Windows设备描述表
  
//HGLRC m_hRC;     // OpenGL渲染描述表

  
// TODO: Add your command handler code here
  wglMakeCurrent(m_pDC->m_hDC,m_hRC);
  
//这里要注意,如果就面渲染完毕的时候,调用了wglMakeCurrent(NULL,NULL);上面一行就一定要加上。




  
int expand = 0;
  
if((m_width *3)%4)
   expand 
= 4 - (m_width*3)%4//保证位图宽度能被4整除
  
  
int mapSize = (m_width*3 +expand) * (m_height);

  
if(mapSize == 0)
   
return;

  
//hDIB = (HGLOBAL) ::GlobalAlloc(GHND,mapSize);
  unsigned char * pTmp = new BYTE[mapSize]; 

  
if(!pTmp)
   
return ;
  
// 读取屏幕像素 
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
  glReadPixels(
00, m_width, m_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, pTmp);
 
// glPixelStorei(GL_PACK_ALIGNMENT, 1); 



  
// BMP信息头 
  CxImage image;
  
//image.CreateFromHBITMAP(hbit);
  image.CreateFromArray(pTmp,m_width,m_height,24,m_width*3 + expand,false);
  image.SetJpegQuality(
98);  //指定JPG文件的质量(0-100)
  
  
if(ext == "jpb")
   image.Save(filename,CXIMAGE_FORMAT_JPG);
  
else if(ext == "bmp")
   image.Save(filename,CXIMAGE_FORMAT_BMP);
  
else if(ext == "tga")
   image.Save(filename,CXIMAGE_FORMAT_TGA);

  
//pFile->Write(pTmp,mapSize*3);



  delete[] pTmp;

 }


 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值