On my second approach I extracted each frame of the.
Approach: Extracting and rendering each frame as DirectX Texture So either there is a trick here or it's simply not efficient enough to use GDI+.Ģ. Obviously that cannot be tolerated in any game with a framerate higher than 1, lol.Įven with smaller images the method is too exhausting for acceptable performance. Tests with a resolution of 1920 x 1080 resulted in 800-1500ms per Gdiplus::Graphics::DrawImage call! }The huge problem with this attempt is that Gdiplus::Graphics::DrawImage takes a huuuuge amount of time to draw larger images to the surface. G_pD3dApp->GetBackBufferDesc().Width, g_pD3dApp->GetBackBufferDesc().Height) Getting the Device Context Handle from the backbuffer surface for GDI+ drawing Render called each time before the swapchain (60 Hz in my case) M_pImage->SelectActiveFrame(&Guid, m_iCurrentFrame)
Update / Ticking logic for the GIF, setting the frames to render with certain velocity G_pD3dDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) Here comes the little "hack" by getting the back buffer surface for gdi+ graphics rendering later on GUID Guid = FrameDimensionTime // Predefined multi-frame dimension ID in GdiPlusImaging.h M_pImage->GetPropertyItem(PropertyTagFrameDelay, TotalBuffer, m_pItem) UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay) M_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs) StringFromGUID2(m_pDimensionIDs, strGuid, 39) M_pImage->GetFrameDimensionsList(m_pDimensionIDs, count) UINT count = m_pImage->GetFrameDimensionsCount() M_pImage = Image::FromFile(L"C:\\opening.gif") Basic loading of the GIF, it's animations and other important properties Used for time calculations for frame display velocity IDirect3DSurface9* surface // Pointer to the back buffers surface UINT m_iCurrentFrame // The index of the current frame to render Gdiplus::PropertyItem* m_pItem // Additional GDI+ properties for the GIF UINT m_FrameCount // Amount of Frames stored in the GIF Gdiplus::GUID* m_pDimensionIDs // GDI+ Image dimensions Gdiplus::Image* m_pImage // GDI+ image handle LPDIRECT3DDEVICE9 g_pD3dDev // Global directX device pointer
This is the simplified code I came up with:Ĭode: // Member and global vars used for this (dumb, I know but it's just for testing atm) However GDI+ is hardly used together with DirectX I noticed and it's not really made to work with it, but with some "hacks" it can be implemented using the back buffers surface (IDirect3DSurface9*). To init / restored / invalidate / release components, respective methods exist but are simplified / left out for the sake of simplicity.Īs I was using GDI+ several times when developing MFC applications already, I knew it could render pretty much any common image file format, including. Afterwards the Render() methods are called to draw onto the back buffer before flipping. Each time the 3D Environment gets rendered, the Tick() methods of all components are called to update the game logic. I'm developing a DirectX9 3D Application that uses swapchaining (having a front & backbuffer). I feel like there is something more straight forward and efficient to use. So I came up with different approaches to do this, but nothing convinced me fully yet. gif file support in DirectX and searching the net hardly gives any good advise. Starting from little loading / button animations to showing a bigger loading screen. I would like to use it for a large scope of animations. Why not use it for games too, instead of converting it to single frames or videos or rarely used formats, I thought. I've been stuck with this topic for a while now.GIF is like the most commonly used file format for short image animations.