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 +9/−0
- README.md +31/−35
- dear-imgui.cabal +38/−13
- examples/Readme.hs +31/−35
- examples/sdl/Renderer.hs +146/−0
- examples/vulkan/Backend.hs +10/−9
- examples/vulkan/Main.hs +12/−6
- imgui/backends/imgui_impl_sdlrenderer2.cpp +262/−0
- src/DearImGui.hs +38/−0
- src/DearImGui/Raw.hs +32/−0
- src/DearImGui/Raw/IO.hs +0/−3
- src/DearImGui/SDL.hs +19/−3
- src/DearImGui/SDL/Renderer.hs +74/−0
- src/DearImGui/Vulkan.hs +23/−15
- src/DearImGui/Vulkan/Types.hs +1/−0
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