XNA Creators Club Online
community forums
Page 1 of 1 (1 items)
Sort Posts: Previous Next

Direct2D

Last post 6/25/2009 1:03 PM by zodX. 0 replies.
  • 6/25/2009 1:03 PM

    Direct2D

    Hi, there !

    I´ve tried the Bitmap Opacity Masking Example.

    Get it from here:
    http://msdn.microsoft.com/en-us/library/dd372307(VS.85).aspx

    The >Bitmap-Opacity-Mask< is always opaque and not transparent, I see no checkerboard thru.
    e.g. tried loading 8bit,32bit,straight,premueltiplied,tif,bmp  for it.

    Maybe you know how to fix this, it´s nearly the original sample.
    Do I have to specially load any exotic-prepared bitmaps ? Or are any exotic parameters wrong ?
    I couldn´t understand why this sample mustn´t work.

     

    My Opacity Mask Sample I´ve changed this little bit:
    Changed BitmaploadfromResource into BitmaploadfromFile (beneath identical).

    // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
    // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    // PARTICULAR PURPOSE.
    //
    // Copyright (c) Microsoft Corporation. All rights reserved
    //+-----------------------------------------------------------------------------
    //
    //
    //  $Description:
    //      Sample DirectWrite Application
    //
    //  $ENDTAG
    //
    //------------------------------------------------------------------------------

    #include "stdafx.h"

    /******************************************************************
    *                                                                 *
    *  WinMain                                                        *
    *                                                                 *
    *  Application entrypoint                                         *
    *                                                                 *
    ******************************************************************/

    int WINAPI WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
    {
        HRESULT hr;
        if (SUCCEEDED(CoInitialize(NULL)))
        {
            {
                DemoApp app;

                if (SUCCEEDED(hr = app.Initialize()))
                {
                    app.RunMessageLoop();
                }
            }
            CoUninitialize();
        }

        return SUCCEEDED(hr) ? EXIT_SUCCESS : EXIT_FAILURE;
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::DemoApp constructor                                   *
    *                                                                 *
    *  Initialize member data                                         *
    *                                                                 *
    ******************************************************************/

    DemoApp::DemoApp() :
        m_hwnd(NULL)
    {
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::~DemoApp destructor                                   *
    *                                                                 *
    *  Tear down resources                                            *
    *                                                                 *
    ******************************************************************/

    DemoApp::~DemoApp()
    {
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::Initialize                                            *
    *                                                                 *
    *  Create application window and device-independent resources     *
    *                                                                 *
    ******************************************************************/
    HRESULT DemoApp::Initialize()
    {
     WNDCLASSEX wcex;
        HRESULT hr;
        ATOM atom;

        IFR(CreateDeviceIndependentResources());

        // Register window class
        wcex.cbSize        = sizeof(WNDCLASSEX);
        wcex.style         = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc   = DemoApp::WndProc;
        wcex.cbClsExtra    = 0;
        wcex.cbWndExtra    = sizeof(LONG_PTR);
        wcex.hInstance     = HINST_THISCOMPONENT;
        wcex.hbrBackground = NULL;
        wcex.lpszMenuName  = NULL;
        wcex.hIcon         = LoadIcon(
            NULL,
            IDI_APPLICATION
            );
        wcex.hCursor       = LoadCursor(
            NULL,
            IDC_ARROW
            );
        wcex.lpszClassName = TEXT("D2DDemoApp");
        wcex.hIconSm       = LoadIcon(
            NULL,
            IDI_APPLICATION
            );

        atom = RegisterClassEx(
            &wcex
            );

        IFR(atom ? S_OK : E_FAIL);

        //
        // Create Window takes its size in Pixels, so, to have a consistent DIP size, you
        // obtain the DPI and use it to scale the window size.
        FLOAT dpiX, dpiY;

        //
        // The factory returns the current system DPI. This is also the value it will use
        // to create its own windows.
        //
        m_spD2DFactory->GetDesktopDpi(&dpiX, &dpiY);

        // Create window
        m_hwnd = CreateWindow(
            TEXT("D2DDemoApp"),
            TEXT("Direct2D Demo App"),
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            static_cast<UINT>(dpiX * 800.f / 96.f),
            static_cast<UINT>(dpiY * 800.f / 96.f),
            NULL,
            NULL,
            HINST_THISCOMPONENT,
            this
            );

        IFR(m_hwnd ? S_OK : E_FAIL);

        ShowWindow(m_hwnd, SW_SHOWNORMAL);

        UpdateWindow(m_hwnd);

        return hr;
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::CreateDeviceIndependentResources                      *
    *                                                                 *
    *  This method is used to create resources which are not bound    *
    *  to any device. Their lifetime effectively extends for the      *
    *  duration of the app.                                           *
    *                                                                 *
    ******************************************************************/

    HRESULT DemoApp::CreateDeviceIndependentResources()
    {
        HRESULT hr = S_OK;
       
        // Create WIC factory
        IFR(CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IWICImagingFactory,
            reinterpret_cast<void **>(&m_spWICFactory)
            ));

        // Create Direct2D factory
        IFR(D2D1CreateFactory(
            D2D1_FACTORY_TYPE_SINGLE_THREADED,
            &m_spD2DFactory
            ));

        // Create a shared DirectWrite factory
        IFR(DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            reinterpret_cast<IUnknown**>(&m_spDWriteFactory)
            ));

        m_spD2DFactory->CreateRectangleGeometry(D2D1::RectF(0,5,200,195),&m_spRectGeo);
       
        m_wszOriginalBitmapText=L"Original Bitmap";
        m_wszBitmapBrushOpacityMaskText=L"Bitmap Opacity Mask";
        m_wszLinearGradientOpacityMaskText=L"Linear Gradient Opacity Mask";
        m_wszRadialGradientOpacityMaskText=L"Radial Gradient Opacity Mask";
        m_wszWithBitmapBrushOpacityMaskText=L"Bitmap With Bitmap Opacity Mask Applied";
        m_wszWithLinearGradientOpacityMaskText=L"Bitmap With Linear Gradient Opacity Mask Applied";
        m_wszWithRadialGradientOpacityMaskText=L"Bitmap With Radial Gradient Opacity Mask Applied";

        // Create a text format.
        IFR(m_spDWriteFactory->CreateTextFormat(
            L"Verdana", //font family name
            NULL, //font collection (NULL sets it to use the system font collection)
            DWRITE_FONT_WEIGHT_REGULAR,
            DWRITE_FONT_STYLE_NORMAL,
            DWRITE_FONT_STRETCH_NORMAL,
            12.0f,
            L"en-us",
            &m_spTextFormat
            ));

        return hr;
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::CreateDeviceResources                                 *
    *                                                                 *
    *  This method creates resources which are bound to a particular  *
    *  D3D device. It's all centralized here, in case the resources   *
    *  need to be recreated in case of D3D device loss (eg. display   *
    *  change, remoting, removal of video card, etc).                 *
    *                                                                 *
    ******************************************************************/

    HRESULT DemoApp::CreateDeviceResources()
    {
        HRESULT hr = S_OK;

        if (!m_spRT)
        {

            RECT rc;
            GetClientRect(m_hwnd, &rc);

            D2D1_SIZE_U size = D2D1::SizeU(
                rc.right - rc.left,
                rc.bottom - rc.top
            );

            // Create a Direct2D render target
            IFR(m_spD2DFactory->CreateHwndRenderTarget(
                D2D1::RenderTargetProperties(),
                D2D1::HwndRenderTargetProperties(
                    m_hwnd,
                    size
                    ),
                &m_spRT
                ));

            IFR(m_spRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black),&m_spBlackBrush));

            //Create the bitmap to be used by the bitmap brush

       // Instead of loadingFromResource this is the only part I changed in this sample
       // But unlikely the official text-samples haven´t got the images with it
       LoadBitmapFromFile(m_spRT,
                m_spWICFactory,
                L"V:\\GRAPHIK space 4D\\Masking Test.bmp",
                0,
                0,
                &m_spBitmap
                );

       LoadBitmapFromFile(m_spRT,
                m_spWICFactory,
                L"V:\\GRAPHIK space 4D\\Masking Test2.bmp",
                0,
                0,
                &m_spBitmapMask
                );

            D2D1_BITMAP_BRUSH_PROPERTIES propertiesXClampYClamp = { D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_CLAMP, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR };
           
      IFR(m_spRT->CreateBitmapBrush(
                m_spBitmap,
                propertiesXClampYClamp,
                &m_spOriginalBitmapBrush));
           
            IFR(m_spRT->CreateBitmapBrush(
                m_spBitmapMask,
                propertiesXClampYClamp,
                &m_spBitmapMaskBrush));
           
            
            //Create an array of gradient stops to put in the gradient stop collection which will be used in the linear gradient brush
           
            D2D1_GRADIENT_STOP gradientStops[2];
            gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::Black,1.0f);
            gradientStops[0].position = 0.0f;
            gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::White,0.0f);
            gradientStops[1].position = 1.0f;
           
            //Create the ID2D1GradientStopCollection from a previously declared array of D2D1_GRADIENT_STOP structs
            IFR(m_spRT->CreateGradientStopCollection(gradientStops,
                2,
                D2D1_GAMMA_2_2,
                D2D1_EXTEND_MODE_CLAMP,
                &m_spGradientStopCollection));
           
           
            //The line that determines the direction of the gradient starts at the top left corner of the box to the bottom right corner
            IFR(m_spRT->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(0,0),D2D1::Point2F(200,200)),
                m_spGradientStopCollection,
                &m_spLinearGradientBrush));
           
            //The center of the gradient is in the center of the box. The gradient origin offset was set to zero(0,0) or center in this case.
            IFR(m_spRT->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(D2D1::Point2F(100,100), D2D1::Point2F(0,0), 100,100),
                m_spGradientStopCollection,
                &m_spRadialGradientBrush));
           
           
            // Create the compatible render target
            ID2D1BitmapRenderTargetPtr spCompatibleRenderTarget;
            IFR(m_spRT->CreateCompatibleRenderTarget(D2D1::SizeF(20.0f, 20.0f),
                &spCompatibleRenderTarget));

            // Create the pattern
            ID2D1SolidColorBrushPtr spWhiteBrush;
            IFR(spCompatibleRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White),
                &spWhiteBrush));

            ID2D1SolidColorBrushPtr spGrayBrush;
            IFR(spCompatibleRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightGray),
                &spGrayBrush));

            //Draw filled rectangles onto the render target
            spCompatibleRenderTarget->BeginDraw();
            spCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.0f, 10.0f, 10.0f), spGrayBrush);
            spCompatibleRenderTarget->FillRectangle(D2D1::RectF(10.0f, 0.0f, 20.0f, 10.0f), spWhiteBrush);
            spCompatibleRenderTarget->FillRectangle(D2D1::RectF(10.0f, 10.0f, 20.0f, 20.0f), spGrayBrush);
            spCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 10.0f, 10.0f, 20.0f), spWhiteBrush);
            spCompatibleRenderTarget->EndDraw();

            //Get the bitmap from the render target.
            IFR(spCompatibleRenderTarget->GetBitmap(&m_spCheckeredBitmap));

            //Choose the tiling mode for the bitmap brush
            D2D1_BITMAP_BRUSH_PROPERTIES brushProperties = D2D1::BitmapBrushProperties(D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
           
            //Create the bitmap brush
            IFR(m_spRT->CreateBitmapBrush(m_spCheckeredBitmap, brushProperties, &m_spCheckerPatternBitmapBrush));
        }

        return hr;
    }

     

    /******************************************************************
    *                                                                 *
    *  DemoApp::DiscardDeviceResources                                *
    *                                                                 *
    *  Discard device-specific resources which need to be recreated   *
    *  when a D3D device is lost                                      *
    *                                                                 *
    ******************************************************************/

    void DemoApp::DiscardDeviceResources()
    {
        m_spRT = NULL;
        m_spBlackBrush = NULL;
        m_spLinearGradientBrush = NULL;
        m_spRadialGradientBrush = NULL;
        m_spOriginalBitmapBrush = NULL;
        m_spGradientStopCollection = NULL;
        m_spCheckerPatternBitmapBrush = NULL;
       
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::RunMessageLoop                                        *
    *                                                                 *
    *  Main window message loop                                       *
    *                                                                 *
    ******************************************************************/

    void DemoApp::RunMessageLoop()
    {
        MSG msg;

        while (GetMessage(&msg, NULL, 0, 0)>0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

     
    /******************************************************************
    *                                                                 *
    *  DemoApp::OnRender                                              *
    *                                                                 *
    *  Called whenever the application needs to display the client    *
    *  window.                                                        *
    *                                                                 *
    *  Note that this function will not render anything if the window *
    *  is occluded (eg. obscured by other windows or off monitor).    *
    *  Also, this function will automatically discard device-specific *
    *  resources if the D3D device disappears during execution, and   *
    *  will recreate the resources the next time it's invoked.        *
    *                                                                 *
    ******************************************************************/

    HRESULT DemoApp::OnRender(const PAINTSTRUCT &ps)
    {
        HRESULT hr;

        IFR(DrawD2DContent(ps));

        return hr;
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::DrawD2DContent                                        *
    *                                                                 *
    *  This method draws blocks demonstrating different opacity       *
    *  masks.                                                         *
    *                                                                 *
    *                                                                 *
    *  Note that this function will not render anything if the window *
    *  is occluded (eg. obscured by other windows or off monitor).    *
    *  Also, this function will automatically discard device-specific *
    *  resources if the D3D device disappears during execution, and   *
    *  will recreate the resources the next time it's invoked.        *
    *                                                                 *
    ******************************************************************/

    HRESULT DemoApp::DrawD2DContent(const PAINTSTRUCT &ps)
    {
        HRESULT hr = S_OK;

        CreateDeviceResources();

        if (!(m_spRT->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))
        {
            m_spRT->BeginDraw();

            m_spRT->SetTransform(
                D2D1::Matrix3x2F::Identity()
                );
            //Rectangle that holds the shape of rectangles to be filled with brushes
            D2D1_RECT_F rcBrushRect = D2D1::RectF(0,5, 200, 195);

            //Rectangle that holds the shape of rectangles where captions are drawn with DrawText
            D2D1_RECT_F rcTextRect = D2D1::RectF(5,205,200,300);

            //Starting with a white background
            m_spRT->Clear(D2D1::ColorF(D2D1::ColorF::Blue));
       
            ////Original Bitmap
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(5, 5)));
            m_spRT->FillRectangle(&rcBrushRect,m_spOriginalBitmapBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);
      

      //
    //  m_spRT->DrawBitmap(m_spOpacityMask);
            //

     

      //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszOriginalBitmapText,
                wcslen(m_wszOriginalBitmapText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);

            //Linear Gradient Opacity Mask
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(255, 5)));
            m_spRT->FillRectangle(&rcBrushRect,m_spCheckerPatternBitmapBrush);
            m_spRT->FillRectangle(&rcBrushRect,m_spLinearGradientBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);

            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszLinearGradientOpacityMaskText,
                wcslen(m_wszLinearGradientOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);

            //Radial Gradient Opacity Mask
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(255, 255)));
            m_spRT->FillRectangle(&rcBrushRect,m_spCheckerPatternBitmapBrush);
            m_spRT->FillRectangle(&rcBrushRect,m_spRadialGradientBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);

            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszRadialGradientOpacityMaskText,
                wcslen(m_wszRadialGradientOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);

            //Bitmap Opacity Mask
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(255, 505)));
            m_spRT->FillRectangle(&rcBrushRect,m_spCheckerPatternBitmapBrush);
            m_spRT->FillRectangle(&rcBrushRect,m_spBitmapMaskBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);

            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszBitmapBrushOpacityMaskText,
                wcslen(m_wszBitmapBrushOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);
           
            //Bitmap with Linear Gradient Opacity Brush
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(505, 5)));   
            m_spRT->FillGeometry(m_spRectGeo,m_spOriginalBitmapBrush,m_spLinearGradientBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);
           
            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszWithLinearGradientOpacityMaskText,
                wcslen(m_wszWithLinearGradientOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);

            //Bitmap with Radial Gradient Opacity Brush
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(505, 255)));   
            m_spRT->FillGeometry(m_spRectGeo,m_spOriginalBitmapBrush,m_spRadialGradientBrush);
            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);
           
            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszWithRadialGradientOpacityMaskText,
                wcslen(m_wszWithRadialGradientOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);
       

            //Bitmap with Bitmap Opacity Brush
            m_spRT->SetTransform(D2D1::Matrix3x2F::Translation(D2D1::SizeF(505, 505)));   

            //D2D1_ANTIALIAS_MODE_ALIASED must be set for FillOpacityMask to function properly
            m_spRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
          
      m_spRT->FillOpacityMask(
       m_spBitmap,
                m_spBitmapMaskBrush,
       D2D1_OPACITY_MASK_CONTENT_GRAPHICS,
                0,
       0);

            m_spRT->DrawRectangle(&rcBrushRect,m_spBlackBrush,1,NULL);

            //Caption using a DirectWrite format from m_spDWriteFactory->CreateTextFormat
            m_spRT->DrawText(m_wszWithBitmapBrushOpacityMaskText,
                wcslen(m_wszWithBitmapBrushOpacityMaskText),
                m_spTextFormat,
                &rcTextRect,
                m_spBlackBrush);

       
            hr = m_spRT->EndDraw();
        }

        if (hr == D2DERR_RECREATE_TARGET)
        {
            DiscardDeviceResources();
        }

        return S_OK;
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::OnResize                                              *
    *                                                                 *
    *  If the application receives a WM_SIZE message, this method     *
    *  resize the render target appropriately.                        *
    *                                                                 *
    ******************************************************************/

    void DemoApp::OnResize(UINT width, UINT height)
    {
        if (m_spRT)
        {
            D2D1_SIZE_U size;
            size.width = width;
            size.height = height;
            HRESULT hr = m_spRT->Resize(size);

            // If we couldn't resize, release it and we'll recreate it
            // during the next render pass.
            if (FAILED(hr))
            {
                DiscardDeviceResources();
                InvalidateRect(m_hwnd, NULL, FALSE);
            }
        }
    }

    /******************************************************************
    *                                                                 *
    *  DemoApp::WndProc                                               *
    *                                                                 *
    *  Window message handler                                         *
    *                                                                 *
    ******************************************************************/

    LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        if (message == WM_CREATE)
        {
            LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
            DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;

            ::SetWindowLongPtrW(
                hwnd,
                GWLP_USERDATA,
                PtrToUlong(pDemoApp));

            return 1;
        }

        DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
                    ::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));

        if (pDemoApp)
        {
            switch(message)
            {
            case WM_SIZE:
                {
                    UINT width = LOWORD(lParam);
                    UINT height = HIWORD(lParam);
                    pDemoApp->OnResize(width, height);
                    //InvalidateRect(hwnd, NULL, true);
                }
                return 0;

            case WM_PAINT:
            case WM_DISPLAYCHANGE:
                {
                    Sleep(200);
        PAINTSTRUCT ps;
                    BeginPaint(hwnd, &ps);
                    pDemoApp->OnRender(ps);
                    EndPaint(hwnd, &ps);
                }
                return 0;

            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                }
                return 1;
            }
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    //
    //
    //
    // Creates a Direct2D bitmap from the specified
    // file name.
    //
    //
    //
    HRESULT DemoApp::LoadBitmapFromFile(
        ID2D1RenderTarget *pRenderTarget,
        IWICImagingFactory *pIWICFactory,
        PCWSTR uri,
        UINT destinationWidth,
        UINT destinationHeight,
        __deref_out ID2D1Bitmap **ppBitmap
        )
    {
        HRESULT hr = S_OK;
      
        IWICBitmapDecoderPtr spDecoder;
        IWICBitmapFrameDecodePtr spSource;
        IWICStreamPtr spStream;
        IWICFormatConverterPtr spConverter;
        IWICBitmapScalerPtr spScaler;

        IFR(pIWICFactory->CreateDecoderFromFilename(
            uri, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &spDecoder
            ));
       
        // Create the initial frame.
        IFR(spDecoder->GetFrame(0, &spSource));

        // Convert the image format to 32bppPBGRA -- which Direct2D expects.
        IFR(pIWICFactory->CreateFormatConverter(&spConverter));

        // If a new width or height was specified, create an
        // IWICBitmapScaler and use it to resize the image.
        if (destinationWidth != 0 || destinationHeight != 0){

            UINT originalWidth, originalHeight;
            spSource->GetSize(&originalWidth, &originalHeight);

            if (destinationWidth == 0){
                FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
                destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
            }
            else if (destinationHeight == 0) {
                FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
                destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
            }

            IFR(pIWICFactory->CreateBitmapScaler(&spScaler));
            IFR(spScaler->Initialize(
                    spSource,
                    destinationWidth,
                    destinationHeight,
                    WICBitmapInterpolationModeCubic
                    ));
       
            IFR(spConverter->Initialize(
                spScaler,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                NULL,
                0.f,
                WICBitmapPaletteTypeMedianCut
                ));
        }
        else // Don't scale the image.
        {

            IFR(spConverter->Initialize(
                spSource,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                NULL,
                0.f,
                WICBitmapPaletteTypeMedianCut
                ));

        }

        // Create a Direct2D bitmap from the WIC bitmap.
        IFR(pRenderTarget->CreateBitmapFromWicBitmap(
            spConverter,
            NULL,
            ppBitmap
            ));

        return hr;
    }

Page 1 of 1 (1 items) Previous Next