├── LICENSE ├── Makefile ├── imgui_impl_raylib.cpp ├── imgui_impl_raylib.h └── imgui_impl_raylib_config.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Oskari Timperi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Example Makefile. Download raylib 2.5.0 binary release and 2 | # imgui release 1.73 to use this. You will also need to have 3 | # glad.h from raylib repository available in glad/glad.h as 4 | # that is included from imgui_impl_opengl3.cpp. 5 | 6 | SOURCES = \ 7 | imgui-1.73/imgui.cpp \ 8 | imgui-1.73/imgui_demo.cpp \ 9 | imgui-1.73/imgui_draw.cpp \ 10 | imgui-1.73/imgui_widgets.cpp \ 11 | imgui-1.73/examples/imgui_impl_opengl3.cpp \ 12 | imgui_impl_raylib.cpp 13 | 14 | OBJECTS = $(SOURCES:.cpp=.o) 15 | 16 | CPPFLAGS += -Iraylib-2.5.0-Linux-amd64/include -Iimgui-1.73 -Iimgui-1.73/examples -I. 17 | 18 | CXXFLAGS += -g -DDEBUG -DIMGUI_IMPL_OPENGL_LOADER_GLAD 19 | 20 | LDLIBS += -lraylib 21 | 22 | LDFLAGS += -Lraylib-2.5.0-Linux-amd64/lib 23 | 24 | example: example.o $(OBJECTS) 25 | $(LINK.cpp) $^ $(LDLIBS) -o $@ 26 | 27 | clean: 28 | rm -f $(OBJECTS) example.o 29 | -------------------------------------------------------------------------------- /imgui_impl_raylib.cpp: -------------------------------------------------------------------------------- 1 | #include "imgui_impl_raylib.h" 2 | #include 3 | #include 4 | #include 5 | 6 | static double g_Time = 0.0; 7 | static bool g_UnloadAtlas = false; 8 | static int g_AtlasTexID = 0; 9 | 10 | static const char* ImGui_ImplRaylib_GetClipboardText(void*) 11 | { 12 | return GetClipboardText(); 13 | } 14 | 15 | static void ImGui_ImplRaylib_SetClipboardText(void*, const char* text) 16 | { 17 | SetClipboardText(text); 18 | } 19 | 20 | bool ImGui_ImplRaylib_Init() 21 | { 22 | ImGuiIO& io = ImGui::GetIO(); 23 | 24 | io.BackendPlatformName = "imgui_impl_raylib"; 25 | 26 | io.KeyMap[ImGuiKey_Tab] = KEY_TAB; 27 | io.KeyMap[ImGuiKey_LeftArrow] = KEY_LEFT; 28 | io.KeyMap[ImGuiKey_RightArrow] = KEY_RIGHT; 29 | io.KeyMap[ImGuiKey_UpArrow] = KEY_UP; 30 | io.KeyMap[ImGuiKey_DownArrow] = KEY_DOWN; 31 | io.KeyMap[ImGuiKey_PageUp] = KEY_PAGE_DOWN; 32 | io.KeyMap[ImGuiKey_PageDown] = KEY_PAGE_UP; 33 | io.KeyMap[ImGuiKey_Home] = KEY_HOME; 34 | io.KeyMap[ImGuiKey_End] = KEY_END; 35 | io.KeyMap[ImGuiKey_Insert] = KEY_INSERT; 36 | io.KeyMap[ImGuiKey_Delete] = KEY_DELETE; 37 | io.KeyMap[ImGuiKey_Backspace] = KEY_BACKSPACE; 38 | io.KeyMap[ImGuiKey_Space] = KEY_SPACE; 39 | io.KeyMap[ImGuiKey_Enter] = KEY_ENTER; 40 | io.KeyMap[ImGuiKey_Escape] = KEY_ESCAPE; 41 | io.KeyMap[ImGuiKey_KeyPadEnter] = KEY_KP_ENTER; 42 | io.KeyMap[ImGuiKey_A] = KEY_A; 43 | io.KeyMap[ImGuiKey_C] = KEY_C; 44 | io.KeyMap[ImGuiKey_V] = KEY_V; 45 | io.KeyMap[ImGuiKey_X] = KEY_X; 46 | io.KeyMap[ImGuiKey_Y] = KEY_Y; 47 | io.KeyMap[ImGuiKey_Z] = KEY_Z; 48 | 49 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 50 | 51 | io.SetClipboardTextFn = ImGui_ImplRaylib_SetClipboardText; 52 | io.GetClipboardTextFn = ImGui_ImplRaylib_GetClipboardText; 53 | io.ClipboardUserData = NULL; 54 | 55 | #ifdef AUTO_FONTATLAS 56 | ImGui_ImplRaylib_LoadDefaultFontAtlas(); 57 | #endif 58 | 59 | return true; 60 | } 61 | 62 | void ImGui_ImplRaylib_Shutdown() 63 | { 64 | if (g_UnloadAtlas) { 65 | ImGuiIO& io = ImGui::GetIO(); 66 | io.Fonts->ClearTexData(); 67 | } 68 | g_Time = 0.0; 69 | } 70 | 71 | static void ImGui_ImplRaylib_UpdateMousePosAndButtons() 72 | { 73 | ImGuiIO& io = ImGui::GetIO(); 74 | 75 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 76 | if (io.WantSetMousePos) 77 | SetMousePosition(io.MousePos.x, io.MousePos.y); 78 | else 79 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 80 | 81 | io.MouseDown[0] = IsMouseButtonDown(MOUSE_LEFT_BUTTON); 82 | io.MouseDown[1] = IsMouseButtonDown(MOUSE_RIGHT_BUTTON); 83 | io.MouseDown[2] = IsMouseButtonDown(MOUSE_MIDDLE_BUTTON); 84 | 85 | if (!IsWindowMinimized()) 86 | io.MousePos = ImVec2(GetMouseX(), GetMouseY()); 87 | } 88 | 89 | static void ImGui_ImplRaylib_UpdateMouseCursor() 90 | { 91 | ImGuiIO& io = ImGui::GetIO(); 92 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 93 | return; 94 | 95 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 96 | if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) 97 | { 98 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 99 | HideCursor(); 100 | } 101 | else 102 | { 103 | // Show OS mouse cursor 104 | ShowCursor(); 105 | } 106 | } 107 | 108 | void ImGui_ImplRaylib_NewFrame() 109 | { 110 | ImGuiIO& io = ImGui::GetIO(); 111 | 112 | io.DisplaySize = ImVec2((float)GetScreenWidth(), (float)GetScreenHeight()); 113 | 114 | double current_time = GetTime(); 115 | io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); 116 | g_Time = current_time; 117 | 118 | io.KeyCtrl = IsKeyDown(KEY_RIGHT_CONTROL) || IsKeyDown(KEY_LEFT_CONTROL); 119 | io.KeyShift = IsKeyDown(KEY_RIGHT_SHIFT) || IsKeyDown(KEY_LEFT_SHIFT); 120 | io.KeyAlt = IsKeyDown(KEY_RIGHT_ALT) || IsKeyDown(KEY_LEFT_ALT); 121 | io.KeySuper = IsKeyDown(KEY_RIGHT_SUPER) || IsKeyDown(KEY_LEFT_SUPER); 122 | 123 | ImGui_ImplRaylib_UpdateMousePosAndButtons(); 124 | ImGui_ImplRaylib_UpdateMouseCursor(); 125 | 126 | if (GetMouseWheelMove() > 0) 127 | io.MouseWheel += 1; 128 | else if (GetMouseWheelMove() < 0) 129 | io.MouseWheel -= 1; 130 | } 131 | 132 | #define FOR_ALL_KEYS(X) \ 133 | X(KEY_APOSTROPHE); \ 134 | X(KEY_COMMA); \ 135 | X(KEY_MINUS); \ 136 | X(KEY_PERIOD); \ 137 | X(KEY_SLASH); \ 138 | X(KEY_ZERO); \ 139 | X(KEY_ONE); \ 140 | X(KEY_TWO); \ 141 | X(KEY_THREE); \ 142 | X(KEY_FOUR); \ 143 | X(KEY_FIVE); \ 144 | X(KEY_SIX); \ 145 | X(KEY_SEVEN); \ 146 | X(KEY_EIGHT); \ 147 | X(KEY_NINE); \ 148 | X(KEY_SEMICOLON); \ 149 | X(KEY_EQUAL); \ 150 | X(KEY_A); \ 151 | X(KEY_B); \ 152 | X(KEY_C); \ 153 | X(KEY_D); \ 154 | X(KEY_E); \ 155 | X(KEY_F); \ 156 | X(KEY_G); \ 157 | X(KEY_H); \ 158 | X(KEY_I); \ 159 | X(KEY_J); \ 160 | X(KEY_K); \ 161 | X(KEY_L); \ 162 | X(KEY_M); \ 163 | X(KEY_N); \ 164 | X(KEY_O); \ 165 | X(KEY_P); \ 166 | X(KEY_Q); \ 167 | X(KEY_R); \ 168 | X(KEY_S); \ 169 | X(KEY_T); \ 170 | X(KEY_U); \ 171 | X(KEY_V); \ 172 | X(KEY_W); \ 173 | X(KEY_X); \ 174 | X(KEY_Y); \ 175 | X(KEY_Z); \ 176 | X(KEY_SPACE); \ 177 | X(KEY_ESCAPE); \ 178 | X(KEY_ENTER); \ 179 | X(KEY_TAB); \ 180 | X(KEY_BACKSPACE); \ 181 | X(KEY_INSERT); \ 182 | X(KEY_DELETE); \ 183 | X(KEY_RIGHT); \ 184 | X(KEY_LEFT); \ 185 | X(KEY_DOWN); \ 186 | X(KEY_UP); \ 187 | X(KEY_PAGE_UP); \ 188 | X(KEY_PAGE_DOWN); \ 189 | X(KEY_HOME); \ 190 | X(KEY_END); \ 191 | X(KEY_CAPS_LOCK); \ 192 | X(KEY_SCROLL_LOCK); \ 193 | X(KEY_NUM_LOCK); \ 194 | X(KEY_PRINT_SCREEN); \ 195 | X(KEY_PAUSE); \ 196 | X(KEY_F1); \ 197 | X(KEY_F2); \ 198 | X(KEY_F3); \ 199 | X(KEY_F4); \ 200 | X(KEY_F5); \ 201 | X(KEY_F6); \ 202 | X(KEY_F7); \ 203 | X(KEY_F8); \ 204 | X(KEY_F9); \ 205 | X(KEY_F10); \ 206 | X(KEY_F11); \ 207 | X(KEY_F12); \ 208 | X(KEY_LEFT_SHIFT); \ 209 | X(KEY_LEFT_CONTROL); \ 210 | X(KEY_LEFT_ALT); \ 211 | X(KEY_LEFT_SUPER); \ 212 | X(KEY_RIGHT_SHIFT); \ 213 | X(KEY_RIGHT_CONTROL); \ 214 | X(KEY_RIGHT_ALT); \ 215 | X(KEY_RIGHT_SUPER); \ 216 | X(KEY_KB_MENU); \ 217 | X(KEY_LEFT_BRACKET); \ 218 | X(KEY_BACKSLASH); \ 219 | X(KEY_RIGHT_BRACKET); \ 220 | X(KEY_GRAVE); \ 221 | X(KEY_KP_0); \ 222 | X(KEY_KP_1); \ 223 | X(KEY_KP_2); \ 224 | X(KEY_KP_3); \ 225 | X(KEY_KP_4); \ 226 | X(KEY_KP_5); \ 227 | X(KEY_KP_6); \ 228 | X(KEY_KP_7); \ 229 | X(KEY_KP_8); \ 230 | X(KEY_KP_9); \ 231 | X(KEY_KP_DECIMAL); \ 232 | X(KEY_KP_DIVIDE); \ 233 | X(KEY_KP_MULTIPLY); \ 234 | X(KEY_KP_SUBTRACT); \ 235 | X(KEY_KP_ADD); \ 236 | X(KEY_KP_ENTER); \ 237 | X(KEY_KP_EQUAL); 238 | 239 | #define SET_KEY_DOWN(KEY) io.KeysDown[KEY] = IsKeyDown(KEY) 240 | 241 | bool ImGui_ImplRaylib_ProcessEvent() 242 | { 243 | ImGuiIO& io = ImGui::GetIO(); 244 | 245 | FOR_ALL_KEYS(SET_KEY_DOWN); 246 | 247 | // Uncomment the three lines below if using raylib earlier than version 3. 248 | //if (GetKeyPressed() != -1) 249 | //{ 250 | #ifdef ENABLE_SCODETOUTF8 251 | int length; // Length was only ever created to be passed to CodepointToUtf8(), since it doesn't check for nullptrs. 252 | io.AddInputCharactersUTF8(CodepointToUtf8(GetCharPressed(), &length)); 253 | (void)length; // Silencing the compiler warnings. 254 | #else 255 | io.AddInputCharacter(GetKeyPressed()); 256 | #endif 257 | //} 258 | 259 | return true; 260 | } 261 | 262 | #ifdef COMPATIBILITY_MODE 263 | void ImGui_ImplRaylib_LoadDefaultFontAtlas() 264 | { 265 | if (!g_UnloadAtlas) { 266 | ImGuiIO& io = ImGui::GetIO(); 267 | unsigned char* pixels = NULL; 268 | int width, height, bpp; 269 | Image image; 270 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bpp); 271 | 272 | unsigned int size = GetPixelDataSize(width, height, 7); 273 | image.data = malloc(size); 274 | memcpy(image.data, pixels, size); 275 | image.width = width; 276 | image.height = height; 277 | image.mipmaps = 1; 278 | image.format = UNCOMPRESSED_R8G8B8A8; 279 | Texture2D tex = LoadTextureFromImage(image); 280 | g_AtlasTexID = tex.id; 281 | io.Fonts->TexID = (void*)&g_AtlasTexID; 282 | free(pixels); 283 | free(image.data); 284 | g_UnloadAtlas = true; 285 | } 286 | }; 287 | 288 | // Code originally provided by WEREMSOFT. 289 | void ImGui_ImplRaylib_Render(ImDrawData* draw_data) 290 | { 291 | 292 | auto DrawTriangleVertex = [](ImDrawVert idx_vert) -> void { 293 | Color* c = (Color*)&idx_vert.col; 294 | rlColor4ub(c->r, c->g, c->b, c->a); 295 | rlTexCoord2f(idx_vert.uv.x, idx_vert.uv.y); 296 | rlVertex2f(idx_vert.pos.x, idx_vert.pos.y); 297 | }; 298 | 299 | rlDisableBackfaceCulling(); 300 | for (int n = 0; n < draw_data->CmdListsCount; n++) 301 | { 302 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 303 | const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui 304 | const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui 305 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 306 | { 307 | const ImDrawCmd* pcmd = &(cmd_list->CmdBuffer.Data)[cmd_i]; // cmd_list->CmdBuffer->data[cmd_i]; 308 | if (pcmd->UserCallback) 309 | { 310 | pcmd->UserCallback(cmd_list, pcmd); 311 | } 312 | else 313 | { 314 | ImVec2 pos = draw_data->DisplayPos; 315 | int rectX = (int)(pcmd->ClipRect.x - pos.x); 316 | int rectY = (int)(pcmd->ClipRect.y - pos.y); 317 | int rectW = (int)(pcmd->ClipRect.z - rectX); 318 | int rectH = (int)(pcmd->ClipRect.w - rectY); 319 | BeginScissorMode(rectX, rectY, rectW, rectH); 320 | { 321 | unsigned int* ti = (unsigned int*)pcmd->TextureId; 322 | for (unsigned int i = 0; i <= (pcmd->ElemCount - 3); i += 3) 323 | { 324 | rlPushMatrix(); 325 | rlBegin(RL_TRIANGLES); 326 | rlEnableTexture(*ti); 327 | 328 | ImDrawIdx index; 329 | ImDrawVert vertex; 330 | 331 | index = idx_buffer[i]; 332 | vertex = vtx_buffer[index]; 333 | DrawTriangleVertex(vertex); 334 | 335 | index = idx_buffer[i + 2]; 336 | vertex = vtx_buffer[index]; 337 | DrawTriangleVertex(vertex); 338 | 339 | index = idx_buffer[i + 1]; 340 | vertex = vtx_buffer[index]; 341 | DrawTriangleVertex(vertex); 342 | rlDisableTexture(); 343 | rlEnd(); 344 | rlPopMatrix(); 345 | } 346 | } 347 | } 348 | idx_buffer += pcmd->ElemCount; 349 | } 350 | } 351 | EndScissorMode(); 352 | rlEnableBackfaceCulling(); 353 | } 354 | #endif -------------------------------------------------------------------------------- /imgui_impl_raylib.h: -------------------------------------------------------------------------------- 1 | #ifndef IMGUI_IMPL_RAYLIB 2 | #define IMGUI_IMPL_RAYLIB 3 | 4 | /* NOTE: I've added a few macros to deal with compatibility. 5 | Most are turned off by default to keep it as close as possible to the original code, 6 | but ImGui has its quirks when it comes to GL2. I'll be integrating part of WEREMSOFT's rendering code. 7 | 8 | (https://github.com/WEREMSOFT/c99-raylib-cimgui-template/). 9 | */ 10 | 11 | // The compiler whines about IMGUI_IMPL_API not being defined, so I'm leaving this here. 12 | #include 13 | 14 | // Config macros 15 | #include "imgui_impl_raylib_config.h" 16 | 17 | #if defined(__cplusplus) 18 | extern "C" { 19 | #endif 20 | 21 | IMGUI_IMPL_API bool ImGui_ImplRaylib_Init(); 22 | IMGUI_IMPL_API void ImGui_ImplRaylib_Shutdown(); 23 | IMGUI_IMPL_API void ImGui_ImplRaylib_NewFrame(); 24 | IMGUI_IMPL_API bool ImGui_ImplRaylib_ProcessEvent(); 25 | 26 | #ifdef COMPATIBILITY_MODE 27 | IMGUI_IMPL_API void ImGui_ImplRaylib_LoadDefaultFontAtlas(); 28 | IMGUI_IMPL_API void ImGui_ImplRaylib_Render(ImDrawData* draw_data); 29 | #endif 30 | 31 | #if defined(__cplusplus) 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /imgui_impl_raylib_config.h: -------------------------------------------------------------------------------- 1 | #ifndef H_IM_RAYLIB_CONFIG 2 | #define H_IM_RAYLIB_CONFIG 3 | 4 | /* This file contains a few macros for you to play with when using the Raylib ImGui implementation. 5 | To use them, just uncomment the macro under its description, and it should be all set! 6 | */ 7 | 8 | // COMPATIBILITY_MODE Toggles the integrated rlgl code. 9 | //#define COMPATIBILITY_MODE 10 | 11 | // AUTO_FONTATLAS REQUIRES COMPATIBILITY - Can be done manually, but is pretty useful... 12 | //#define AUTO_FONTATLAS 13 | 14 | /* ENABLE_SCODETOUTF8 Toggled by default, since the code was passing 15 | raylib's scancodes as codepoints, and ImGui uses UTF-8 16 | on widgets like InputText. 17 | */ 18 | #define ENABLE_SCODETOUTF8 19 | 20 | #endif 21 | --------------------------------------------------------------------------------