-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for SDL2 Renderer backend #193
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 )) } |] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ImGui preprocessor error calls for 2.0.17+, but I opted for 2.0.18+ here as that's when the official docs and release notes indicate
SDL_RenderGeometry
was added.My understanding is that SDL uses the odd version numbers for releases that might not be proven to be stable, so it may likely have been added in 2.0.17, but it seems users won't find much in the way of documentation for that version, so 2.0.18+ will hopefully avoid confusion.