您的位置:首页 > 其它

透明效果算法及程序实现

2009-05-15 14:42 543 查看
//
#define TransTimes 8
#define LCDWIDTH 800
#define LCDHEIGHT 480
#define PIX_BIT 16

/****************************************************************************************/
/* TransBitmaProc 实现FirstBuf与SecondBuf这两个图之间的透明效果,DisBuf为显示Buffer区 */
/* FirstBuf为第一张图的RGB数据,SecondBuf为第二张图的RGB数据
/****************************************************************************************/
static BOOL TransBitmaProc(UINT8 *FirstBuf,UINT8 *SecondBuf,UINT8 *DispBuf)
{
UINT8 Trans=0;
UINT8 Count=0;
if (FirstBuf == NULL ||SecondBuf == NULL)
return FALSE;

while(1)
{
Count++;
if (Count >TransTimes)
return 0;
//Trans = Count*100/TransTimes;

//这里采用128作为基数,主要是为了能在后面的updataTransChangeWin函数中把低效率
//的/100优化成>>7的操作
Trans = Count*128/TransTimes;
if (Trans<=128)
{
updataTransChangeWin((UINT8 *)FirstBuf,(UINT8 *)SecondBuf,Trans);
memcpy(DispBuf,RGBBuffer,LCDHEIGHT*LCDWIDTH*(PIX_BIT>>3));
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//使用GDI绘图
#ifdef USE_GDI_FOR_DEBUG
BITMAPINFO info;
memset(&info.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
info.bmiHeader.biWidth = LCDWIDTH;
info.bmiHeader.biHeight = -LCDHEIGHT;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = PIX_BIT;
info.bmiHeader.biCompression = BI_RGB;

HDC hdc =GetDC(hRadioWnd);
SetDIBitsToDevice(hdc, 0, 0, LCDWIDTH, LCDHEIGHT, 0, 0, 0,LCDHEIGHT, RGBBuffer, (BITMAPINFO*)&info, DIB_RGB_COLORS);
ReleaseDC(hRadioWnd,hdc);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}
}

/*******************************************************/
/* 透明算法 */
/*******************************************************/
void updataTransChangeWin(UINT8 *Mbuf,UINT8 *Sbuf,UINT8 Trans)
{
UINT32 i;
UINT8 PTrans;

if (Mbuf == NULL ||Sbuf == NULL)
return;
if (Trans >=128)
{
memcpy(RGBBuffer,Sbuf,LCDWIDTH*LCDHEIGHT*(PIX_BIT>>3));
return;
}
PTrans = 128 - Trans;
UINT32 temp =0,temp1 =0;

switch( PIX_BIT )
{
case 16:
{
temp1 = LCDWIDTH*LCDHEIGHT>>1;
//UINT8 tempMR =0,tempMG =0, tempMB =0;
//UINT8 tempSR =0,tempSG =0, tempSB =0;

UINT32 tempR =0,tempG =0, tempB =0;
UINT32* pTempM = (UINT32*)Mbuf;
UINT32* pTempS = (UINT32*)Sbuf;
UINT32* pRGBBuffer = (UINT32*)RGBBuffer;
UINT32 tempData =0;
UINT32 tempD1,tempD2;
DWORD dwRes =GetTickCount();

for (i=0;i<temp1;i++)
{
/************************************************************************/
/* 方法一: 耗时300ms,采用8位对齐 */
/************************************************************************/
/*
temp = i*2;

tempMR = *(pTempM+temp+1)>>3;
tempMG = ((*(pTempM+temp+1)&0x7)<<3) | (*(pTempM+temp)>>5);
tempMB = *(pTempM+temp)& 0x1f;

tempSR = *(pTempS+temp+1)>>3;
tempSG = ((*(pTempS+temp+1)&0x7)<<3) | (*(pTempS+temp)>>5);
tempSB = *(pTempS+temp)& 0x1f;

((UINT16*)RGBBuffer)[temp>>1] = ((tempMR*PTrans+tempSR*Trans)>>7)<<11 | ((tempMG*PTrans+tempSG*Trans)>>7)<<5 | ((tempMB*PTrans+tempSB*Trans)>>7);
*/

/************************************************************************/
/* 方法二:耗时150ms,采用32位对齐 */
/************************************************************************/
tempD1 = *(pTempM+i);
tempD2 = *(pTempS+i);

tempR = (((((tempD1>>11) & 0x1f)*PTrans)+(((tempD2>>11)& 0x1f)*Trans))>>7)<<11;
tempG = ((((((tempD1>>5)&0x3f)*PTrans)+(((tempD2>>5)&0x3f)*Trans)))>>7)<<5;
tempB = ((((tempD1 & 0x1f))*PTrans)+(((tempD2 & 0x1f))*Trans))>>7;
tempData = tempR | tempG |tempB;

tempR = ((((tempD1>>27 & 0x1f)*PTrans)+(tempD2>>27& 0x1f)*Trans)>>7)<<27;
tempG = ((((tempD1>>21)&0x3f)*PTrans)+(((tempD2>>21)&0x3f)*Trans)>>7)<<21;
tempB = (((((tempD1>>16) & 0x1f)*PTrans)+(((tempD2>>16) & 0x1f)*Trans))>>7)<<16;
tempData |= (tempR | tempG |tempB);

*(pRGBBuffer+i) = tempData;

}
RETAILMSG(1,(TEXT("Spend %d ms!!!!!/r/n"),GetTickCount()-dwRes));
}
break;
case 24:
break;
case 32:
{
temp1 = LCDWIDTH*LCDHEIGHT;
for (i=0;i<temp1;i++)
{
temp = i<<2;

RGBBuffer[temp++] = (Mbuf[temp]*PTrans + Sbuf[temp] *Trans)>>7;
RGBBuffer[temp++] = (Mbuf[temp] *PTrans + Sbuf[temp] *Trans)>>7;
RGBBuffer[temp] = (Mbuf[temp] *PTrans + Sbuf[temp] *Trans)>>7;
}
}
break;
default:
break;
}

}

//*****************************************************************/
// DDRAW中的使用方法!
/*****************************************************************/
lpDDSPrimary->Lock(&rt,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
if( ddsd.lpSurface != NULL )
{
//动画处理两个DIB数据
TransBitmaProc( screenDCBuffer,lpBitmapBits,ddsd.lpSurface);
}
lpDDSPrimary->Unlock(ddsd.lpSurface);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: