Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
ImGui-SFML v.2.0
* Better CMake support
* Compiler warning fixes
* Can now compile as shared library
  • Loading branch information
eliasdaler committed May 10, 2019
2 parents e5bc24e + 399b698 commit 72df1fd
Show file tree
Hide file tree
Showing 9 changed files with 680 additions and 405 deletions.
200 changes: 134 additions & 66 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,84 +1,152 @@
# Only tested in 3.1, may work in older versions.
# .
# Install SFML or set SFML_ROOT and set IMGUI_ROOT prior to running cmake
# .
# Provides the follow variables:
# IMGUI_SFML_INCLUDE_DIRS - imgui and imgui_sfml include paths
# IMGUI_SOURCES - imgui.cpp source path to link with your binary
# IMGUI_SFML_SOURCES - imgui_sfml.cpp source path to link with your binary
# IMGUI_SFML_DEPENDENCIES - found dependencies to link with your library (sfml)
# .
# Sample usage:
# add_subdirectory(repos/imgui-sfml)
# include_directories("${IMGUI_SFML_INCLUDE_DIRS}")
# add_executable(MY_PROJECT ${IMGUI_SOURCES} ${IMGUI_SFML_SOURCES} ${SRCS})
# ...
# target_link_libraries(MY_PROJECT ${IMGUI_SFML_DEPENDENCIES})
# .
cmake_minimum_required(VERSION 3.1)

project(imgui_sfml)
project(imgui_sfml
LANGUAGES CXX
VERSION 2.0
)

option(IMGUI_SFML_BUILD_EXAMPLES "Build ImGui_SFML examples" ON)
option(IMGUI_SFML_BUILD_EXAMPLES "Build ImGui_SFML examples" OFF)
option(IMGUI_SFML_FIND_SFML "Use find_package to find SFML" ON)

# Find required libraries
find_package(SFML 2.2 COMPONENTS graphics window system)
message(status "** SFML Include: ${SFML_INCLUDE_DIR}")
message(status "** SFML Libraries: ${SFML_LIBRARIES}")
if(NOT SFML_FOUND)
set(SFML_ROOT "" CACHE PATH "SFML top-level directory")
message("---> SFML 2 directory not found. Set SFML_ROOT to SFML's top-level path (containing \"include\" and \"lib\" directories).\n")
# If you want to use your own user config when compiling ImGui, please set the following variables
# For example, if you have your config in /path/to/dir/with/config/myconfig.h, set the variables as follows:
#
# IMGUI_SFML_USE_DEFAULT_CONFIG = OFF
# IMGUI_SFML_USER_CONFIG_DIR = /path/to/dir/with/config
# IMGUI_SFML_USER_CONFIG_NAME = "myconfig.h"
#
# If you set IMGUI_SFML_CONFIG_INSTALL_DIR, ImGui-SFML won't install your custom config, because
# you might want to do it yourself
option(IMGUI_SFML_USE_DEFAULT_CONFIG "Use default imconfig-SFML.h" ON)
set(IMGUI_SFML_CONFIG_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "Path to a directory containing user ImGui config")
set(IMGUI_SFML_CONFIG_NAME "imconfig-SFML.h" CACHE STRING "Name of a custom user ImGui config header")
set(IMGUI_SFML_CONFIG_INSTALL_DIR "" CACHE PATH "Path where user's config header will be installed")

# For FindImGui.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

if (IMGUI_SFML_FIND_SFML)
find_package(SFML 2.5 COMPONENTS graphics system window)

if(NOT SFML_FOUND)
message(FATAL_ERROR "SFML 2 directory not found. Set SFML_DIR to directory where SFML was built (or one which ccontains SFMLConfig.cmake)")
endif()
endif()

# ImGui does not provide native support for CMakeLists, workaround for now to have
# users specify IMGUI_ROOT. See:
# https://github.com/ocornut/imgui/pull/255
if(NOT IMGUI_ROOT)
set(IMGUI_ROOT "" CACHE PATH "imgui top-level directory")
message("---> ImGui directory not found. Set IMGUI_ROOT to imgui's top-level path (containing \"imgui.cpp\" and \"imgui.h\" files).\n")
# users specify IMGUI_DIR. Waiting for this PR to get merged...
# https://github.com/ocornut/imgui/pull/1713
if(NOT IMGUI_DIR)
set(IMGUI_DIR "" CACHE PATH "imgui top-level directory")
message(FATAL_ERROR "ImGui directory not found. Set IMGUI_ROOT to imgui's top-level path (containing 'imgui.h' and other files).\n")
endif()

# Do a pseudo find files for ImGui once IMGUI_ROOT is set
if(IMGUI_ROOT)
set(IMGUI_SERACH_PATH
${IMGUI_ROOT}
$ENV{IMGUI_ROOT}
)
find_path(IMGUI_INCLUDE_DIR imgui.cpp
PATHS ${IMGUI_SERACH_PATH})
if(NOT IMGUI_INCLUDE_DIR)
message(FATAL_ERROR "---> IMGUI imgui.cpp not found. Set IMGUI_ROOT to imgui's top-level path (containing \"imgui.cpp\" and \"imgui.h\" files).\n")
else()
file(GLOB IMGUI_FILES
"${IMGUI_INCLUDE_DIR}/imgui_draw.cpp"
"${IMGUI_INCLUDE_DIR}/imgui_demo.cpp"
"${IMGUI_INCLUDE_DIR}/imgui.cpp" )
message("Found imgui.cpp in ${IMGUI_INCLUDE_DIR}")
# Rename that pesky imconfig.h file for the user.
install(FILES ${IMGUI_INCLUDE_DIR}/imconfig.h DESTINATION include RENAME imconfig-sample.h)
endif()
# This uses FindImGui.cmake provided in ImGui-SFML repo for now
find_package(ImGui 1.68 REQUIRED)

# these headers will be installed alongside ImGui-SFML
set(IMGUI_PUBLIC_HEADERS
${IMGUI_INCLUDE_DIR}/imconfig.h
${IMGUI_INCLUDE_DIR}/imgui.h
${IMGUI_INCLUDE_DIR}/imgui_internal.h # not actually public, but users might need it
${IMGUI_INCLUDE_DIR}/imstb_rectpack.h
${IMGUI_INCLUDE_DIR}/imstb_textedit.h
${IMGUI_INCLUDE_DIR}/imstb_truetype.h
${IMGUI_INCLUDE_DIR}/misc/cpp/imgui_stdlib.h
)

# CMake 3.11 and later prefer to choose GLVND, but we choose legacy OpenGL just because it's safer
# (unless the OpenGL_GL_PREFERENCE was explicitly set)
# See CMP0072 for more details (cmake --help-policy CMP0072)
if ((NOT ${CMAKE_VERSION} VERSION_LESS 3.11) AND (NOT OpenGL_GL_PREFERENCE))
set(OpenGL_GL_PREFERENCE "LEGACY")
endif()

# Glob up both source and headers as sources for VS users.
file(GLOB IMGUI_SFML_FILES "${PROJECT_SOURCE_DIR}/*.cpp" "${PROJECT_SOURCE_DIR}/*.h")
find_package(OpenGL REQUIRED)

# Set these for users to use
set(IMGUI_SFML_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}
${IMGUI_INCLUDE_DIR}
${SFML_INCLUDE_DIR} CACHE INTERNAL "")
add_library(ImGui-SFML
imgui-SFML.cpp
${IMGUI_SOURCES}
)

set(IMGUI_SOURCES
${IMGUI_FILES} CACHE INTERNAL "")
# Add pretty alias
add_library(ImGui-SFML::ImGui-SFML ALIAS ImGui-SFML)

set(IMGUI_SFML_SOURCES
${IMGUI_SFML_FILES} CACHE INTERNAL "")
target_link_libraries(ImGui-SFML
PUBLIC
sfml-graphics
sfml-system
sfml-window
${OPENGL_LIBRARIES}
)

set(IMGUI_SFML_DEPENDENCIES
${SFML_DEPENDENCIES}
${SFML_LIBRARIES} CACHE INTERNAL "")
include(GNUInstallDirs)

target_include_directories(ImGui-SFML
PUBLIC
$<BUILD_INTERFACE:${IMGUI_INCLUDE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

if(NOT IMGUI_SFML_USE_DEFAULT_CONFIG)
if (IMGUI_SFML_CONFIG_DIR)
target_include_directories(ImGui-SFML
PUBLIC
$<BUILD_INTERFACE:${IMGUI_SFML_CONFIG_DIR}>
$<INSTALL_INTERFACE:${IMGUI_SFML_INSTALL_CONFIG_DIR}>
)
else()
message(FATAL_ERROR "IMGUI_SFML_CONFIG_DIR should be set if IMGUI_SFML_USE_DEFAULT_CONFIG is OFF")
endif()
endif()

target_compile_definitions(ImGui-SFML
PUBLIC
IMGUI_USER_CONFIG="${IMGUI_SFML_CONFIG_NAME}"
)

if(BUILD_SHARED_LIBS)
target_compile_definitions(ImGui-SFML PRIVATE IMGUI_SFML_SHARED_LIB)
set_target_properties(ImGui-SFML PROPERTIES
DEFINE_SYMBOL "IMGUI_SFML_EXPORTS"
)
endif()

set(IMGUI_SFML_PUBLIC_HEADERS
"${CMAKE_CURRENT_LIST_DIR}/imgui-SFML.h"
"${CMAKE_CURRENT_LIST_DIR}/imgui-SFML_export.h"
)

if (IMGUI_SFML_USE_DEFAULT_CONFIG OR
(NOT DEFINED "${IMGUI_SFML_CONFIG_INSTALL_DIR}"))
list(APPEND IMGUI_SFML_PUBLIC_HEADERS
"${IMGUI_SFML_CONFIG_DIR}/${IMGUI_SFML_CONFIG_NAME}"
)
# If user set IMGUI_SFML_INSTALL_CONFIG_DIR, it means that they'll install file themselves
endif()

list(APPEND IMGUI_SFML_PUBLIC_HEADERS "${IMGUI_PUBLIC_HEADERS}")

set_target_properties(ImGui-SFML PROPERTIES
PUBLIC_HEADER "${IMGUI_SFML_PUBLIC_HEADERS}"
)

if(IMGUI_SFML_BUILD_EXAMPLES)
# Build examples
add_subdirectory(examples)
endif(IMGUI_SFML_BUILD_EXAMPLES)
endif()

# installation rules
install(TARGETS ImGui-SFML
EXPORT ImGui-SFML
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(EXPORT ImGui-SFML
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ImGui-SFML
NAMESPACE ImGui-SFML::
FILE ImGui-SFMLConfig.cmake
)
86 changes: 60 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
ImGui + SFML
ImGui + SFML v2.0
=======

Library which allows you to use [ImGui](https://github.com/ocornut/imgui) with [SFML](https://github.com/SFML/SFML)

> Use [ImGui-SFML's v1.0](https://github.com/eliasdaler/imgui-sfml/releases/tag/v.1.0) if you're using ImGui's stable release (v.1.53)! This repo's master will be kept up to date with breaking changes in ImGui's master.
![screenshot](https://i2.wp.com/i.imgur.com/iQibpSk.gif)

Based on [this repository](https://github.com/Mischa-Alff/imgui-backends) with big improvements and changes.

Dependencies
-----

* [SFML](https://github.com/SFML/SFML) >= 2.5.0
* [ImGui](https://github.com/ocornut/imgui) >= 1.68

How-to
----

- [**Detailed tutorial on my blog**](https://eliasdaler.github.io/using-imgui-with-sfml-pt1)
- [**Using ImGui with modern C++ and STL**](https://eliasdaler.github.io/using-imgui-with-sfml-pt2/)
- [**Thread on SFML forums**](https://en.sfml-dev.org/forums/index.php?topic=20137.0). Feel free to ask your questions there.

Setting up:
Building and integrating into your CMake project
---

```sh
cmake <ImGui-SFML repo folder> -DIMGUI_DIR=<ImGui repo folder> -DSFML_DIR=<path with built SFML>
```

If you have SFML installed on your system, you don't need to set SFML_DIR during
configuration.

You can also specify `BUILD_SHARED_LIBS=ON` to build ImGui-SFML as a shared library. To build ImGui-SFML examples, set `IMGUI_SFML_BUILD_EXAMPLES=ON`.

After the building, you can install the library on your system by running:
```sh
cmake --build . --target install
```

If you set `CMAKE_INSTALL_PREFIX` during configuration, you can install ImGui-SFML locally.

Integrating into your project is simple.
```cmake
find_package(ImGui-SFML REQUIRED)
target_link_libraries(my_target PRIVATE ImGui-SFML::ImGui-SFML)
```

If CMake can't find ImGui-SFML on your system, just define `ImGui-SFML_DIR` before calling `find_package`.

Integrating into your project manually
---
- Download [ImGui](https://github.com/ocornut/imgui)
- Add ImGui folder to your include directories
- Add `imgui.cpp` and `imgui_draw.cpp` to your build/project
Expand All @@ -26,13 +57,14 @@ Setting up:
- Add `imgui-SFML.cpp` to your build/project
- Link OpenGL if you get linking errors

In your code:
Using ImGui-SFML in your code
---

- Call `ImGui::SFML::Init` and pass your `sf::Window` + `sf::RenderTarget` or `sf::RenderWindow` there. You can create your font atlas and pass the pointer in Init too, otherwise the default internal font atlas will be created for you.
- For each iteration of a game loop:
- Poll and process events:

```c++
```cpp
sf::Event event;
while (window.pollEvent(event)) {
ImGui::SFML::ProcessEvent(event);
Expand All @@ -54,7 +86,7 @@ Example code

See example file [here](examples/main.cpp)

```c++
```cpp
#include "imgui.h"
#include "imgui-SFML.h"

Expand Down Expand Up @@ -106,7 +138,7 @@ Default font is loaded if you don't pass `false` in `ImGui::SFML::Init`. Call `I

* Load your fonts like this:

```c++
```cpp
IO.Fonts->Clear(); // clear fonts if you loaded some before (even if only default one was loaded)
// IO.Fonts->AddFontDefault(); // this will load default font as well
IO.Fonts->AddFontFromFileTTF("font1.ttf", 8.f);
Expand All @@ -117,7 +149,7 @@ ImGui::SFML::UpdateFontTexture(); // important call: updates font texture
* And use them like this:
```c++
```cpp
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);
ImGui::Button("Look at this pretty button");
ImGui::PopFont();
Expand All @@ -129,47 +161,49 @@ ImGui::PopFont();

The first loaded font is treated as the default one and doesn't need to be pushed with `ImGui::PushFont`.

CMake how-to
---
- Checkout the repository as a submoudle
- Set IMGUI_ROOT
- Modify your builds to copy imgui-SFML and dependencies (sfml) to your project
```CMakeLists
add_subdirectory(repos/imgui-sfml)
include_directories("${IMGUI_SFML_INCLUDE_DIRS}")
add_executable(MY_PROJECT ${IMGUI_SOURCES} ${IMGUI_SFML_SOURCES} ${SRCS})
...
target_link_libraries(MY_PROJECT ${IMGUI_SFML_DEPENDENCIES})
```

SFML related ImGui overloads / new widgets
---

There are some useful overloads implemented for SFML objects (see header for overloads):
```c++
```cpp
ImGui::Image(const sf::Sprite& sprite);
ImGui::Image(const sf::Texture& texture);
ImGui::ImageButton(const sf::Sprite& sprite);
ImGui::ImageButton(const sf::Texture& texture);
```
Mouse cursors
---
You can change your cursors in ImGui like this:
```cpp
ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput);
```

By default, your system cursor will change and will be rendered by your system. If you want SFML to draw your cursor with default ImGui cursors (the system cursor will be hidden), do this:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.MouseDrawCursor = true;
```

Keyboard/Gamepad navigation
---
Starting with [ImGui 1.60](https://github.com/ocornut/imgui/releases/tag/v1.60), there's a feature to control ImGui with keyboard and gamepad. To use keyboard navigation, you just need to do this:

```c++
```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
```

Gamepad navigation requires more work, unless you have XInput gamepad, in which case the mapping is automatically set for you. But you can still set it up for your own gamepad easily, just take a look how it's done for the default mapping [here](https://github.com/eliasdaler/imgui-sfml/blob/navigation/imgui-SFML.cpp#L697). And then you need to do this:

```c++
```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
```
By default, the first active joystick is used for navigation, but you can set joystick id explicitly like this:
```c++
```cpp
ImGui::SFML::SetActiveJoystickId(5);
```
Expand Down
Loading

0 comments on commit 72df1fd

Please sign in to comment.