 |
谢谢你对我提出的问题热心帮助和关心。我也向网上的其他高手进行了咨询,了解到目前版本中的DirectDraw中的Blt还不支持alpha融合,所以无法通过填充DDBLTFX结构以Blt出一个半透明的图象。但可以用D3D编程或lock 表面直接编程的方法来实现。本人就通过lock一个表面直接写点的方法实现了一个半透明的图象。
mail.下面是我的一段程序。800*600*32位模式。背景位图和前景位图均为16M色。
HRESULT ddrval;
ddrval = lpBackBuffer->BltFast( 0, 0, lpDDSOne,&rc,DDBLTFAST_WAIT);//背景位图传送到后台缓冲区
if( ddrval != DD_OK )
{
Msg("Blt failed! err=135971476",ddrval);
return;
}
DDSURFACEDESC ddsd,ddsd2;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ZeroMemory(&ddsd2,sizeof(ddsd2));
ddsd2.dwSize=sizeof(ddsd2);
ddrval=lpBackBuffer->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);//锁定台缓冲区
if(ddrval!=DD_OK)
{
Msg("lock failed");//锁定台缓冲区失败,退出程序
PostMessage(WM_CLOSE);
return;
}
ddrval=lpDDSTwo->Lock(NULL,&ddsd2,DDLOCK_WAIT,NULL);//锁定包含前景位图的表面
if(ddrval!=DD_OK)
{
Msg("lock failed");
PostMessage(WM_CLOSE);
return;
}
BYTE* Bitmap=(BYTE*)ddsd.lpSurface;//获取背景位图在内存中的起点位置
BYTE* Bitmap2=(BYTE*)ddsd2.lpSurface;//获取前景位图在内存中的起点位置
int alpha;
int pos,pos1;
static double rate1=0.05,rate2=0.0;
if(rate1>1.0)rate1=0.0;
rate2=1.0-rate1;
for(int y=newRect1.top;y<=newRect1.bottom;y++)
{//newRect1为CRect对象,存放前景位图在屏幕中的显示位置
pos=newRect1.left*4+y*ddsd.lPitch;
pos1=(y-newRect1.top)*ddsd2.lPitch;
for(int x=newRect1.left;x<=newRect1.right;x++)
{
//RED
alpha=(int)Bitmap2[pos1]*rate1;
Bitmap[pos]=(int)Bitmap[pos]*rate2+alpha;
if((int)Bitmap[pos]>255)Bitmap[pos]=255;
pos++;pos1++;
//GREEN
alpha=(int)Bitmap2[pos1]*rate1;
Bitmap[pos]=(int)Bitmap[pos]*rate2+alpha;
if((int)Bitmap[pos]>255)Bitmap[pos]=255;
pos++;pos1++;
//BLUE
alpha=(int)Bitmap2[pos1]*rate1;
Bitmap[pos]=(int)Bitmap[pos]*rate2+alpha;
if((int)Bitmap[pos]>255)Bitmap[pos]=255;
pos++;pos1++;
//REVERSE
pos++;pos1++;
}
}
rate1+=0.05;
lpBackBuffer->Unlock(&ddsd);//解锁表面
lpDDSTwo->Unlock(&ddsd2);//解锁表面
CGameWnd::Flip();//翻转表面
相关书籍:
《Inside DirectX 从入门到精通》
《DIRECTX6多媒体技术参考手册》
《DirectX7速成教程 (含盘)》
此问题由黄小军回答。
附加关键字:编程, 源程序, programming, source code, C/C++, MFC, C++ Builder, Borland C++, Turbo C, C, BCB, 图形、图象, picture, graph, image, draw。
|