2021-01-24 19:50:21 +00:00
|
|
|
# Dear ImGui.hs
|
|
|
|
|
|
|
|
> Dear ImGui is a **bloat-free graphical user interface library for C++**. It
|
|
|
|
> outputs optimized vertex buffers that you can render anytime in your
|
|
|
|
> 3D-pipeline enabled application. It is fast, portable, renderer agnostic and
|
|
|
|
> self-contained (no external dependencies).
|
|
|
|
|
|
|
|
This project contains Haskell bindings to the
|
|
|
|
[ImGui](https://github.com/ocornut/imgui) project. This allows you to rapidly
|
|
|
|
put together graphical user interfaces in Haskell, with a particular focus to
|
|
|
|
games and graphics intensive applications.
|
|
|
|
|
|
|
|
# Getting Started
|
|
|
|
|
2021-01-25 09:18:13 +00:00
|
|
|
To get started, we'll build the following:
|
|
|
|
|
|
|
|
![](./Example.png)
|
|
|
|
|
2021-01-24 19:50:21 +00:00
|
|
|
`dear-imgui.hs` can be used like a normal Haskell library. If you use Cabal,
|
|
|
|
simply add `dear-imgui` to your `build-depends`. ImGui supports a variety of
|
|
|
|
backends, and you will need to choose your backend at configuration time.
|
|
|
|
Backends can be enabled using Cabal flags, and these can be set through the
|
|
|
|
`cabal.project` file. For example, if you want to use a combination of SDL and
|
|
|
|
OpenGL:
|
|
|
|
|
|
|
|
```
|
|
|
|
package dear-imgui
|
2021-06-30 21:47:23 +00:00
|
|
|
flags: +sdl +opengl3
|
2021-01-24 19:50:21 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
With this done, the following module is the "Hello, World!" of ImGui:
|
|
|
|
|
|
|
|
``` haskell
|
|
|
|
{-# language OverloadedStrings #-}
|
|
|
|
|
|
|
|
module Main ( main ) where
|
|
|
|
|
|
|
|
import DearImGui
|
2024-02-04 18:24:06 +00:00
|
|
|
import DearImGui.OpenGL3
|
2021-01-24 19:50:21 +00:00
|
|
|
import DearImGui.SDL
|
|
|
|
import DearImGui.SDL.OpenGL
|
2024-02-04 18:24:06 +00:00
|
|
|
|
2021-01-24 19:50:21 +00:00
|
|
|
import Graphics.GL
|
|
|
|
import SDL
|
|
|
|
|
2024-02-04 18:24:06 +00:00
|
|
|
import Control.Monad.Managed
|
|
|
|
import Control.Monad.IO.Class ()
|
|
|
|
import Control.Monad (when, unless)
|
|
|
|
import Control.Exception (bracket, bracket_)
|
|
|
|
|
2021-01-24 19:50:21 +00:00
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
-- Initialize SDL
|
|
|
|
initializeAll
|
|
|
|
|
2024-02-04 18:24:06 +00:00
|
|
|
runManaged $ do
|
|
|
|
-- Create a window using SDL; as we're using OpenGL, we enable OpenGL too
|
2021-09-14 12:41:38 +00:00
|
|
|
window <- do
|
2021-01-24 19:50:21 +00:00
|
|
|
let title = "Hello, Dear ImGui!"
|
|
|
|
let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL }
|
|
|
|
managed $ bracket (createWindow title config) destroyWindow
|
|
|
|
|
|
|
|
-- Create an OpenGL context
|
2021-09-14 12:41:38 +00:00
|
|
|
glContext <- managed $ bracket (glCreateContext window) glDeleteContext
|
2021-01-24 19:50:21 +00:00
|
|
|
-- Create an ImGui context
|
|
|
|
_ <- managed $ bracket createContext destroyContext
|
|
|
|
|
|
|
|
-- Initialize ImGui's SDL2 backend
|
2024-02-04 18:24:06 +00:00
|
|
|
managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown
|
2021-01-24 19:50:21 +00:00
|
|
|
-- Initialize ImGui's OpenGL backend
|
2024-02-04 18:24:06 +00:00
|
|
|
managed_ $ bracket_ openGL3Init openGL3Shutdown
|
2021-01-24 19:50:21 +00:00
|
|
|
|
2021-09-14 12:41:38 +00:00
|
|
|
liftIO $ mainLoop window
|
2021-01-24 19:50:21 +00:00
|
|
|
|
|
|
|
mainLoop :: Window -> IO ()
|
2024-02-04 18:24:06 +00:00
|
|
|
mainLoop window = unlessQuit $ do
|
2021-01-24 19:50:21 +00:00
|
|
|
-- Tell ImGui we're starting a new frame
|
2024-02-04 18:24:06 +00:00
|
|
|
openGL3NewFrame
|
2021-08-30 16:57:00 +00:00
|
|
|
sdl2NewFrame
|
2021-01-24 19:50:21 +00:00
|
|
|
newFrame
|
|
|
|
|
|
|
|
-- Build the GUI
|
2024-02-04 18:24:06 +00:00
|
|
|
withWindowOpen "Hello, ImGui!" $ do
|
2021-01-24 19:50:21 +00:00
|
|
|
-- Add a text widget
|
|
|
|
text "Hello, ImGui!"
|
|
|
|
|
|
|
|
-- Add a button widget, and call 'putStrLn' when it's clicked
|
2024-02-04 18:24:06 +00:00
|
|
|
button "Clickety Click" >>= \clicked ->
|
|
|
|
when clicked $ putStrLn "Ow!"
|
2021-01-24 19:50:21 +00:00
|
|
|
|
2021-01-25 09:18:13 +00:00
|
|
|
-- Show the ImGui demo window
|
|
|
|
showDemoWindow
|
|
|
|
|
2021-01-24 19:50:21 +00:00
|
|
|
-- Render
|
|
|
|
glClear GL_COLOR_BUFFER_BIT
|
|
|
|
render
|
2024-02-04 18:24:06 +00:00
|
|
|
openGL3RenderDrawData =<< getDrawData
|
2021-01-24 19:50:21 +00:00
|
|
|
|
2021-09-14 12:41:38 +00:00
|
|
|
glSwapWindow window
|
|
|
|
mainLoop window
|
2021-01-24 19:50:21 +00:00
|
|
|
where
|
2024-02-04 18:24:06 +00:00
|
|
|
-- Process the event loop
|
|
|
|
unlessQuit action = do
|
|
|
|
shouldQuit <- gotQuitEvent
|
|
|
|
unless shouldQuit action
|
|
|
|
|
|
|
|
gotQuitEvent = do
|
|
|
|
ev <- pollEventWithImGui
|
|
|
|
|
|
|
|
case ev of
|
|
|
|
Nothing ->
|
|
|
|
return False
|
|
|
|
Just event ->
|
|
|
|
(isQuit event ||) <$> gotQuitEvent
|
|
|
|
|
|
|
|
isQuit event =
|
|
|
|
eventPayload event == QuitEvent
|
2021-01-24 19:50:21 +00:00
|
|
|
```
|
2021-01-25 17:53:59 +00:00
|
|
|
|
|
|
|
# Hacking
|
|
|
|
|
|
|
|
If you would like to help `dear-imgui`, here's how you can get started.
|
|
|
|
|
|
|
|
The best path to development is using
|
|
|
|
[Nix](https://nixos.org/guides/install-nix.html). Once you have Nix installed
|
|
|
|
(either in your operating system, or by running NixOS), you can enter a
|
|
|
|
development shell:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ nix-shell
|
|
|
|
```
|
|
|
|
|
|
|
|
You should now be in a `bash` shell where you can run `cabal build all`,
|
|
|
|
`cabal run readme`, etc.
|
|
|
|
|
|
|
|
If you experience any difficulties, please don't hesistate to raise an issue.
|
|
|
|
|
|
|
|
# Getting Help
|
|
|
|
|
|
|
|
Feel free to raise bugs, questions and feature requests on the GitHub issue
|
|
|
|
tracker.
|
|
|
|
|
|
|
|
We have a Matrix room at
|
|
|
|
[`#dear-imgui.hs:ocharles.org.uk`](https://matrix.to/#/#dear-imgui.hs:ocharles.org.uk).
|