wince下在OpenGLES中加载jpg、png格式的文件为纹理。

在OpenGLES中要求图片的宽和高为2的n次方,因为有了这个要求,使得我们加载纹理的时候就麻烦了许多。经过对加载纹理这个过程的学习和研究,终于把这个问题给解决了。虽然不一定是最好的方法,但是在没有找到更好的方法前,将就着用吧。

思路很简单:就是将jpg、png文件解码到一个DC中,然后将DC中的保持到一个位图结构中,在保存之前对DC进行加工,使它的宽高大小变成2的n次方,最后从位图结构中读出数据作为纹理数据。解码我用的是wince下自带的IImage组件来解码,如果你有更好,速度更快的方法那就更好咯。废话少说,下面贴代码:

 

 

//计算绘制目标矩形区域 
void CPicScan3DDlg::CalcuteDrawArea(CRect DestRect, CRect *pDrawRect, int nWidth, int nHeight)
{
 
 if (DestRect.Width() > nWidth && DestRect.Height() > nHeight)
 {
  pDrawRect->left  = DestRect.left + (DestRect.Width() - nWidth)/2;
  pDrawRect->top  = DestRect.top + (DestRect.Height() - nHeight)/2;
  pDrawRect->right = pDrawRect->left + nWidth;
  pDrawRect->bottom = pDrawRect->top + nHeight;
 }
 else
 {
  if (DestRect.Height() * nWidth > DestRect.Width() * nHeight)
  {
   int w    = DestRect.Width();
   int h    = (int)( (float)w / (float)nWidth * nHeight );
   pDrawRect->left  = DestRect.left;
   pDrawRect->top  = ( DestRect.Height() - h ) / 2 + DestRect.top;
   pDrawRect->right = pDrawRect->left + w;
   pDrawRect->bottom = pDrawRect->top + h;
  }
  else if (DestRect.Height() * nWidth < DestRect.Width() * nHeight)
  {
   int h    = DestRect.Height();
   int w    = (int)( (float)h / (float)nHeight * nWidth );
   pDrawRect->left  = ( DestRect.Width() - w ) / 2 + DestRect.left;
   pDrawRect->top  = DestRect.top;
   pDrawRect->right = pDrawRect->left + w;
   pDrawRect->bottom = pDrawRect->top + h;
  }
  else
  {
   pDrawRect->left  = DestRect.left;
   pDrawRect->top  = DestRect.top;
   pDrawRect->right = DestRect.right;
   pDrawRect->bottom = DestRect.bottom;
  }
 }
 
}

 

 

//把给定设备环境内容保存成位图
void CPicScan3DDlg::SaveDCToBMP(HDC hDC, CRect sRect, int nWidth,int nHeight,CBitmap *pBitMap)
{
 //定义图形色深
 int iPixel = 24;
 //位图信息头
 LPBITMAPINFO lpbmih = new BITMAPINFO;
 lpbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 lpbmih->bmiHeader.biWidth = nWidth;
 lpbmih->bmiHeader.biHeight = nHeight;
 lpbmih->bmiHeader.biPlanes = 1;
 lpbmih->bmiHeader.biBitCount = iPixel;
 lpbmih->bmiHeader.biCompression = BI_RGB;
 lpbmih->bmiHeader.biSizeImage = 0;
 lpbmih->bmiHeader.biXPelsPerMeter = 0;
 lpbmih->bmiHeader.biYPelsPerMeter = 0;
 lpbmih->bmiHeader.biClrUsed = 0;
 lpbmih->bmiHeader.biClrImportant = 0;
 //创建位图数据
 HDC hdcMem;
 HBITMAP hBitMap = NULL;
 CDC *pMemDC = NULL;
 BYTE *pBits;
 hdcMem = CreateCompatibleDC(hDC);
 hBitMap = CreateDIBSection(hdcMem,lpbmih,DIB_RGB_COLORS,(void **)&pBits,NULL,0);
 
 pBitMap->Attach(hBitMap);
 pMemDC = new CDC;
 pMemDC->Attach(hdcMem);
 pMemDC->SelectObject(pBitMap);
 
 pMemDC->StretchBlt(0,0,nWidth,nHeight,CDC::FromHandle(hDC),sRect.left,sRect.top, sRect.Width(), sRect.Height(),SRCCOPY);

 DeleteObject(hBitMap);
 pMemDC->DeleteDC();
 
 delete pMemDC; pMemDC = NULL; 
 delete lpbmih; lpbmih = NULL;
}

 

 

//读取缩略图为纹理
BOOL CPicScan3DDlg::LoadThumhbnailImage(TCHAR* szFileName, GLuint *id)
{
 IImagingFactory *pImgFactory = NULL;
 IImage *pImage = NULL;
 IImage *pImgThumbnail = NULL;
 ImageInfo Info;
 
 CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
 if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) &pImgFactory)))
 {
  if (SUCCEEDED(pImgFactory->CreateImageFromFile(szFileName, &pImage)))
  {
   pImage->GetImageInfo(&Info);
   
   CRect rt;

   CRect rect(0,0,179,128);

   CBrush brush(RGB(0,0,0));
   m_ThumhDC.FillRect(rect, &brush);
   brush.DeleteObject();

   CalcuteDrawArea(rect, &rt, Info.Width, Info.Height);
      
   pImage->GetThumbnail(rt.Width(), rt.Height(), &pImgThumbnail);    
   pImgThumbnail->Draw(m_ThumhDC.m_hDC, &rt, NULL);
      
   if (!pImage)
   {
    pImage->Release();
    pImage = NULL;
   }
   
   if (!pImgThumbnail)
   {
    pImgThumbnail->Release();
    pImage = NULL;
   }
      
   CBitmap tempBmp;
   SaveDCToBMP(m_ThumhDC.m_hDC, rect, 128, 128, &tempBmp);
   
   BITMAP bm;     
   tempBmp.GetBitmap(&bm);
   
   unsigned char *bitmap = (unsigned char *)bm.bmBits;     
   unsigned char tmpRGB;
   
   for (LONG i = 0; i<bm.bmHeight*bm.bmWidth*3; i+=3)
   {
    tmpRGB = bitmap[i];
    bitmap[i] = bitmap[i+2];
    bitmap[i+2] = tmpRGB;
   }     
   
   glGenTextures(1, id);
   glBindTexture(GL_TEXTURE_2D, *id);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap);

   tempBmp.DeleteObject();
  }
  else
  {
   pImgFactory = NULL;
   pImage = NULL;
   CoUninitialize();
   return FALSE;
  }
  
  pImgFactory->Release();
  pImgFactory = NULL;
 }
 else
 {
  pImgFactory = NULL;
  pImage = NULL;
  CoUninitialize();
  return FALSE;
 }
 
 CoUninitialize();
 
 return TRUE;
}

 

 

//读取图片文件为纹理(非缩略图)
BOOL CPicScan3DDlg::LoadIntegrityImage(TCHAR* szFileName, GLuint *id)
{
 IImagingFactory *pImgFactory = NULL;
 IImage *pImage = NULL;
 ImageInfo Info;
 
 CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
 if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) &pImgFactory)))
 {
  if (SUCCEEDED(pImgFactory->CreateImageFromFile(szFileName, &pImage)))
  {
   pImage->GetImageInfo(&Info);

   CRect rt;
   
   CRect rect(0,0,640,512);
   
   CBrush brush(RGB(0,0,0));
   m_IntegDC.FillRect(rect, &brush);
   brush.DeleteObject();
   
   CalcuteDrawArea(rect, &rt, Info.Width, Info.Height);

   pImage->Draw(m_IntegDC.m_hDC, &rt, NULL);

   if (!pImage)
   {
    pImage->Release();
    pImage = NULL;
   }

   CBitmap tempBmp;
   SaveDCToBMP(m_IntegDC.m_hDC, rect, 512, 512, &tempBmp);
   
   BITMAP bm;     
   tempBmp.GetBitmap(&bm);
   
   unsigned char *bitmap = (unsigned char *)bm.bmBits;     
   unsigned char tmpRGB;
   
   for (LONG i = 0; i<bm.bmHeight*bm.bmWidth*3; i+=3)
   {
    tmpRGB = bitmap[i];
    bitmap[i] = bitmap[i+2];
    bitmap[i+2] = tmpRGB;
   }     
   
   glGenTextures(1, id);
   glBindTexture(GL_TEXTURE_2D, *id);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap);

   tempBmp.DeleteObject();
  }
  else
  {
   pImgFactory = NULL;
   pImage = NULL;
   CoUninitialize();
   return FALSE;
  }

  pImgFactory->Release();
  pImgFactory = NULL;
 }
 else
 {
  pImgFactory = NULL;
  pImage = NULL;
  CoUninitialize();
  return FALSE;
 }
 
 CoUninitialize();

 return TRUE;
}

 

哈哈,这样就可以完成只要IImage能解码的文件格式,都能做为OpenGLES的纹理了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值