【问题标题】:Direct X Sprite Rendering IssueDirect X Sprite 渲染问题
【发布时间】:2012-07-23 18:32:35
【问题描述】:

我一直在使用 Direct X 编写自己的库,但遇到了一个奇怪的问题。在尝试渲染动画精灵时,我只是看到了一个黑色的大方块:

我痴迷地浏览了代码,并得出结论,这一定与实际精灵的加载有关,因为我在代码中看到的一切都很好。显然,我无法进入诸如 BltFast 之类的函数,因此无法判断我的精灵表面是否成功地被 blitted 到后台缓冲区。

这是我的精灵的加载和渲染函数:

SPRITE::LOAD

/**
 *  loads a bitmap file and copies it to a directdraw surface
 *
 *  @param  pID             wait
 *  @param  pFileName       name of the bitmap file to load into memory
 */
void Sprite::Load (const char *pID, const char *pFileName)
{
    //  initialises the member variables with the new image id and file name
    mID                 = pID;
    mFileName           = pFileName;

    //  creates the necessary variables
    HBITMAP             tHBM;
    BITMAP              tBM;
    DDSURFACEDESC2      tDDSD;
    IDirectDrawSurface7 *tDDS;

    //  stores bitmap image into HBITMAP handler
    tHBM                    = static_cast<HBITMAP> (LoadImage (NULL, pFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION));

    GetObject (tHBM, sizeof (tBM), &tBM);

    //  create surface for the HBITMAP to be copied onto
    ZeroMemory (&tDDSD, sizeof (tDDSD));
    tDDSD.dwSize            = sizeof (tDDSD);
    tDDSD.dwFlags           = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
    tDDSD.ddsCaps.dwCaps    = DDSCAPS_OFFSCREENPLAIN;
    tDDSD.dwWidth           = tBM.bmWidth;
    tDDSD.dwHeight          = tBM.bmHeight;
    DirectDraw::GetInstance ()->DirectDrawObject()->CreateSurface (&tDDSD, &tDDS, NULL);

    //  copying bitmap image onto surface
    CopyBitmap(tDDS, tHBM, 0, 0, 0, 0);

    //  deletes bitmap image now that it has been used
    DeleteObject(tHBM);

    //  stores the new width and height of the image
    mSpriteWidth            = tBM.bmWidth;
    mSpriteHeight           = tBM.bmHeight;

    //  sets the address of the bitmap surface to this temporary surface with the new bitmap image
    mBitmapSurface          = tDDS;
}

SPRITE::RENDER

/**
 *  renders the sprites surface to the back buffer
 *
 *  @param  pBackBuffer     surface to render the sprite to
 *  @param  pX              x co-ordinate to render to (default is 0)
 *  @param  pY              y co-ordinate to render to (default is 0)
 */
void Sprite::Render (LPDIRECTDRAWSURFACE7 &pBackBuffer, float pX, float pY)
{
    if (mSpriteWidth > 800)     mSpriteWidth = 800;

    RECT            tFrom;

    tFrom.left      = tFrom.top     =   0;
    tFrom.right     = mSpriteWidth;
    tFrom.bottom    = mSpriteHeight;

    //  bltfast parameters are (position x, position y, dd surface, draw rect, wait flag)
    //  pBackBuffer->BltFast (0 + DirectDraw::GetInstance()->ScreenWidth(), 0, mBitmapSurface, &tFrom, DDBLTFAST_WAIT);
    pBackBuffer->BltFast (static_cast<DWORD>(pX + DirectDraw::GetInstance()->ScreenWidth()), 
        static_cast<DWORD>(pY), mBitmapSurface, &tFrom, DDBLTFAST_WAIT);
}

【问题讨论】:

    标签: directx rendering sprite


    【解决方案1】:

    表面根本不是兼容的格式。

    这是我现在在加载函数中调用的固定复制位图函数:

    extern "C" HRESULT
    DDCopyBitmap(IDirectDrawSurface7 * pdds, HBITMAP hbm, int x, int y,
                 int dx, int dy)
    {
        HDC                     hdcImage;
        HDC                     hdc;
        BITMAP                  bm;
        DDSURFACEDESC2          ddsd;
        HRESULT                 hr;
    
        if (hbm == NULL || pdds == NULL)
            return E_FAIL;
        //
        // Make sure this surface is restored.
        //
        pdds->Restore();
        //
        // Select bitmap into a memoryDC so we can use it.
        //
        hdcImage = CreateCompatibleDC(NULL);
        if (!hdcImage)
            OutputDebugString("createcompatible dc failed\n");
        SelectObject(hdcImage, hbm);
        //
        // Get size of the bitmap
        //
        GetObject(hbm, sizeof(bm), &bm);
        dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
        dy = dy == 0 ? bm.bmHeight : dy;
        //
        // Get size of surface.
        //
        ddsd.dwSize = sizeof(ddsd);
        ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
        pdds->GetSurfaceDesc(&ddsd);
    
        if ((hr = pdds->GetDC(&hdc)) == DD_OK)
        {
            StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
                       dx, dy, SRCCOPY);
            pdds->ReleaseDC(hdc);
        }
        DeleteDC(hdcImage);
        return hr;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-27
      • 2015-11-09
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      相关资源
      最近更新 更多