packages feed

dear-imgui 2.2.0 → 2.2.1

raw patch · 15 files changed

+726/−119 lines, 15 filesdep +system-cxx-std-libdep ~basedep ~containersdep ~filepathnew-component:exe:sdlrendererPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: system-cxx-std-lib

Dependency ranges changed: base, containers, filepath, megaparsec, sdl2, template-haskell, text, vulkan

API changes (from Hackage documentation)

+ DearImGui: beginDisabled :: MonadIO m => CBool -> m ()
+ DearImGui: endDisabled :: MonadIO m => m ()
+ DearImGui: framerate :: MonadIO m => m Float
+ DearImGui: withCloseableWindow :: (HasSetter ref Bool, MonadUnliftIO m) => Text -> ref -> m () -> m ()
+ DearImGui: withDisabled :: (MonadUnliftIO m, HasGetter ref Bool) => ref -> m a -> m a
+ DearImGui.Raw: beginDisabled :: MonadIO m => CBool -> m ()
+ DearImGui.Raw: endDisabled :: MonadIO m => m ()
+ DearImGui.Raw: framerate :: MonadIO m => m Float
+ DearImGui.SDL: dispatchRawEvent :: MonadIO m => Ptr Event -> m Bool
+ DearImGui.SDL.Renderer: sdl2InitForSDLRenderer :: MonadIO m => Window -> Renderer -> m Bool
+ DearImGui.SDL.Renderer: sdlRendererInit :: MonadIO m => Renderer -> m Bool
+ DearImGui.SDL.Renderer: sdlRendererNewFrame :: MonadIO m => m ()
+ DearImGui.SDL.Renderer: sdlRendererRenderDrawData :: MonadIO m => DrawData -> m ()
+ DearImGui.SDL.Renderer: sdlRendererShutdown :: MonadIO m => m ()
+ DearImGui.Vulkan: [colorAttachmentFormat] :: InitInfo -> !Maybe Format
+ DearImGui.Vulkan: [useDynamicRendering] :: InitInfo -> !Bool
- DearImGui.Vulkan: InitInfo :: !Instance -> !PhysicalDevice -> !Device -> !Word32 -> !Queue -> !PipelineCache -> !DescriptorPool -> !Word32 -> !Word32 -> !Word32 -> !SampleCountFlagBits -> Maybe AllocationCallbacks -> (Result -> IO ()) -> InitInfo
+ DearImGui.Vulkan: InitInfo :: !Instance -> !PhysicalDevice -> !Device -> !Word32 -> !Queue -> !PipelineCache -> !DescriptorPool -> !Word32 -> !Word32 -> !Word32 -> !SampleCountFlagBits -> !Maybe Format -> !Bool -> Maybe AllocationCallbacks -> (Result -> IO ()) -> InitInfo

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Changelog for dear-imgui +## [2.2.1]++- Added `DearImGui.SDL.Renderer` backend and `sdlrenderer` example.+- Added `DearImgui.withCloseableWindow`.+- Added `DearImgui.Raw.framerate`.+- Added dynamic rendering and color attachment format options for `DearImGui.Vulkan` backend.+- Fixed Windows builds by using `system-cxx-std-lib` for GHC>=9.4.+ ## [2.2.0]  - `imgui` updated to [1.89.9].@@ -116,6 +124,7 @@ [2.1.2]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.1.2 [2.1.3]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.1.3 [2.2.0]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.2.0+[2.2.1]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.2.1  [1.89.9]: https://github.com/ocornut/imgui/releases/tag/v1.89.9 [1.87]: https://github.com/ocornut/imgui/releases/tag/v1.87
README.md view
@@ -31,29 +31,30 @@ With this done, the following module is the "Hello, World!" of ImGui:  ``` haskell-{-# language BlockArguments #-}-{-# language LambdaCase #-} {-# language OverloadedStrings #-}  module Main ( main ) where -import Control.Exception-import Control.Monad.IO.Class-import Control.Monad.Managed import DearImGui-import DearImGui.OpenGL2+import DearImGui.OpenGL3 import DearImGui.SDL import DearImGui.SDL.OpenGL+ import Graphics.GL import SDL +import Control.Monad.Managed+import Control.Monad.IO.Class ()+import Control.Monad (when, unless)+import Control.Exception (bracket, bracket_)+ main :: IO () main = do   -- Initialize SDL   initializeAll -  runManaged do-    -- Create a window using SDL. As we're using OpenGL, we need to enable OpenGL too.+  runManaged $ do+    -- Create a window using SDL; as we're using OpenGL, we enable OpenGL too     window <- do       let title = "Hello, Dear ImGui!"       let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL }@@ -61,64 +62,59 @@      -- Create an OpenGL context     glContext <- managed $ bracket (glCreateContext window) glDeleteContext-     -- Create an ImGui context     _ <- managed $ bracket createContext destroyContext      -- Initialize ImGui's SDL2 backend-    _ <- managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown-+    managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown     -- Initialize ImGui's OpenGL backend-    _ <- managed_ $ bracket_ openGL2Init openGL2Shutdown+    managed_ $ bracket_ openGL3Init openGL3Shutdown      liftIO $ mainLoop window - mainLoop :: Window -> IO ()-mainLoop window = unlessQuit do+mainLoop window = unlessQuit $ do   -- Tell ImGui we're starting a new frame-  openGL2NewFrame+  openGL3NewFrame   sdl2NewFrame   newFrame    -- Build the GUI-  withWindowOpen "Hello, ImGui!" do+  withWindowOpen "Hello, ImGui!" $ do     -- Add a text widget     text "Hello, ImGui!"      -- Add a button widget, and call 'putStrLn' when it's clicked-    button "Clickety Click" >>= \case-      False -> return ()-      True  -> putStrLn "Ow!"+    button "Clickety Click" >>= \clicked ->+      when clicked $ putStrLn "Ow!"    -- Show the ImGui demo window   showDemoWindow    -- Render   glClear GL_COLOR_BUFFER_BIT-   render-  openGL2RenderDrawData =<< getDrawData+  openGL3RenderDrawData =<< getDrawData    glSwapWindow window-   mainLoop window-   where-    -- Process the event loop-    unlessQuit action = do-      shouldQuit <- checkEvents-      if shouldQuit then pure () else action+  -- Process the event loop+  unlessQuit action = do+    shouldQuit <- gotQuitEvent+    unless shouldQuit action -    checkEvents = do-      pollEventWithImGui >>= \case-        Nothing ->-          return False-        Just event ->-          (isQuit event ||) <$> checkEvents+  gotQuitEvent = do+    ev <- pollEventWithImGui -    isQuit event =-      SDL.eventPayload event == SDL.QuitEvent+    case ev of+      Nothing ->+        return False+      Just event ->+        (isQuit event ||) <$> gotQuitEvent++  isQuit event =+    eventPayload event == QuitEvent ```  # Hacking
dear-imgui.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0  name: dear-imgui-version: 2.2.0+version: 2.2.1 author: Oliver Charles maintainer: ollie@ocharles.org.uk, aenor.realm@gmail.com license: BSD-3-Clause@@ -94,6 +94,15 @@   manual:     True +flag sdl-renderer+  description:+    Enable SDL Renderer backend (requires the SDL_RenderGeometry function available in SDL 2.0.18+).+    The sdl configuration flag must also be enabled when using this flag.+  default:+    False+  manual:+    True+ flag glfw   description:     Enable GLFW backend.@@ -140,7 +149,7 @@ common common   build-depends:       base-        >= 4.12 && < 4.19+        >= 4.12 && < 4.20   default-language:       Haskell2010 @@ -170,8 +179,10 @@     imgui/imgui_draw.cpp     imgui/imgui_tables.cpp     imgui/imgui_widgets.cpp-  extra-libraries:-    stdc+++  if impl(ghc >= 9.4)+    build-depends: system-cxx-std-lib+  else+    extra-libraries: stdc++   include-dirs:     imgui   build-depends:@@ -222,7 +233,7 @@     other-modules:       DearImGui.Vulkan.Types     build-depends:-        vulkan+        vulkan >= 3.20       , unliftio     cxx-sources:       imgui/backends/imgui_impl_vulkan.cpp@@ -241,7 +252,7 @@     exposed-modules:       DearImGui.SDL     build-depends:-      sdl2+      sdl2 >= 2     cxx-sources:       imgui/backends/imgui_impl_sdl2.cpp @@ -260,6 +271,12 @@       exposed-modules:         DearImGui.SDL.Vulkan +    if flag(sdl-renderer)+      exposed-modules:+        DearImGui.SDL.Renderer+      cxx-sources:+        imgui/backends/imgui_impl_sdlrenderer2.cpp+   if flag(glfw)     exposed-modules:       DearImGui.GLFW@@ -291,23 +308,23 @@     , DearImGui.Generator.Types   build-depends:       template-haskell-        >= 2.15 && < 2.21+        >= 2.15 && < 2.22     , containers-       ^>= 0.6.2.1+        >= 0.6.2.1 && < 0.8     , directory         >= 1.3 && < 1.4     , filepath-        >= 1.4 && < 1.5+        >= 1.4 && < 1.6     , inline-c         >= 0.9.0.0 && < 0.10     , megaparsec-        >= 9.0 && < 9.3+        >= 9.0 && < 9.7     , parser-combinators         >= 1.2.0 && < 1.4     , scientific         >= 0.3.6.2 && < 0.3.8     , text-        >= 1.2.4 && < 2.1+        >= 1.2.4 && < 2.2     , th-lift         >= 0.7 && < 0.9     , transformers@@ -358,6 +375,14 @@   if (!flag(examples) || !flag(sdl) || !flag(opengl3))     buildable: False +executable sdlrenderer+  import: common, exe-flags+  main-is: Renderer.hs+  hs-source-dirs: examples/sdl+  build-depends: sdl2, dear-imgui, managed, text+  if (!flag(examples) || !flag(sdl) || !flag(sdl-renderer))+    buildable: False+ executable vulkan   import: common, exe-flags   main-is: Main.hs@@ -380,7 +405,7 @@       , sdl2           >= 2.5.3.0 && < 2.6       , text-          >= 1.2.4 && < 2.1+          >= 1.2.4 && < 2.2       , transformers           >= 0.5.6 && < 0.7       , unliftio@@ -390,7 +415,7 @@       , vector          >= 0.12.1.2 && < 0.14       , vulkan-         >= 3.12+         >= 3.20       , vulkan-utils          >= 0.5       , VulkanMemoryAllocator
examples/Readme.hs view
@@ -1,29 +1,30 @@ -- NOTE: If this is file is edited, please also copy and paste it into -- README.md. -{-# language BlockArguments #-}-{-# language LambdaCase #-} {-# language OverloadedStrings #-}  module Main ( main ) where -import Control.Exception-import Control.Monad.IO.Class-import Control.Monad.Managed import DearImGui-import DearImGui.OpenGL2+import DearImGui.OpenGL3 import DearImGui.SDL import DearImGui.SDL.OpenGL+ import Graphics.GL import SDL +import Control.Monad.Managed+import Control.Monad.IO.Class ()+import Control.Monad (when, unless)+import Control.Exception (bracket, bracket_)+ main :: IO () main = do   -- Initialize SDL   initializeAll -  runManaged do-    -- Create a window using SDL. As we're using OpenGL, we need to enable OpenGL too.+  runManaged $ do+    -- Create a window using SDL; as we're using OpenGL, we enable OpenGL too     window <- do       let title = "Hello, Dear ImGui!"       let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL }@@ -31,61 +32,56 @@      -- Create an OpenGL context     glContext <- managed $ bracket (glCreateContext window) glDeleteContext-     -- Create an ImGui context     _ <- managed $ bracket createContext destroyContext      -- Initialize ImGui's SDL2 backend-    _ <- managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown-+    managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown     -- Initialize ImGui's OpenGL backend-    _ <- managed_ $ bracket_ openGL2Init openGL2Shutdown+    managed_ $ bracket_ openGL3Init openGL3Shutdown      liftIO $ mainLoop window - mainLoop :: Window -> IO ()-mainLoop window = unlessQuit do+mainLoop window = unlessQuit $ do   -- Tell ImGui we're starting a new frame-  openGL2NewFrame+  openGL3NewFrame   sdl2NewFrame   newFrame    -- Build the GUI-  withWindowOpen "Hello, ImGui!" do+  withWindowOpen "Hello, ImGui!" $ do     -- Add a text widget     text "Hello, ImGui!"      -- Add a button widget, and call 'putStrLn' when it's clicked-    button "Clickety Click" >>= \case-      False -> return ()-      True  -> putStrLn "Ow!"+    button "Clickety Click" >>= \clicked ->+      when clicked $ putStrLn "Ow!"    -- Show the ImGui demo window   showDemoWindow    -- Render   glClear GL_COLOR_BUFFER_BIT-   render-  openGL2RenderDrawData =<< getDrawData+  openGL3RenderDrawData =<< getDrawData    glSwapWindow window-   mainLoop window-   where-    -- Process the event loop-    unlessQuit action = do-      shouldQuit <- checkEvents-      if shouldQuit then pure () else action+  -- Process the event loop+  unlessQuit action = do+    shouldQuit <- gotQuitEvent+    unless shouldQuit action -    checkEvents = do-      pollEventWithImGui >>= \case-        Nothing ->-          return False-        Just event ->-          (isQuit event ||) <$> checkEvents+  gotQuitEvent = do+    ev <- pollEventWithImGui -    isQuit event =-      SDL.eventPayload event == SDL.QuitEvent+    case ev of+      Nothing ->+        return False+      Just event ->+        (isQuit event ||) <$> gotQuitEvent++  isQuit event =+    eventPayload event == QuitEvent
+ examples/sdl/Renderer.hs view
@@ -0,0 +1,146 @@+{-# language BlockArguments #-}+{-# language LambdaCase #-}+{-# language OverloadedStrings #-}++-- | Port of [example_sdl2_sdlrenderer2](https://github.com/ocornut/imgui/blob/54c1bdecebf3c9bb9259c07c5f5666bb4bd5c3ea/examples/example_sdl2_sdlrenderer2/main.cpp).+--+-- Minor differences:+-- - No changing of the clear color via @ImGui::ColorEdit3@ as a Haskell binding+-- doesn't yet exist for this function.+-- - No high DPI renderer scaling as this seems to be in flux [upstream](https://github.com/ocornut/imgui/issues/6065)++module Main ( main ) where++import Control.Exception (bracket, bracket_)+import Control.Monad.IO.Class (MonadIO(liftIO))+import Control.Monad.Managed (managed, managed_, runManaged)+import Data.IORef (IORef, newIORef)+import Data.Text (pack)+import DearImGui+import DearImGui.SDL (pollEventWithImGui, sdl2NewFrame, sdl2Shutdown)+import DearImGui.SDL.Renderer+  ( sdl2InitForSDLRenderer, sdlRendererInit, sdlRendererNewFrame, sdlRendererRenderDrawData+  , sdlRendererShutdown+  )+import SDL (V4(V4), ($=), ($~), get)+import Text.Printf (printf)+import qualified SDL+++main :: IO ()+main = do+  -- Initialize SDL2+  SDL.initializeAll++  runManaged do+    -- Create a window using SDL2+    window <- do+      let title = "ImGui + SDL2 Renderer"+      let config = SDL.defaultWindow+            { SDL.windowInitialSize = SDL.V2 1280 720+            , SDL.windowResizable = True+            , SDL.windowPosition = SDL.Centered+            }+      managed $ bracket (SDL.createWindow title config) SDL.destroyWindow++    -- Create an SDL2 renderer+    renderer <- managed do+      bracket+        (SDL.createRenderer window (-1) SDL.defaultRenderer)+        SDL.destroyRenderer++    -- Create an ImGui context+    _ <- managed $ bracket createContext destroyContext++    -- Initialize ImGui's SDL2 backend+    _ <- managed_ do+      bracket_ (sdl2InitForSDLRenderer window renderer) sdl2Shutdown++    -- Initialize ImGui's SDL2 renderer backend+    _ <- managed_ $ bracket_ (sdlRendererInit renderer) sdlRendererShutdown++    liftIO $ mainLoop renderer+++mainLoop :: SDL.Renderer -> IO ()+mainLoop renderer = do+  refs <- newRefs+  go refs+  where+  go refs = unlessQuit do+    -- Tell ImGui we're starting a new frame+    sdlRendererNewFrame+    sdl2NewFrame+    newFrame++    -- Show the ImGui demo window+    get (refsShowDemoWindow refs) >>= \case+      False -> pure ()+      True -> showDemoWindow++    withWindowOpen "Hello, world!" do+      text "This is some useful text."+      _ <- checkbox "Demo Window" $ refsShowDemoWindow refs+      _ <- checkbox "Another Window" $ refsShowAnotherWindow refs+      _ <- sliderFloat "float" (refsFloat refs) 0 1++      button "Button" >>= \case+        False -> pure ()+        True -> refsCounter refs $~ succ+      sameLine+      counter <- get $ refsCounter refs+      text $ "counter = " <> pack (show counter)++      fr <- framerate+      text+        $ pack+        $ printf "Application average %.3f ms/frame (%.1f FPS)" (1000 / fr) fr++    get (refsShowAnotherWindow refs) >>= \case+      False -> pure ()+      True ->+        withCloseableWindow "Another Window" (refsShowAnotherWindow refs) do+          text "Hello from another window!"+          button "Close Me" >>= \case+            False -> pure ()+            True -> refsShowAnotherWindow refs $= False++    -- Render+    SDL.rendererDrawColor renderer $= V4 0 0 0 255+    SDL.clear renderer+    render+    sdlRendererRenderDrawData =<< getDrawData+    SDL.present renderer++    go refs++  -- Process the event loop+  unlessQuit action = do+    shouldQuit <- checkEvents+    if shouldQuit then pure () else action++  checkEvents = do+    pollEventWithImGui >>= \case+      Nothing ->+        return False+      Just event ->+        (isQuit event ||) <$> checkEvents++  isQuit event =+    SDL.eventPayload event == SDL.QuitEvent+++data Refs = Refs+  { refsShowDemoWindow :: IORef Bool+  , refsShowAnotherWindow :: IORef Bool+  , refsFloat :: IORef Float+  , refsCounter :: IORef Int+  }++newRefs :: IO Refs+newRefs =+  Refs+    <$> newIORef True+    <*> newIORef False+    <*> newIORef 0+    <*> newIORef 0
examples/vulkan/Backend.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}@@ -99,6 +100,7 @@  -- vulkan import qualified Vulkan+import Vulkan.Core10.DeviceInitialization (pattern INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR) import qualified Vulkan.CStruct.Extends as Vulkan import qualified Vulkan.Requirement     as Vulkan import qualified Vulkan.Zero            as Vulkan@@ -156,9 +158,10 @@  data VulkanRequirements =   VulkanRequirements-    { instanceRequirements :: [ Vulkan.InstanceRequirement ]-    , deviceRequirements   :: [ Vulkan.DeviceRequirement   ]-    , queueFlags           :: Vulkan.QueueFlags+    { instanceRequirements    :: [ Vulkan.InstanceRequirement ]+    , instanceRequirementsOpt :: [ Vulkan.InstanceRequirement ]+    , deviceRequirements      :: [ Vulkan.DeviceRequirement   ]+    , queueFlags              :: Vulkan.QueueFlags     }  data ValidationLayerName@@ -167,12 +170,12 @@   deriving stock ( Eq, Show )  initialiseVulkanContext :: MonadVulkan m => InstanceType -> ByteString -> VulkanRequirements -> m VulkanContext-initialiseVulkanContext instanceType appName ( VulkanRequirements { instanceRequirements, deviceRequirements, queueFlags } ) = do+initialiseVulkanContext instanceType appName ( VulkanRequirements { instanceRequirements, instanceRequirementsOpt, deviceRequirements, queueFlags } ) = do   logDebug "Creating Vulkan instance"   instanceInfo    <- vulkanInstanceInfo appName   instance'       <- case instanceType of-    NormalInstance -> Vulkan.Utils.createInstanceFromRequirements      instanceRequirements [] instanceInfo-    DebugInstance  -> Vulkan.Utils.createDebugInstanceFromRequirements instanceRequirements [] instanceInfo+    NormalInstance -> Vulkan.Utils.createInstanceFromRequirements      instanceRequirements instanceRequirementsOpt instanceInfo+    DebugInstance  -> Vulkan.Utils.createDebugInstanceFromRequirements instanceRequirements instanceRequirementsOpt instanceInfo   physicalDevice  <- logDebug "Creating physical device"      *> createPhysicalDevice instance'   queueFamily     <- logDebug "Finding suitable queue family" *> findQueueFamilyIndex physicalDevice queueFlags   let@@ -236,7 +239,7 @@     createInfo =       Vulkan.InstanceCreateInfo         { Vulkan.next                  = ()-        , Vulkan.flags                 = Vulkan.zero+        , Vulkan.flags                 = INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR         , Vulkan.applicationInfo       = Just appInfo         , Vulkan.enabledLayerNames     = Boxed.Vector.fromList enabledLayers         , Vulkan.enabledExtensionNames = mempty@@ -400,8 +403,6 @@ createSwapchain physicalDevice device surface surfaceFormat imageUsage imageCount oldSwapchain = do    surfaceCapabilities <- Vulkan.getPhysicalDeviceSurfaceCapabilitiesKHR physicalDevice ( Vulkan.SurfaceKHR surface )--  ( _, presentModes ) <- Vulkan.getPhysicalDeviceSurfacePresentModesKHR physicalDevice ( Vulkan.SurfaceKHR surface )    let     presentMode :: Vulkan.PresentModeKHR
examples/vulkan/Main.hs view
@@ -148,10 +148,14 @@         , mouseMode  = SDL.AbsoluteLocation         }   let+    compatExtensions =+      [ Vulkan.KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME+      ]     vulkanReqs :: VulkanRequirements     vulkanReqs =       VulkanRequirements         { instanceRequirements = instanceExtensions windowExtensions+        , instanceRequirementsOpt = instanceExtensions compatExtensions         , deviceRequirements   = []         , queueFlags           = Vulkan.QUEUE_GRAPHICS_BIT         }@@ -387,14 +391,16 @@       , device       , queueFamily       , queue-      , pipelineCache  = Vulkan.NULL_HANDLE-      , descriptorPool = imGuiDescriptorPool-      , subpass        = 0+      , pipelineCache         = Vulkan.NULL_HANDLE+      , descriptorPool        = imGuiDescriptorPool+      , subpass               = 0       , minImageCount       , imageCount-      , msaaSamples    = Vulkan.SAMPLE_COUNT_1_BIT-      , mbAllocator    = Nothing-      , checkResult    = \case { Vulkan.SUCCESS -> pure (); e -> throw $ Vulkan.VulkanException e }+      , msaaSamples           = Vulkan.SAMPLE_COUNT_1_BIT+      , mbAllocator           = Nothing+      , useDynamicRendering   = False+      , colorAttachmentFormat = Nothing+      , checkResult           = \case { Vulkan.SUCCESS -> pure (); e -> throw $ Vulkan.VulkanException e }       }    logDebug "Initialising ImGui SDL2 for Vulkan"
+ imgui/backends/imgui_impl_sdlrenderer2.cpp view
@@ -0,0 +1,262 @@+// dear imgui: Renderer Backend for SDL_Renderer for SDL2+// (Requires: SDL 2.0.17+)++// Note how SDL_Renderer is an _optional_ component of SDL2.+// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.+// If your application will want to render any non trivial amount of graphics other than UI,+// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and+// it might be difficult to step out of those boundaries.++// Implemented features:+//  [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!+//  [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.++// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.+// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.+// Read online: https://github.com/ocornut/imgui/tree/master/docs++// CHANGELOG+//  2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.+//  2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.+//  2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19.+//  2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.+//  2021-10-06: Backup and restore modified ClipRect/Viewport.+//  2021-09-21: Initial version.++#include "imgui.h"+#ifndef IMGUI_DISABLE+#include "imgui_impl_sdlrenderer2.h"+#include <stdint.h>     // intptr_t++// Clang warnings with -Weverything+#if defined(__clang__)+#pragma clang diagnostic push+#pragma clang diagnostic ignored "-Wsign-conversion"    // warning: implicit conversion changes signedness+#endif++// SDL+#include <SDL.h>+#if !SDL_VERSION_ATLEAST(2,0,17)+#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function+#endif++// SDL_Renderer data+struct ImGui_ImplSDLRenderer2_Data+{+    SDL_Renderer*   SDLRenderer;+    SDL_Texture*    FontTexture;+    ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); }+};++// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts+// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.+static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()+{+    return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;+}++// Functions+bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)+{+    ImGuiIO& io = ImGui::GetIO();+    IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");+    IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");++    // Setup backend capabilities flags+    ImGui_ImplSDLRenderer2_Data* bd = IM_NEW(ImGui_ImplSDLRenderer2_Data)();+    io.BackendRendererUserData = (void*)bd;+    io.BackendRendererName = "imgui_impl_sdlrenderer2";+    io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.++    bd->SDLRenderer = renderer;++    return true;+}++void ImGui_ImplSDLRenderer2_Shutdown()+{+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();+    IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");+    ImGuiIO& io = ImGui::GetIO();++    ImGui_ImplSDLRenderer2_DestroyDeviceObjects();++    io.BackendRendererName = nullptr;+    io.BackendRendererUserData = nullptr;+    io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;+    IM_DELETE(bd);+}++static void ImGui_ImplSDLRenderer2_SetupRenderState()+{+	ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();++	// Clear out any viewports and cliprect set by the user+    // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.+	SDL_RenderSetViewport(bd->SDLRenderer, nullptr);+	SDL_RenderSetClipRect(bd->SDLRenderer, nullptr);+}++void ImGui_ImplSDLRenderer2_NewFrame()+{+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();+    IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDLRenderer2_Init()?");++    if (!bd->FontTexture)+        ImGui_ImplSDLRenderer2_CreateDeviceObjects();+}++void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data)+{+	ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();++	// If there's a scale factor set by the user, use that instead+    // If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass+    // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.+    float rsx = 1.0f;+	float rsy = 1.0f;+	SDL_RenderGetScale(bd->SDLRenderer, &rsx, &rsy);+    ImVec2 render_scale;+	render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;+	render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;++	// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)+	int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);+	int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);+	if (fb_width == 0 || fb_height == 0)+		return;++    // Backup SDL_Renderer state that will be modified to restore it afterwards+    struct BackupSDLRendererState+    {+        SDL_Rect    Viewport;+        bool        ClipEnabled;+        SDL_Rect    ClipRect;+    };+    BackupSDLRendererState old = {};+    old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer) == SDL_TRUE;+    SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport);+    SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect);++	// Will project scissor/clipping rectangles into framebuffer space+	ImVec2 clip_off = draw_data->DisplayPos;         // (0,0) unless using multi-viewports+	ImVec2 clip_scale = render_scale;++    // Render command lists+    ImGui_ImplSDLRenderer2_SetupRenderState();+    for (int n = 0; n < draw_data->CmdListsCount; n++)+    {+        const ImDrawList* cmd_list = draw_data->CmdLists[n];+        const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;+        const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;++        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)+        {+            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];+            if (pcmd->UserCallback)+            {+                // User callback, registered via ImDrawList::AddCallback()+                // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)+                if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)+                    ImGui_ImplSDLRenderer2_SetupRenderState();+                else+                    pcmd->UserCallback(cmd_list, pcmd);+            }+            else+            {+                // Project scissor/clipping rectangles into framebuffer space+                ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);+                ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);+                if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }+                if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }+                if (clip_max.x > (float)fb_width) { clip_max.x = (float)fb_width; }+                if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }+                if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)+                    continue;++                SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };+                SDL_RenderSetClipRect(bd->SDLRenderer, &r);++                const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos));+                const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv));+#if SDL_VERSION_ATLEAST(2,0,19)+                const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19++#else+                const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18+#endif++                // Bind texture, Draw+				SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();+                SDL_RenderGeometryRaw(bd->SDLRenderer, tex,+                    xy, (int)sizeof(ImDrawVert),+                    color, (int)sizeof(ImDrawVert),+                    uv, (int)sizeof(ImDrawVert),+                    cmd_list->VtxBuffer.Size - pcmd->VtxOffset,+                    idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));+            }+        }+    }++    // Restore modified SDL_Renderer state+    SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport);+    SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : nullptr);+}++// Called by Init/NewFrame/Shutdown+bool ImGui_ImplSDLRenderer2_CreateFontsTexture()+{+    ImGuiIO& io = ImGui::GetIO();+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();++    // Build texture atlas+    unsigned char* pixels;+    int width, height;+    io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);   // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.++    // Upload texture to graphics system+    // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)+    bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);+    if (bd->FontTexture == nullptr)+    {+        SDL_Log("error creating texture");+        return false;+    }+    SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);+    SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);+    SDL_SetTextureScaleMode(bd->FontTexture, SDL_ScaleModeLinear);++    // Store our identifier+    io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);++    return true;+}++void ImGui_ImplSDLRenderer2_DestroyFontsTexture()+{+    ImGuiIO& io = ImGui::GetIO();+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();+    if (bd->FontTexture)+    {+        io.Fonts->SetTexID(0);+        SDL_DestroyTexture(bd->FontTexture);+        bd->FontTexture = nullptr;+    }+}++bool ImGui_ImplSDLRenderer2_CreateDeviceObjects()+{+    return ImGui_ImplSDLRenderer2_CreateFontsTexture();+}++void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()+{+    ImGui_ImplSDLRenderer2_DestroyFontsTexture();+}++//-----------------------------------------------------------------------------++#if defined(__clang__)+#pragma clang diagnostic pop+#endif++#endif // #ifndef IMGUI_DISABLE
src/DearImGui.hs view
@@ -45,6 +45,7 @@     -- * Windows   , withWindow   , withWindowOpen+  , withCloseableWindow   , withFullscreen   , fullscreenFlags @@ -278,6 +279,11 @@   , Raw.beginTooltip   , Raw.endTooltip +    -- ** Disabled blocks+  , withDisabled+  , Raw.beginDisabled+  , Raw.endDisabled+     -- * Popups/Modals      -- ** Generic@@ -335,6 +341,7 @@   , Raw.getBackgroundDrawList   , Raw.getForegroundDrawList   , Raw.imCol32+  , Raw.framerate      -- * Types   , module DearImGui.Enums@@ -415,6 +422,26 @@ withWindowOpen name action =   withWindow name (`when` action) +-- | Append items to a closeable window unless it is collapsed or fully clipped.+--+-- You may append multiple times to the same window during the same frame+-- by calling 'withWindowOpen' in multiple places.+--+-- The 'Bool' state variable will be set to 'False' when the window's close+-- button is pressed.+withCloseableWindow :: (HasSetter ref Bool, MonadUnliftIO m) => Text -> ref -> m () -> m ()+withCloseableWindow name ref action = bracket open close (`when` action)+  where+    open = liftIO do+      with 1 \boolPtr -> do+        Text.withCString name \namePtr -> do+          isVisible <- Raw.begin namePtr (Just boolPtr) Nothing+          isOpen <- peek boolPtr+          when (isOpen == 0) $ ref $=! False+          pure isVisible++    close = liftIO . const Raw.end+ -- | Append items to a fullscreen window. -- -- The action runs inside a window that is set to behave as a backdrop.@@ -1740,6 +1767,17 @@ -- Can contain any kind of items. withTooltip ::  MonadUnliftIO m => m a -> m a withTooltip = bracket_ Raw.beginTooltip Raw.endTooltip+++-- | Action wrapper for disabled blocks.+--+-- See 'Raw.beginDisabled' and 'Raw.endDisabled' for more info.+withDisabled :: (MonadUnliftIO m, HasGetter ref Bool) => ref -> m a -> m a+withDisabled disabledRef action = do+  disabled <- get disabledRef+  if disabled then bracket_ (Raw.beginDisabled 1) Raw.endDisabled action else action++  -- | Returns 'True' if the popup is open, and you can start outputting to it. --
src/DearImGui/Raw.hs view
@@ -65,6 +65,8 @@   , setNextWindowSizeConstraints   , setNextWindowCollapsed   , setNextWindowBgAlpha+  , beginDisabled+  , endDisabled      -- ** Child Windows   , beginChild@@ -249,6 +251,7 @@   , getBackgroundDrawList   , getForegroundDrawList   , imCol32+  , framerate      -- * Types   , module DearImGui.Enums@@ -1581,6 +1584,29 @@   [C.exp| void { SetNextWindowBgAlpha($(float alpha)) } |]  +-- | Begin a block that may be disabled. This disables all user interactions+-- and dims item visuals.+--+-- Always call a matching 'endDisabled' for each 'beginDisabled' call.+--+-- The boolean argument is only intended to facilitate use of boolean+-- expressions. If you can avoid calling @beginDisabled 0@ altogether,+-- that should be preferred.+--+-- Wraps @ImGui::BeginDisabled()@+beginDisabled :: (MonadIO m) => CBool -> m ()+beginDisabled disabled = liftIO do+  [C.exp| void { BeginDisabled($(bool disabled)) } |]+++-- | Ends a block that may be disabled.+--+-- Wraps @ImGui::EndDisabled()@+endDisabled :: (MonadIO m) => m ()+endDisabled = liftIO do+  [C.exp| void { EndDisabled() } |]++ -- | undo a sameLine or force a new line when in an horizontal-layout context. -- -- Wraps @ImGui::NewLine()@@@ -1778,6 +1804,12 @@ wantCaptureKeyboard :: MonadIO m => m Bool wantCaptureKeyboard = liftIO do   (0 /=) <$> [C.exp| bool { GetIO().WantCaptureKeyboard } |]++-- | Estimate of application framerate (rolling average over 60 frames), in+-- frame per second. Solely for convenience.+framerate :: MonadIO m => m Float+framerate = liftIO do+  realToFrac <$> [C.exp| float { GetIO().Framerate } |]  -- | This draw list will be the first rendering one. --
src/DearImGui/Raw/IO.hs view
@@ -120,14 +120,11 @@  {- TODO: -bool   WantCaptureMouse;         // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.).-bool   WantCaptureKeyboard;      // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). bool   WantTextInput;            // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool   WantSetMousePos;          // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. bool   WantSaveIniSettings;      // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! bool   NavActive;                // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool   NavVisible;               // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events).-float  Framerate;                // Rough estimate of application framerate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames. int    MetricsRenderVertices;    // Vertices output during last call to Render() int    MetricsRenderIndices;     // Indices output during last call to Render() = number of triangles * 3 int    MetricsRenderWindows;     // Number of visible windows
src/DearImGui/SDL.hs view
@@ -21,12 +21,14 @@   , sdl2Shutdown   , pollEventWithImGui   , pollEventsWithImGui+    -- *** Raw+  , dispatchRawEvent   )   where  -- base import Control.Monad-  ( when )+  ( void, when ) import Foreign.Marshal.Alloc   ( alloca ) import Foreign.Ptr@@ -42,6 +44,7 @@ import SDL import SDL.Raw.Enum as Raw import qualified SDL.Raw.Event as Raw+import qualified SDL.Raw.Types as Raw  -- transformers import Control.Monad.IO.Class@@ -77,10 +80,23 @@     nEvents <- Raw.peepEvents evPtr 1 Raw.SDL_PEEKEVENT Raw.SDL_FIRSTEVENT Raw.SDL_LASTEVENT      when (nEvents > 0) do-      let evPtr' = castPtr evPtr :: Ptr ()-      [C.exp| void { ImGui_ImplSDL2_ProcessEvent((SDL_Event*) $(void* evPtr')) } |]+      void $ dispatchRawEvent evPtr      pollEvent++-- | Dispatch a raw 'Raw.Event' value to Dear ImGui.+--+-- You may want this function instead of 'pollEventWithImGui' if you do not use+-- @sdl2@'s higher-level 'Event' type (e.g. your application has its own polling+-- mechanism).+--+-- __It is your application's responsibility to both manage the input__+-- __pointer's memory and to fill the memory location with a raw 'Raw.Event'__+-- __value.__+dispatchRawEvent :: MonadIO m => Ptr Raw.Event -> m Bool+dispatchRawEvent evPtr = liftIO do+  let evPtr' = castPtr evPtr :: Ptr ()+  (0 /=) <$> [C.exp| bool { ImGui_ImplSDL2_ProcessEvent((const SDL_Event*) $(void* evPtr')) } |]  -- | Like the SDL2 'pollEvents' function, while also dispatching the events to -- Dear ImGui. See 'pollEventWithImGui'.
+ src/DearImGui/SDL/Renderer.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++{-|+Module: DearImGUI.SDL.Renderer++Initialising the SDL2 renderer backend for Dear ImGui.+-}++module DearImGui.SDL.Renderer+  ( sdl2InitForSDLRenderer+  , sdlRendererInit+  , sdlRendererShutdown+  , sdlRendererNewFrame+  , sdlRendererRenderDrawData+  )+  where++-- inline-c+import qualified Language.C.Inline as C++-- inline-c-cpp+import qualified Language.C.Inline.Cpp as Cpp++-- sdl2+import SDL.Internal.Types+  ( Renderer(..), Window(..) )++-- transformers+import Control.Monad.IO.Class+  ( MonadIO, liftIO )++-- DearImGui+import DearImGui+  ( DrawData(..) )+++C.context (Cpp.cppCtx <> C.bsCtx)+C.include "imgui.h"+C.include "backends/imgui_impl_sdlrenderer2.h"+C.include "backends/imgui_impl_sdl2.h"+C.include "SDL.h"+Cpp.using "namespace ImGui"+++-- | Wraps @ImGui_ImplSDL2_InitForSDLRenderer@.+sdl2InitForSDLRenderer :: MonadIO m => Window -> Renderer -> m Bool+sdl2InitForSDLRenderer (Window windowPtr) (Renderer renderPtr) = liftIO do+  (0 /=) <$> [C.exp| bool { ImGui_ImplSDL2_InitForSDLRenderer((SDL_Window*)$(void* windowPtr), (SDL_Renderer*)$(void* renderPtr)) } |]++-- | Wraps @ImGui_ImplSDLRenderer2_Init@.+sdlRendererInit :: MonadIO m => Renderer -> m Bool+sdlRendererInit (Renderer renderPtr) = liftIO do+  (0 /=) <$> [C.exp| bool { ImGui_ImplSDLRenderer2_Init((SDL_Renderer*)$(void* renderPtr)) } |]++-- | Wraps @ImGui_ImplSDLRenderer2_Shutdown@.+sdlRendererShutdown :: MonadIO m => m ()+sdlRendererShutdown = liftIO do+  [C.exp| void { ImGui_ImplSDLRenderer2_Shutdown(); } |]++-- | Wraps @ImGui_ImplSDLRenderer2_NewFrame@.+sdlRendererNewFrame :: MonadIO m => m ()+sdlRendererNewFrame = liftIO do+  [C.exp| void { ImGui_ImplSDLRenderer2_NewFrame(); } |]++-- | Wraps @ImGui_ImplSDLRenderer2_RenderDrawData@.+sdlRendererRenderDrawData :: MonadIO m => DrawData -> m ()+sdlRendererRenderDrawData (DrawData ptr) = liftIO do+  [C.exp| void { ImGui_ImplSDLRenderer2_RenderDrawData((ImDrawData*) $( void* ptr )) } |]
src/DearImGui/Vulkan.hs view
@@ -31,6 +31,8 @@   ( Word32 ) import Foreign.Marshal.Alloc   ( alloca )+import Foreign.Marshal.Utils+  ( fromBool ) import Foreign.Ptr   ( FunPtr, Ptr, freeHaskellFunPtr, nullPtr ) import Foreign.Storable@@ -70,19 +72,21 @@  data InitInfo =   InitInfo-  { instance'      :: !Vulkan.Instance-  , physicalDevice :: !Vulkan.PhysicalDevice-  , device         :: !Vulkan.Device-  , queueFamily    :: !Word32-  , queue          :: !Vulkan.Queue-  , pipelineCache  :: !Vulkan.PipelineCache-  , descriptorPool :: !Vulkan.DescriptorPool-  , subpass        :: !Word32-  , minImageCount  :: !Word32-  , imageCount     :: !Word32-  , msaaSamples    :: !Vulkan.SampleCountFlagBits-  , mbAllocator    :: Maybe Vulkan.AllocationCallbacks-  , checkResult    :: Vulkan.Result -> IO ()+  { instance'             :: !Vulkan.Instance+  , physicalDevice        :: !Vulkan.PhysicalDevice+  , device                :: !Vulkan.Device+  , queueFamily           :: !Word32+  , queue                 :: !Vulkan.Queue+  , pipelineCache         :: !Vulkan.PipelineCache+  , descriptorPool        :: !Vulkan.DescriptorPool+  , subpass               :: !Word32+  , minImageCount         :: !Word32+  , imageCount            :: !Word32+  , msaaSamples           :: !Vulkan.SampleCountFlagBits+  , colorAttachmentFormat :: !(Maybe Vulkan.Format)+  , useDynamicRendering   :: !Bool+  , mbAllocator           :: Maybe Vulkan.AllocationCallbacks+  , checkResult           :: Vulkan.Result -> IO ()   }  -- | Wraps @ImGui_ImplVulkan_Init@ and @ImGui_ImplVulkan_Shutdown@.@@ -112,6 +116,10 @@     withCallbacks f = case mbAllocator of       Nothing        -> f nullPtr       Just callbacks -> alloca ( \ ptr -> poke ptr callbacks *> f ptr )+    useDynamicRendering' :: Cpp.CBool+    useDynamicRendering' = fromBool useDynamicRendering+    colorAttachmentFormat' :: Vulkan.Format+    colorAttachmentFormat' = fromMaybe Vulkan.FORMAT_UNDEFINED colorAttachmentFormat   liftIO do     checkResultFunPtr <- $( C.mkFunPtr [t| Vulkan.Result -> IO () |] ) checkResult     initResult <- withCallbacks \ callbacksPtr ->@@ -134,8 +142,8 @@           initInfo.MSAASamples = $(VkSampleCountFlagBits msaaSamples);           initInfo.Allocator = $(VkAllocationCallbacks* callbacksPtr);           initInfo.CheckVkResultFn = $( void (*checkResultFunPtr)(VkResult) );-          initInfo.UseDynamicRendering = false;-          // TODO: initInfo.ColorAttachmentFormat+          initInfo.UseDynamicRendering = $(bool useDynamicRendering');+          initInfo.ColorAttachmentFormat = $(VkFormat colorAttachmentFormat');           return ImGui_ImplVulkan_Init(&initInfo, $(VkRenderPass renderPass) );         }|]     pure ( checkResultFunPtr, initResult /= 0 )
src/DearImGui/Vulkan/Types.hs view
@@ -35,6 +35,7 @@   , ( C.TypeName "VkImageView"          , [t| Vulkan.ImageView           |] )   , ( C.TypeName "VkImageLayout"        , [t| Vulkan.ImageLayout         |] )   , ( C.TypeName "VkDescriptorSet"      , [t| Vulkan.DescriptorSet       |] )+  , ( C.TypeName "VkFormat"             , [t| Vulkan.Format              |])   ]  vulkanCtx :: C.Context