创建了一个24位的离屏表面,靠上数据,怎么绘制到一个32位的主表面?
总是画不出来啊

解决方案 »

  1.   

    直接
    lpDDPrimary->BitBlt(0,0,lpSurface,NULL,DDBLTFAST_NOCOLORKEY)
    /*
    lpDDPrimary 主表面
    lpSurface 离屏表面
    24位的离屏表面到32位主表面不会有影响的
    */
      

  2.   

    不行,还是画不出
    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);
      

  3.   

    不好意思,我上面的帖子写错了,手误!!
    这句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);
    这样一般能显示出来,而且与颜色位无关.
      

  4.   

    还是不行
    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;
    }
    }
      

  5.   

    你把下面的这段代码去掉试试,我不明白你为什么要创建与主表面颜色位不一样的页面.而且,如果不是用全屏模式,完全可以不用主表面,直接把后台页面上的内容放到窗口中的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 
    */
      

  6.   

    数据来的时候就是8位,我应该是没必要自己先转换成32吧,ddraw blt是不是可以自动完成转换
      

  7.   

    我也遇到跟楼主一样的问题,如果是窗口模式下创建24位离屏表面,blt到主表面的话显示不支持此项操作,可是我又不想把24位数据转换成32位的这样浪费时间,有没有人知道有什么办法可以解决?
      

  8.   


    这个问题是你的显卡不支持24位表面,我的也这样,后面我将它改成32位表面,能创建成功,但是后面将RGB24 位的数据copy到32位的表面,然后再blt到主表面,这个过程是很耗cpu的。还不如直接用GDI显示、