Pergunta

I'm trying to incorporate some Direct2D drawing into an Ogre project. Right now Ogre only really supports DirectX9, which causes some complications with using Direct2D. My solution is this. Draw my overlay to a png using Direct2D, then use DirectX to draw the image to a sprite. I try doing this method and as soon as the draw method is complete, the sprite is corrupted. First the Direct2D drawing code:

void SceneManager::_initalize( void ){
    // Initalize the bitmiap
    hr = CoCreateInstance( 
        CLSID_WICImagingFactory,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IWICImagingFactory,
        reinterpret_cast<void **>(&pWICFactory)
    );

    // Initalize Direct2D
    if(SUCCEEDED(hr)){
        hr = D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory );
    }

    if(SUCCEEDED(hr)){
        hr = pWICFactory->CreateBitmap(
            rc.right - rc.left,
            rc.bottom - rc.top,
            GUID_WICPixelFormat8bppAlpha,
            WICBitmapCacheOnLoad,
            &pBitMap
        );
    }

    if(SUCCEEDED(hr)){
        hr = pD2DFactory->CreateWicBitmapRenderTarget(
            pBitMap, 
            D2D1::RenderTargetProperties(), 
            &pRenderTarget
        );
    }

    if(SUCCEEDED(hr)){
        hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(1,1,1,1), &pWhiteBrush);
    }


    // Draw to the bitmap here :)
    if(SUCCEEDED(hr)){
        pRenderTarget->BeginDraw();
        pRenderTarget->Clear(D2D1::ColorF(0,0,0,0));

        pRenderTarget->FillRectangle( D2D1::RectF( 0, 0, 500, 500), pWhiteBrush);

        pRenderTarget->EndDraw();

    }

    if(SUCCEEDED(hr)){
        hr = pWICFactory->CreateStream(&pStream);
    }

    WICPixelFormatGUID format = GUID_WICPixelFormat8bppAlpha;

    if(SUCCEEDED(hr)){
        hr = pStream->InitializeFromFilename(L"c:\\tmp\\dsplyr.xmg", GENERIC_WRITE);
    }

    if(SUCCEEDED(hr)){
        hr = pWICFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder);
    }

    if(SUCCEEDED(hr)){
        hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache);
    }

    if(SUCCEEDED(hr)){
        hr = pEncoder->CreateNewFrame(&pFrameEncode, NULL);
    }

    if(SUCCEEDED(hr)){
        hr = pFrameEncode->Initialize(NULL);
    }

    if(SUCCEEDED(hr)){
        hr = pFrameEncode->SetSize(rc.right - rc.left, rc.bottom - rc.top);
    }

    if(SUCCEEDED(hr)){
        hr = pFrameEncode->SetPixelFormat(&format);
    }

    if(SUCCEEDED(hr)){
        hr = pFrameEncode->WriteSource(pBitMap, NULL);
    }

    if(SUCCEEDED(hr)){
        hr = pFrameEncode->Commit();
    }

    if(SUCCEEDED(hr)){
        hr = pEncoder->Commit();
    }

    if(!SUCCEEDED(hr)){
        MessageBox(NULL, L"ERROR!", L"ERROR!", MB_OKCANCEL);
    }
}

And here's the code for drawing:

void SceneManager::Render( void ){

    LPDIRECT3DDEVICE9 pd3dDevice = NULL; // Our rendering device
    LPD3DXSPRITE d3dspt;
    LPDIRECT3DTEXTURE9 sprite;

    mWindow->getCustomAttribute("D3DDEVICE", &pd3dDevice);

    D3DXCreateSprite(pd3dDevice, &d3dspt);

    //D3DXCreateTextureFromFileInMemory(pd3dDevice, pBitMap, sizeof(pBitMap) , &sprite);
    D3DXCreateTextureFromFile(pd3dDevice, L"c:\\tmp\\testxmg" , &sprite);

    d3dspt->Begin( D3DXSPRITE_ALPHABLEND );

    D3DXVECTOR3 center(0,0,0);
    D3DXVECTOR3 position(0,0,0);

    d3dspt->Draw(sprite, &rc, &center, &position, D3DCOLOR_XRGB(255,255,255));

    d3dspt->End();
    sprite->Release();
    d3dspt->Release();
}

The error occurs at this line d3dspt->End();

And here is the error:

First-chance exception at 0x000007FA34B51F9C (D3DX9_43.dll) in GUI.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA34B51F9C (D3DX9_43.dll) in GUI.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

Obviously the d3dspt is becoming corrupted, buecause it's address is now 0xFFFFFFFFFFFFFFFF. I have no idea why this could be. Going to continue to debug and try and find a solution to my problem, but any input from SO would be great! :)

Environment Info: Microsfot Visual Studio 2012 C++ Ogre 1.9 DirectX9 Direct2D

Foi útil?

Solução

Ah. Looks as if the file is still locked after it is created. Have to '->Release()' the streams and buffers and such. Think I'm going to try writing the file to memory so I don't have to reallocate these every frame.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top