directDraw创建了一个24位的离屏表面,靠上数据,怎么绘制到一个32位的主表面?

mem0set 2009-06-08 05:57:14
创建了一个24位的离屏表面,靠上数据,怎么绘制到一个32位的主表面?
总是画不出来啊
...全文
327 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
smilestone322 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mem0set 的回复:]
数据来的时候就是8位,我应该是没必要自己先转换成32吧,ddraw blt是不是可以自动完成转换
[/Quote]

这个问题是你的显卡不支持24位表面,我的也这样,后面我将它改成32位表面,能创建成功,但是后面将RGB24 位的数据copy到32位的表面,然后再blt到主表面,这个过程是很耗cpu的。还不如直接用GDI显示、
shenlaocangzhou 2011-11-16
  • 打赏
  • 举报
回复
我也遇到跟楼主一样的问题,如果是窗口模式下创建24位离屏表面,blt到主表面的话显示不支持此项操作,可是我又不想把24位数据转换成32位的这样浪费时间,有没有人知道有什么办法可以解决?
zhouzhipen 2009-06-09
  • 打赏
  • 举报
回复
我也研究了一段时间的DDraw,听说现在没有人用这东西了,都改用D3D了.但是我还是觉得,DDraw做2D方面的图形开发怎么也比GDI强吧.经过了一段时间的学习,我也封装了一个DDraw类,有兴趣可以交流下.
QQ:110696543
zhouzhipen 2009-06-09
  • 打赏
  • 举报
回复
你把下面的这段代码去掉试试,我不明白你为什么要创建与主表面颜色位不一样的页面.而且,如果不是用全屏模式,完全可以不用主表面,直接把后台页面上的内容放到窗口中的DC中不行吗?也不必要设定剪辑区,剪辑区这个东西不是所有的DDraw函数都支持的.

/*
* 设置剪辑
*/

ddrval = pData->lpdd->CreateClipper(0, &pData->lpddClipper, NULL);

if(FAILED(ddrval)) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

ddrval = pData->lpddClipper->SetHWnd(0, hwnd);

if(FAILED(ddrval)) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

ddrval = pData->lpddsPrimary->SetClipper(pData->lpddClipper);

if(ddrval != DD_OK) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

/*
* 最后产生背景Finally Create Back Surface
*/

mem0set 2009-06-09
  • 打赏
  • 举报
回复
再顶一下
mem0set 2009-06-09
  • 打赏
  • 举报
回复
数据来的时候就是8位,我应该是没必要自己先转换成32吧,ddraw blt是不是可以自动完成转换
zhouzhipen 2009-06-09
  • 打赏
  • 举报
回复
哪就直接用32位的图像呀,完全可以显示8位灰度效果.黑白的两位图像都可以呀.
24位,32位,如果你不处理32位的高位字节,和24位的没什么很大的区别呀.
mem0set 2009-06-09
  • 打赏
  • 举报
回复
还是画不出,我就是想用它显示各种(8位灰度,24位,32位)位图图像,用这个效率不是高嘛
mem0set 2009-06-08
  • 打赏
  • 举报
回复
顶一下
mem0set 2009-06-08
  • 打赏
  • 举报
回复
还是不行
int CDirectDrawImage::Init(HWND hwnd, unsigned int width, unsigned int height)
{
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
DirectDrawData* pData=(DirectDrawData*)m_pData;
if(hwnd && width > 0 && height > 0)
{

/*
* 产生主要的直接显示对象
*/

ddrval = DirectDrawCreateEx(NULL, (void **) &pData->lpdd, IID_IDirectDraw7, NULL);

if(FAILED(ddrval)) {

return 1;
}

ddrval = pData->lpdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL);

if(FAILED(ddrval)) {

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

/*
* 产生主界面Create the primary surface
*/

memset( &ddsd, 0, sizeof(ddsd) );
ddsd.dwSize = sizeof( ddsd );

ddsd.dwFlags = DDSD_CAPS;//| DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;


ddrval = pData->lpdd->CreateSurface(&ddsd, &pData->lpddsPrimary, NULL);

if(FAILED(ddrval)) {

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

/*
* 设置剪辑
*/

ddrval = pData->lpdd->CreateClipper(0, &pData->lpddClipper, NULL);

if(FAILED(ddrval)) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

ddrval = pData->lpddClipper->SetHWnd(0, hwnd);

if(FAILED(ddrval)) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

ddrval = pData->lpddsPrimary->SetClipper(pData->lpddClipper);

if(ddrval != DD_OK) {

pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;
}

/*
* 最后产生背景Finally Create Back Surface
*/


ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;// | DDSCAPS_VIDEOMEMORY;//DDSCAPS_SYSTEMMEMORY

ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.ddpfPixelFormat.dwRGBBitCount = 24;

ddsd.dwWidth = width;
ddsd.dwHeight = height;

switch( ddsd.ddpfPixelFormat.dwRGBBitCount )
{
case 8:
ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000;
break;
case 15: //RGB555
ddsd.ddpfPixelFormat.dwRBitMask = 0x7c00;
ddsd.ddpfPixelFormat.dwGBitMask = 0x3e0;
ddsd.ddpfPixelFormat.dwBBitMask = 0x1f;
break;
case 16: //RGB565
ddsd.ddpfPixelFormat.dwRBitMask = 0xf800;
ddsd.ddpfPixelFormat.dwGBitMask = 0x7e0;
ddsd.ddpfPixelFormat.dwBBitMask = 0x1f;
break;
case 24:
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
break;
case 32:
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
break;
default:
return FALSE;

}
ddrval = pData->lpdd->CreateSurface(&ddsd, &pData->lpddsBack, NULL);
if( ddrval != DD_OK) {
pData->lpddsPrimary->Release();
pData->lpddsPrimary = NULL;

pData->lpdd->Release();
pData->lpdd = NULL;

return 1;

}

pData->width = width;
pData->height = height;

pData->hwndPlayback = hwnd;

/*
* 获取视频模式
*/

ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);

ddrval = pData->lpddsBack->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);

if(FAILED(ddrval)) {

return 1;
}

pData->lpddsBack->Unlock(NULL);

switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {

case 8:
return 1;
break;

case 16:
pData->bpp = 2;
break;

case 24:
pData->bpp = 3;
break;

case 32:
pData->bpp = 4;
break;
}
pData->inited=1;
return 0;
}

return 1;
}



int CDirectDrawImage::Draw(int Width, int Height,int BitsPerPixel,unsigned char* pImageBuf,int dstX,int dstY,int dstWidth,int dstHeight,int srcX,int srcY,int srcWidth,int srcHeight)
{
HRESULT ddrval;
DDSURFACEDESC2 desc;
DWORD i;
DirectDrawData* pData=(DirectDrawData*)m_pData;
if(pData->lpdd && pData->lpddsBack && pData->lpddsPrimary && pImageBuf)
{

ZeroMemory(&desc, sizeof(DDSURFACEDESC2));
desc.dwSize = sizeof(DDSURFACEDESC2);

ddrval = pData->lpddsBack->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);

if(FAILED(ddrval))
{
return 1;
}

/*
* 复制象素
*/

// for(i=0; i < desc.dwHeight; i++)
// {
// memcpy((char *) desc.lpSurface + i*desc.lPitch, pImageBuf + (desc.dwHeight - i - 1)*pData->bpp*pData->width, pData->width*pData->bpp);
// }
int w4=(Width*BitsPerPixel+31)/32*4;
for(i=0; i < Height; i++)
{
memcpy((char *) desc.lpSurface + i*desc.lPitch, pImageBuf + (Height - i - 1)*w4, w4);
}
pData->lpddsBack->Unlock(NULL);

/*
* 复制到窗口
*/

if(pData->hwndPlayback)
{
RECT rcRect;
RECT destRect;
POINT pt;

rcRect.left = srcX;
rcRect.top = srcY;
rcRect.right = srcX+srcWidth;
rcRect.bottom = srcY+srcHeight;

GetClientRect( pData->hwndPlayback, &destRect );

/*
* 压缩rect以便放置控件
*/


destRect.left += dstX;
destRect.right = dstX + dstWidth;

destRect.top += dstY;
destRect.bottom = dstX+dstHeight;

pt.x = pt.y = 0;

ClientToScreen( pData->hwndPlayback, &pt );
OffsetRect(&destRect, pt.x, pt.y);

while( 1 )
{
// ddrval = pData->lpddsPrimary->Blt( &destRect, pData->lpddsBack, &rcRect, DDBLTFAST_NOCOLORKEY,NULL);//DDBLT_ASYNC | DDBLT_WAIT, NULL);
ddrval = pData->lpddsPrimary->BltFast(0,0,pData->lpddsBack,NULL,DDBLTFAST_NOCOLORKEY) ;

if( ddrval == DD_OK )
{
break;
}

if( ddrval == DDERR_SURFACELOST )
{
if(!pData->lpdd->RestoreAllSurfaces())
{
return 1;
}
}

if( ddrval != DDERR_WASSTILLDRAWING )
{
return 1;
}
}

if(ddrval != DD_OK)
{
return 1;
}

return 0;
}
}
zhouzhipen 2009-06-08
  • 打赏
  • 举报
回复
不好意思,我上面的帖子写错了,手误!!
这句lpDDPrimary->BitBlt(0,0,lpSurface,NULL,DDBLTFAST_NOCOLORKEY)
应为lpDDPrimary->BltFast(0,0,lpSurface,NULL,DDBLTFAST_NOCOLORKEY)

刚才你的代码,如果24位表面创建成功了,那可能是这句
lpddsPrimary->Blt( &destRect, lpddsBack, &rcRect, DDBLTFAST_NOCOLORKEY,NULL);
这句中DDBLTFAST_NOCOLORKEY标志错了.Blt函数中没有这个标志.

如果只是从离屏表面复制到主表面,没有什么其它的处理,还是用
pDDPrimary->BltFast(0,0,lpSurface,NULL,DDBLTFAST_NOCOLORKEY);
这样一般能显示出来,而且与颜色位无关.
mem0set 2009-06-08
  • 打赏
  • 举报
回复
不行,还是画不出
lpddsPrimary->Blt( &destRect, lpddsBack, &rcRect, DDBLTFAST_NOCOLORKEY,NULL);
我的lpddsBack默认创建出来是32位,强制memcpy进24位数据,再用lpddsPrimary->Blt倒是能画出来,效果就是只画上左边3/4,创建24位lpddsBack也能成功,但是就是blt不出东西 :(

ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;// | DDSCAPS_VIDEOMEMORY;//DDSCAPS_SYSTEMMEMORY

ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.ddpfPixelFormat.dwRGBBitCount = 24;

ddsd.dwWidth = width;
ddsd.dwHeight = height;

switch( ddsd.ddpfPixelFormat.dwRGBBitCount )
{
case 8:
ddsd.ddpfPixelFormat.dwRBitMask = 0xFF0000;
break;
case 15: //RGB555
ddsd.ddpfPixelFormat.dwRBitMask = 0x7c00;
ddsd.ddpfPixelFormat.dwGBitMask = 0x3e0;
ddsd.ddpfPixelFormat.dwBBitMask = 0x1f;
break;
case 16: //RGB565
ddsd.ddpfPixelFormat.dwRBitMask = 0xf800;
ddsd.ddpfPixelFormat.dwGBitMask = 0x7e0;
ddsd.ddpfPixelFormat.dwBBitMask = 0x1f;
break;
case 24:
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
break;
case 32:
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
break;
default:
return FALSE;

}
ddrval = lpdd->CreateSurface(&ddsd, &pData->lpddsBack, NULL);
zhouzhipen 2009-06-08
  • 打赏
  • 举报
回复
直接
lpDDPrimary->BitBlt(0,0,lpSurface,NULL,DDBLTFAST_NOCOLORKEY)
/*
lpDDPrimary 主表面
lpSurface 离屏表面
24位的离屏表面到32位主表面不会有影响的
*/

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧