OpengGL ES的内存贴图(从界面取贴图)

Windows mobile系统下调用Opengl es,当我试图使用当前DC下的bitmap对象(DDB位图)作为材质贴图,执行3D表面贴图。但是这个操作还是比较曲折的:

我使用glTexImage2D函数绑定图像到3D表面,glTexImage2D函数要求携带的数据是图像像素阵列。我必须要从DDB位图取出数据,因此我通过DIB位图来操作,首先要建立一个使用DIB位图的内存DC,通过把DDB位图bitblt到这个内存DC中,从而取到DDB位图的像素阵列

//--------------DIB结构定义---------------------------

     UINT iSize = sizeof(BITMAPINFO);

     BITMAPINFO* pBMI = (BITMAPINFO*) malloc(iSize);

     if( pBMI != NULL)

     {

         memset(pBMI, 0, iSize);

         // Fill in the header info.

         pBMI->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);

         pBMI->bmiHeader.biWidth       = 1024;

         pBMI->bmiHeader.biHeight      = 512;

         pBMI->bmiHeader.biPlanes      = 1;

         pBMI->bmiHeader.biBitCount    = 16;      //

         //pBMI->bmiHeader.biCompression = BI_BITFIELDS; // to use this flag.

         pBMI->bmiHeader.biCompression = BI_RGB; // to use this flag.

     }

else

     {

         return;

     }

//--------------DIB结构定义---------------------------

//--------------创建DIB内存DC---------------------------

 

BYTE* pBits ;

HDC hdcTexture=CreateCompatibleDC(hdc);

     //HBITMAP hbitmapTexture=CreateCompatibleBitmap(hdcTexture,1024,512);

     HBITMAP hbitmapTexture = CreateDIBSection( hdcTexture,

         pBMI,

         DIB_RGB_COLORS,

         //DIB_PAL_COLORS,

         (VOID **) &pBits,

         NULL,

         0);

     HBITMAP hbitmapTextureold=(HBITMAP)SelectObject(hdcTexture,hbitmapTexture);

//--------------创建DIB内存DC---------------------------

因此通过上述操作,我建立了一个hdcTexture,这个内存DC使用的是DIB位图,我要把从界面上得到的位图贴入这个内存DC

     //DC用于拼图

     HDC hdc = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);

     //传进的两张位图数据

     BITMAP bmp1;

     BITMAP bmp2;

     (void)GetObject(txtmap1,sizeof(BITMAP),&bmp1);//txtmap1是从外部传入的位图

     (void)GetObject(txtmap2,sizeof(BITMAP),&bmp2);//txtmap2是从外部传入的位图

 

     HDC hdcMemtxt1=CreateCompatibleDC(hdc);

     HBITMAP holdmapMem1=(HBITMAP)SelectObject(hdcMemtxt1,txtmap1);

 

     HDC hdcMemtxt2=CreateCompatibleDC(hdc);

     HBITMAP holdmapMem2=(HBITMAP)SelectObject(hdcMemtxt2,txtmap2);

     // txtStyle是外部传入的参数,表示拼图的样式

     if(txtStyle)

     {    StretchBlt(hdcTexture,0,0,512,512,hdcMemtxt2,0,0,bmp2.bmWidth,bmp2.bmHeight,SRCCOPY);

     StretchBlt(hdcTexture,512,0,512,512,hdcMemtxt1,0,0,bmp1.bmWidth,bmp1.bmHeight,SRCCOPY);

     }

     else

     {

     StretchBlt(hdcTexture,0,0,512,512,hdcMemtxt1,0,0,bmp1.bmWidth,bmp1.bmHeight,SRCCOPY);

     StretchBlt(hdcTexture,512,0,512,512,hdcMemtxt2,0,0,bmp2.bmWidth,bmp2.bmHeight,SRCCOPY);

     }

 

     SelectObject(hdcMemtxt1,holdmapMem1);

     SelectObject(hdcMemtxt2,holdmapMem2);

     SelectObject(hdcTexture,hbitmapTextureold);

此时我已经取得了我所需要的像素数据了,但是又遇到一个问题,当我直接把数据传入glTexImage2D函数时会发现整个图形的色彩都变了,我的函数是glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pbits);显然565格式与当前的像素阵列的格式不匹配,但是当我把参数改成GL_UNSIGNED_SHORT_5_5_5_1时也还是不对。因此我直接对原来的像素格式做了计算,同时执行了一次序列反转。

//--------------像素处理函数---------------------------

//像素格式转换

//pb1:源格式数据

//pixelW,pixelH:源图的像素尺寸

//实现格转换及数据翻转

BYTE* C3Dgles::ChangePixel555To565(BYTE* pb1,UINT pixelW,UINT pixelH) const

{

     //位图像素集指针

     DWORD dwSize = (DWORD)(pixelW * pixelH)*2;

     //目的像素集指针

     BYTE* pPixelPool =  new BYTE[dwSize];

     if(pPixelPool == NULL) return NULL;

     memset(pPixelPool,  0,  dwSize);

 

     //移动源像素数据指针到最后一位

     //BYTE* currSrcpx=pb1+dwSize;

     BYTE* currSrcpx=NULL;

     BYTE* pPixelPoolFirst=pPixelPool;

     //像素循环

     for(UINT i=0;i<pixelH;i++)

     {

         //从最后一行计算,移动数据指针到每行的开头

         //currSrcpx=currSrcpx-(i+1)*pixelW*2;

         currSrcpx=pb1+(pixelH-(i+1))*pixelW*2;

 

         for(UINT j=0;j<pixelW;j++)

         {

              //currSrcpx=currSrcpx+1;

              BYTE btTemp1=*currSrcpx++;

              BYTE btDestTemp1=(BYTE)((btTemp1 & 0xE0)<<1)|(btTemp1 & 0x1F);

              //currSrcpx--;

              BYTE btTemp2=*currSrcpx++;

              BYTE btDestTemp2=(BYTE)(btTemp2<<1)|((btTemp1 & 0x80)>>7);

              *pPixelPool++=btDestTemp1;

              *pPixelPool++=btDestTemp2;

         }

     }

     return pPixelPoolFirst;

 

}

//--------------像素处理函数---------------------------

此时就能取得与配置相符合的数据,继续我的操作,完成这次内存贴图的功能

     //拼合后的贴图数据

     BITMAP bmpinfo;

     (void)GetObject(hbitmapTexture,sizeof(BITMAP),&bmpinfo);

     //BYTE* btbits=(BYTE*)bmpinfo.bmBits;

 

     //数据转换

     BYTE* pPixelWordPool = ChangePixel555To565((BYTE*)bmpinfo.bmBits,(UINT)bmpinfo.bmWidth,(UINT)bmpinfo.bmHeight);

 

     //测试位图是否取得

     //StretchBlt(hdc,0,0,480,640,hdcTexture,0,0,bmpinfo.bmWidth,bmpinfo.bmHeight,SRCCOPY);

     DELETEP(pBits);

     DELETEGDIOBJ(txtmap1);

     DELETEGDIOBJ(txtmap2);

     DELETEGDIOBJ(hbitmapTexture);

 

     (void)DeleteDC(hdcMemtxt1);

     (void)DeleteDC(hdcMemtxt2);

     (void)DeleteDC(hdcTexture);

     (void)DeleteDC(hdc);

     free(pBMI);

     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pbits);   

     DELETEP(pPixelWordPool);

     return TRUE;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值