I am trying to draw cppwinrt Lottie animation into my Direct2D app, but can't understand how to do this...
It's possible draw this animation (WinRT::Windows::UI::Composition::Visual) and get data without xaml::Controls and windows?
I have loaded Lottie animation:
auto bmv = winrt::make<AnimatedVisuals::LottieLogo1>();
auto avptr = bmv.TryCreateAnimatedVisual(compositor, diags);
m_visual = avptr.RootVisual();
auto progressAnimation = compositor.CreateScalarKeyFrameAnimation();
progressAnimation.Duration(std::chrono::seconds(5));
progressAnimation.IterationBehavior(winrt::Windows::UI::Composition::AnimationIterationBehavior::Forever);
progressAnimation.Direction(winrt::Windows::UI::Composition::AnimationDirection::Alternate);
auto linearEasing = compositor.CreateLinearEasingFunction();
progressAnimation.InsertKeyFrame(0, 0, linearEasing);
progressAnimation.InsertKeyFrame(1, 1, linearEasing);
m_visual.Properties().StartAnimation(L"Progress", progressAnimation);
and now I need to draw this animation on the d2dbitmap or get pixels.
I tried to create the framepool but frames not arrived:
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_device;{auto d3dDevice = CreateD3DDevice();auto dxgiDevice = d3dDevice.as<IDXGIDevice>();if (dxgiDevice){hr = CreateDirect3DDevice(dxgiDevice.get(), &m_device);}}
m_framePool = winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool::Create(
m_device,
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
3,
winrt::Windows::Graphics::SizeInt32({ 400, 400 }));
m_session = m_framePool.CreateCaptureSession(winrt::Windows::Graphics::Capture::GraphicsCaptureItem::CreateFromVisual(m_visual));
m_frameArrived = m_framePool.FrameArrived(winrt::auto_revoke, { this, &CLottie::OnFrameArrived });
m_session.StartCapture();
It's possible draw this animation and get data without xaml::Controls and windows?
UPDATE:
auto controller = CreateDispatcherQueueController();
winrt::Windows::UI::Composition::Compositor compositor{};
CComPtr<ABI::Windows::UI::Composition::ICompositorInterop> compositorInterop;
hr = winrt::get_unknown(compositor)->QueryInterface(&compositorInterop);
winrt::com_ptr<ABI::Windows::UI::Composition::ICompositionGraphicsDevice> device = nullptr;
hr = compositorInterop->CreateGraphicsDevice(direct2dDevice, device.put());
auto gDevice = device.as<winrt::Windows::UI::Composition::CompositionGraphicsDevice>();
winrt::Windows::Foundation::Size surfaceSize{ 400, 400 };
winrt::Windows::UI::Composition::CompositionDrawingSurface surface = gDevice.CreateDrawingSurface(surfaceSize,
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
auto brush = compositor.CreateSurfaceBrush(surface);
float width = 400.0f, height = 400.0f;
winrt::Windows::UI::Composition::SpriteVisual visual = compositor.CreateSpriteVisual();
visual.Brush(brush);
visual.Size({ width, height });
winrt::Windows::UI::Composition::ShapeVisual shape = compositor.CreateShapeVisual();
shape.Size({ 100.0f,100.0f });
auto circleGeometry = compositor.CreateEllipseGeometry();
circleGeometry.Radius(winrt::Windows::Foundation::Numerics::float2(30, 30));
auto circleShape = compositor.CreateSpriteShape(circleGeometry);
circleShape.FillBrush(compositor.CreateColorBrush(winrt::Windows::UI::Colors::Orange()));
circleShape.Offset(winrt::Windows::Foundation::Numerics::float2(50, 50));
shape.Shapes().Append(circleShape);
visual.Children().InsertAtTop(shape);
auto surfaceInterop = surface.as<ABI::Windows::UI::Composition::ICompositionDrawingSurfaceInterop>();
CComPtr<ID2D1DeviceContext> dc;
POINT offset = {};
hr = surfaceInterop->BeginDraw(nullptr,
__uuidof(dc),
reinterpret_cast<void**>(&dc),
&offset);
CComPtr<ID2D1Bitmap1> bitmap = nullptr;
D2D1_BITMAP_PROPERTIES1 prop;
prop.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
prop.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
prop.dpiX = 96;
prop.dpiY = 96;
prop.bitmapOptions = D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
prop.colorContext = NULL;
hr = dc->CreateBitmap(D2D1::SizeU(width, height), NULL, 0, prop, &bitmap);
hr = bitmap->CopyFromRenderTarget(NULL, dc, NULL);
hr = surfaceInterop->EndDraw();