locked
Store ID2D1Effect output in ID2D1Bitmap/Image to draw it at a later time?

    Question

  • Hey,

    I'm applying alot of effects to an ID2D1Bitmap before I draw it.

    To archieve better performance I want to convert the output image of the last ID2D1Effect to an ID2D1Bitmap, so I'm able to draw it at a later time without applying all the effects over and over...

    My first try was just to keep the ID2D1Effect::GetOutput image ptr, but this image changes every time I use the effect with another image source...

    My next try was to create a Bitmap (ID2D1DeviceContext::CreateBitmap) with D2D1_BITMAP_OPTIONS_TARGET flag set and draw the effects output to this Bitmap but that doesn't seem to work either...

    Draw effect to given Bitmap1** (dest):

    ComPtr<ID2D1Image> swapChainImageBuffer;
        this->pD2DeviceContext->CreateBitmap(D2D1::SizeU(120, 50), nullptr, 0, D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET), dest);
        this->pD2DeviceContext->GetTarget(swapChainImageBuffer.GetAddressOf());
        this->pD2DeviceContext->SetTarget(*dest);
        this->pD2DeviceContext->BeginDraw();
        this->pD2DeviceContext->Clear(D2D1::ColorF(RGB(0, 0, 0), 1.f));
        this->pD2DeviceContext->DrawImage(this->pCompositeEffect.Get(), D2D1::Point2F(20.f, 10.f));    
        this->pD2DeviceContext->EndDraw();
        this->pD2DeviceContext->SetTarget(swapChainImageBuffer.Get());
        swapChainImageBuffer = nullptr;

    Draw the bitmap at a later time : (img)

    this->pD2DeviceContext->DrawBitmap(img.Get(), D2D1::RectF(x, y, x+width, y + height));

    with this code, DrawBitmap draws nothing and EndDraw doesn't return an error.

    What am I doing wrong?

    How am I supposed to do this?

    Sunday, March 23, 2014 12:40 PM

Answers

  • Hello,

    Your second solution should work. I think you are just have a simple bug in your code. Create your bitmap as a pointer not a pointer to a pointer. When you set your target with "dest", try calling dest.Get() and avoid the extra derference.

    Here is basically the same code from the D2D performance page:

    // Create a bitmap.
    m_d2dContext->CreateBitmap(size, nullptr, 0,
    	D2D1::BitmapProperties(
    		D2D1_BITMAP_OPTIONS_TARGET,
    		D2D1::PixelFormat(
    			DXGI_FORMAT_B8G8R8A8_UNORM,
    			D2D1_ALPHA_MODE_PREMULTIPLIED),
    		dpiX, dpiY),
    	&sceneBitmap);
    
    // Preserve the pre-existing target.
    ComPtr<ID2D1Image> oldTarget;
    m_d2dContext->GetTarget(&oldTarget);
    
    // Render static content to the sceneBitmap.
    m_d2dContext->SetTarget(sceneBitmap.Get());
    m_d2dContext->BeginDraw();
    …
    m_d2dContext->EndDraw();
    
    // Render sceneBitmap to oldTarget.
    m_d2dContext->SetTarget(oldTarget.Get());
    m_d2dContext->DrawBitmap(sceneBitmap.Get());

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd372260(v=vs.85).aspx#sharedbitmaps

    I hope this helps,

    James

     
    Monday, March 24, 2014 11:43 PM

All replies

  • I'll ask one of our DirectX experts to check out this post.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Monday, March 24, 2014 12:19 PM
    Moderator
  • Hello,

    Your second solution should work. I think you are just have a simple bug in your code. Create your bitmap as a pointer not a pointer to a pointer. When you set your target with "dest", try calling dest.Get() and avoid the extra derference.

    Here is basically the same code from the D2D performance page:

    // Create a bitmap.
    m_d2dContext->CreateBitmap(size, nullptr, 0,
    	D2D1::BitmapProperties(
    		D2D1_BITMAP_OPTIONS_TARGET,
    		D2D1::PixelFormat(
    			DXGI_FORMAT_B8G8R8A8_UNORM,
    			D2D1_ALPHA_MODE_PREMULTIPLIED),
    		dpiX, dpiY),
    	&sceneBitmap);
    
    // Preserve the pre-existing target.
    ComPtr<ID2D1Image> oldTarget;
    m_d2dContext->GetTarget(&oldTarget);
    
    // Render static content to the sceneBitmap.
    m_d2dContext->SetTarget(sceneBitmap.Get());
    m_d2dContext->BeginDraw();
    …
    m_d2dContext->EndDraw();
    
    // Render sceneBitmap to oldTarget.
    m_d2dContext->SetTarget(oldTarget.Get());
    m_d2dContext->DrawBitmap(sceneBitmap.Get());

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd372260(v=vs.85).aspx#sharedbitmaps

    I hope this helps,

    James

     
    Monday, March 24, 2014 11:43 PM
  • Hello,

    I forgot to specify the PixelFormat for the CreateBitmap call... the code works now.

    Thanks for your help (:

    Tuesday, March 25, 2014 1:29 PM