From 2acdafe4f2cf844c6e21d77e83b605b7aa1aa75c Mon Sep 17 00:00:00 2001 From: Cedric Guillemet Date: Mon, 25 May 2015 09:40:58 +0200 Subject: [PATCH 1/7] imgui_impl_sdl and main sample --- .../opengl_sdl_example/imgui_impl_sdl.cpp | 286 ++++++++++++++++++ examples/opengl_sdl_example/imgui_impl_sdl.h | 12 + examples/opengl_sdl_example/main.cpp | 109 +++++++ 3 files changed, 407 insertions(+) create mode 100644 examples/opengl_sdl_example/imgui_impl_sdl.cpp create mode 100644 examples/opengl_sdl_example/imgui_impl_sdl.h create mode 100644 examples/opengl_sdl_example/main.cpp diff --git a/examples/opengl_sdl_example/imgui_impl_sdl.cpp b/examples/opengl_sdl_example/imgui_impl_sdl.cpp new file mode 100644 index 000000000..2ac1f5be0 --- /dev/null +++ b/examples/opengl_sdl_example/imgui_impl_sdl.cpp @@ -0,0 +1,286 @@ + +#ifdef _MSC_VER +#include +#include +#include +#endif + +#ifdef MACOSX +#include +#endif + +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +static void ImGui_ImplSdl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +{ + if (cmd_lists_count == 0) + return; + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < cmd_lists_count; n++) + { + const ImDrawList* cmd_list = cmd_lists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + int vtx_offset = 0; + for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; + if (pcmd->user_callback) + { + pcmd->user_callback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); + glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); + glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); + } + vtx_offset += pcmd->vtx_count; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, 0); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +void ImGui_ImplSdl_KeyCallback(int key, bool down) +{ + ImGuiIO& io = ImGui::GetIO(); + if (down) + io.KeysDown[key] = true; + else + io.KeysDown[key] = false; + + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); +} + +void ImGui_ImplSdl_CharCallback(unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Build texture + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Create texture + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + io.Fonts->ClearInputData(); + io.Fonts->ClearTexData(); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window *window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _MSC_VER + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +bool ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + bool done(false); + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_QUIT: + done = true; + break; + case SDL_MOUSEWHEEL: + if (event.wheel.y>0 ) + { + g_MouseWheel = 1; + } + if (event.wheel.y<0 ) + { + g_MouseWheel = -1; + } + break; + case SDL_TEXTINPUT: + ImGui_ImplSdl_CharCallback(event.text.text[0]); + break; + case SDL_KEYUP: + ImGui_ImplSdl_KeyCallback(event.key.keysym.sym&~SDLK_SCANCODE_MASK, false); + break; + case SDL_KEYDOWN: + ImGui_ImplSdl_KeyCallback(event.key.keysym.sym&~SDLK_SCANCODE_MASK, true); + break; + default: + break; + } + } + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + SDL_GetWindowSize(window, &w, &h); + io.DisplaySize = ImVec2((float)w, (float)h); + + // Time + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + Uint32 windowFlags = SDL_GetWindowFlags(window); + if (windowFlags&SDL_WINDOW_MOUSE_FOCUS) + { + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || (mouseMask&(1< +#include "imgui_impl_sdl.h" +#include + +#ifdef WIN32 +#include +#include +#include +#endif + +#ifdef MACOSX +#include + +#endif + +#include + +int SDL_main(int /*argc*/, char* /*argv*/[]) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) + return -1; + + // Init OpenGL + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + + int width(1024), height(576); + + // SDL window + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow( "ImGui OpenGL2/SDL2 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE ); + + // Create an OpenGL context associated with the window. + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + //ImGuiIO& io = ImGui::GetIO(); + //ImFont* my_font0 = io.Fonts->AddFontDefault(); + //ImFont* my_font1 = io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("../../extra_fonts/Karla-Regular.ttf", 16.0f); + //ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1; + //ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1; + //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + bool done(false); + // Main loop + while(!done) + { + done = ImGui_ImplSdl_NewFrame(window); + + // 1. Show a simple window + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + ImGui::Text("Hello"); + ImGui::End(); + } + + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + + SDL_Quit(); + + return 0; +} From b3ae2976c55f4aac310c69f16e4934b84eb1970d Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 09:46:55 -0600 Subject: [PATCH 2/7] SDL example: tweaks and fixes. --- .../opengl_sdl_example/imgui_impl_sdl.cpp | 37 +++++++------------ examples/opengl_sdl_example/imgui_impl_sdl.h | 1 - examples/opengl_sdl_example/main.cpp | 13 +++---- 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/examples/opengl_sdl_example/imgui_impl_sdl.cpp b/examples/opengl_sdl_example/imgui_impl_sdl.cpp index 2ac1f5be0..b1e129ece 100644 --- a/examples/opengl_sdl_example/imgui_impl_sdl.cpp +++ b/examples/opengl_sdl_example/imgui_impl_sdl.cpp @@ -1,4 +1,3 @@ - #ifdef _MSC_VER #include #include @@ -25,9 +24,6 @@ static GLuint g_FontTexture = 0; // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) static void ImGui_ImplSdl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { - if (cmd_lists_count == 0) - return; - // We are using the OpenGL fixed pipeline to make the example code simpler to read! // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. @@ -208,7 +204,7 @@ bool ImGui_ImplSdl_NewFrame(SDL_Window *window) ImGuiIO& io = ImGui::GetIO(); - bool done(false); + bool done = false; SDL_Event event; while (SDL_PollEvent(&event)) { @@ -218,14 +214,15 @@ bool ImGui_ImplSdl_NewFrame(SDL_Window *window) done = true; break; case SDL_MOUSEWHEEL: - if (event.wheel.y>0 ) - { + if (event.wheel.y > 0) g_MouseWheel = 1; - } - if (event.wheel.y<0 ) - { + if (event.wheel.y < 0) g_MouseWheel = -1; - } + break; + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; break; case SDL_TEXTINPUT: ImGui_ImplSdl_CharCallback(event.text.text[0]); @@ -258,27 +255,21 @@ bool ImGui_ImplSdl_NewFrame(SDL_Window *window) // Setup inputs // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - Uint32 windowFlags = SDL_GetWindowFlags(window); - if (windowFlags&SDL_WINDOW_MOUSE_FOCUS) - { + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - } else - { io.MousePos = ImVec2(-1,-1); - } - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || (mouseMask&(1< #include "imgui_impl_sdl.h" @@ -12,10 +12,10 @@ #ifdef MACOSX #include - #endif #include +#include int SDL_main(int /*argc*/, char* /*argv*/[]) { @@ -27,16 +27,13 @@ int SDL_main(int /*argc*/, char* /*argv*/[]) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - int width(1024), height(576); - // SDL window SDL_DisplayMode current; SDL_GetCurrentDisplayMode(0, ¤t); - SDL_Window *window = SDL_CreateWindow( "ImGui OpenGL2/SDL2 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE ); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); // Create an OpenGL context associated with the window. SDL_GLContext glcontext = SDL_GL_CreateContext(window); @@ -55,9 +52,9 @@ int SDL_main(int /*argc*/, char* /*argv*/[]) bool show_another_window = false; ImVec4 clear_color = ImColor(114, 144, 154); - bool done(false); // Main loop - while(!done) + bool done = false; + while (!done) { done = ImGui_ImplSdl_NewFrame(window); From 44c23e0eed69a2587d16e3342bb0d58eaa105bfd Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 09:48:10 -0600 Subject: [PATCH 3/7] Allowing DeltaTime==0.0f to not assert --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 507e8d832..9e93dfdfe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2080,10 +2080,10 @@ void ImGui::NewFrame() ImGuiState& g = *GImGui; // Check user data - IM_ASSERT(g.IO.DeltaTime > 0.0f); + IM_ASSERT(g.IO.DeltaTime >= 0.0f); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f); IM_ASSERT(g.IO.RenderDrawListsFn != NULL); // Must be implemented - IM_ASSERT(g.IO.Fonts->Fonts.Size > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(g.IO.Fonts->Fonts.Size > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? if (!g.Initialized) From b7a2a6b23fc215aa7c82baa4a334f5cd59c5fb82 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 09:49:32 -0600 Subject: [PATCH 4/7] SDL example: renamed folder, added in README --- examples/README.txt | 3 +++ .../imgui_impl_sdl.cpp | 0 .../imgui_impl_sdl.h | 0 examples/{opengl_sdl_example => sdl_opengl_example}/main.cpp | 0 4 files changed, 3 insertions(+) rename examples/{opengl_sdl_example => sdl_opengl_example}/imgui_impl_sdl.cpp (100%) rename examples/{opengl_sdl_example => sdl_opengl_example}/imgui_impl_sdl.h (100%) rename examples/{opengl_sdl_example => sdl_opengl_example}/main.cpp (100%) diff --git a/examples/README.txt b/examples/README.txt index 0a5ad0e05..f958d526f 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -25,3 +25,6 @@ directx11_example/ ios_example/ iOS example. Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. + +sdl_opengl_example/ + SDL2 + OpenGL example. diff --git a/examples/opengl_sdl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp similarity index 100% rename from examples/opengl_sdl_example/imgui_impl_sdl.cpp rename to examples/sdl_opengl_example/imgui_impl_sdl.cpp diff --git a/examples/opengl_sdl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h similarity index 100% rename from examples/opengl_sdl_example/imgui_impl_sdl.h rename to examples/sdl_opengl_example/imgui_impl_sdl.h diff --git a/examples/opengl_sdl_example/main.cpp b/examples/sdl_opengl_example/main.cpp similarity index 100% rename from examples/opengl_sdl_example/main.cpp rename to examples/sdl_opengl_example/main.cpp From 416752800182d60c9ad0b82e8d843e77ebf6c73b Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 10:10:54 -0600 Subject: [PATCH 5/7] SDL example: moved event loop to main.cpp , adding page up/page down. (#226) --- .../sdl_opengl_example/imgui_impl_sdl.cpp | 93 ++++++++----------- examples/sdl_opengl_example/imgui_impl_sdl.h | 8 +- examples/sdl_opengl_example/main.cpp | 9 +- 3 files changed, 53 insertions(+), 57 deletions(-) diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp index b1e129ece..8c9b2f16d 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp @@ -101,24 +101,46 @@ static void ImGui_ImplSdl_SetClipboardText(const char* text) SDL_SetClipboardText(text); } -void ImGui_ImplSdl_KeyCallback(int key, bool down) +bool ImGui_ImplSdl_EventCallback(const SDL_Event& event) { ImGuiIO& io = ImGui::GetIO(); - if (down) - io.KeysDown[key] = true; - else - io.KeysDown[key] = false; - - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); -} - -void ImGui_ImplSdl_CharCallback(unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); + switch (event.type) + { + case SDL_MOUSEWHEEL: + { + if (event.wheel.y > 0) + g_MouseWheel = 1; + if (event.wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + ImGuiIO& io = ImGui::GetIO(); + unsigned int c = event.text.text[0]; + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event.key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event.type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + return true; + } + } + return false; } bool ImGui_ImplSdl_CreateDeviceObjects() @@ -164,6 +186,8 @@ bool ImGui_ImplSdl_Init(SDL_Window *window) io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; @@ -197,47 +221,13 @@ void ImGui_ImplSdl_Shutdown() ImGui::Shutdown(); } -bool ImGui_ImplSdl_NewFrame(SDL_Window *window) +void ImGui_ImplSdl_NewFrame(SDL_Window *window) { if (!g_FontTexture) ImGui_ImplSdl_CreateDeviceObjects(); ImGuiIO& io = ImGui::GetIO(); - bool done = false; - SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_QUIT: - done = true; - break; - case SDL_MOUSEWHEEL: - if (event.wheel.y > 0) - g_MouseWheel = 1; - if (event.wheel.y < 0) - g_MouseWheel = -1; - break; - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event.button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event.button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - break; - case SDL_TEXTINPUT: - ImGui_ImplSdl_CharCallback(event.text.text[0]); - break; - case SDL_KEYUP: - ImGui_ImplSdl_KeyCallback(event.key.keysym.sym&~SDLK_SCANCODE_MASK, false); - break; - case SDL_KEYDOWN: - ImGui_ImplSdl_KeyCallback(event.key.keysym.sym&~SDLK_SCANCODE_MASK, true); - break; - default: - break; - } - } - // Setup display size (every frame to accommodate for window resizing) int w, h; SDL_GetWindowSize(window, &w, &h); @@ -273,5 +263,4 @@ bool ImGui_ImplSdl_NewFrame(SDL_Window *window) // Start the frame ImGui::NewFrame(); - return done; } diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h index d8f3c2ecf..08d6df695 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl_example/imgui_impl_sdl.h @@ -1,11 +1,11 @@ -struct SDL_Window; +struct SDL_Window; +typedef union SDL_Event SDL_Event; bool ImGui_ImplSdl_Init(SDL_Window *window); void ImGui_ImplSdl_Shutdown(); -bool ImGui_ImplSdl_NewFrame(SDL_Window *window); +void ImGui_ImplSdl_NewFrame(SDL_Window *window); +bool ImGui_ImplSdl_EventCallback(const SDL_Event& event); void ImGui_ImplSdl_InvalidateDeviceObjects(); bool ImGui_ImplSdl_CreateDeviceObjects(); -void ImGui_ImplSdl_KeyCallback(int key, int, bool down); -void ImGui_ImplSdl_CharCallback(unsigned int c); diff --git a/examples/sdl_opengl_example/main.cpp b/examples/sdl_opengl_example/main.cpp index c6aa24e9e..333612127 100644 --- a/examples/sdl_opengl_example/main.cpp +++ b/examples/sdl_opengl_example/main.cpp @@ -56,7 +56,14 @@ int SDL_main(int /*argc*/, char* /*argv*/[]) bool done = false; while (!done) { - done = ImGui_ImplSdl_NewFrame(window); + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_EventCallback(event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(window); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" From 22e099366f0e4c0ec4351ceac3abbceb9252f806 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 10:20:08 -0600 Subject: [PATCH 6/7] SDL example: further cleanup to match other examples (#233 #226) --- .../sdl_opengl_example/imgui_impl_sdl.cpp | 11 +-------- examples/sdl_opengl_example/imgui_impl_sdl.h | 1 - examples/sdl_opengl_example/main.cpp | 23 +++---------------- 3 files changed, 4 insertions(+), 31 deletions(-) diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp index 8c9b2f16d..b22250b8e 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp @@ -1,15 +1,6 @@ -#ifdef _MSC_VER -#include -#include -#include -#endif - -#ifdef MACOSX -#include -#endif - #include #include +#include #include #include "imgui_impl_sdl.h" diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h index 08d6df695..6d56b2e0e 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl_example/imgui_impl_sdl.h @@ -8,4 +8,3 @@ bool ImGui_ImplSdl_EventCallback(const SDL_Event& event); void ImGui_ImplSdl_InvalidateDeviceObjects(); bool ImGui_ImplSdl_CreateDeviceObjects(); - diff --git a/examples/sdl_opengl_example/main.cpp b/examples/sdl_opengl_example/main.cpp index 333612127..87e5c794f 100644 --- a/examples/sdl_opengl_example/main.cpp +++ b/examples/sdl_opengl_example/main.cpp @@ -1,41 +1,26 @@ -// ImGui - standalone example application for SDL2 +// ImGui - standalone example application for SDL2 + OpenGL #include #include "imgui_impl_sdl.h" #include - -#ifdef WIN32 -#include -#include -#include -#endif - -#ifdef MACOSX -#include -#endif - #include #include -int SDL_main(int /*argc*/, char* /*argv*/[]) +int SDL_main(int, char**) { // Setup SDL if (SDL_Init(SDL_INIT_EVERYTHING) != 0) return -1; - // Init OpenGL + // Setup window SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - - // SDL window SDL_DisplayMode current; SDL_GetCurrentDisplayMode(0, ¤t); SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); - - // Create an OpenGL context associated with the window. SDL_GLContext glcontext = SDL_GL_CreateContext(window); // Setup ImGui binding @@ -103,10 +88,8 @@ int SDL_main(int /*argc*/, char* /*argv*/[]) // Cleanup ImGui_ImplSdl_Shutdown(); - SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(window); - SDL_Quit(); return 0; From a14f6696a3e52d81127175fcc32c7c1df3fc92dd Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Jul 2015 10:27:25 -0600 Subject: [PATCH 7/7] SDL example: more cleanup to match other examples (#233 #226) --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 3 --- examples/opengl_example/imgui_impl_glfw.cpp | 3 --- .../sdl_opengl_example/imgui_impl_sdl.cpp | 20 ++++++++++--------- examples/sdl_opengl_example/imgui_impl_sdl.h | 4 ++++ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 2328a08a2..fb3286de8 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -31,9 +31,6 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0; // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { - if (cmd_lists_count == 0) - return; - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled GLint last_program, last_texture; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index 4756947a4..d289a7ada 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -25,9 +25,6 @@ static GLuint g_FontTexture = 0; // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) static void ImGui_ImplGlfw_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) { - if (cmd_lists_count == 0) - return; - // We are using the OpenGL fixed pipeline to make the example code simpler to read! // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp index b22250b8e..139a5db79 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl_example/imgui_impl_sdl.cpp @@ -1,3 +1,6 @@ +// ImGui SDL2 binding with OpenGL +// https://github.com/ocornut/imgui + #include #include #include @@ -52,7 +55,7 @@ static void ImGui_ImplSdl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); int vtx_offset = 0; - for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) + for (int cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; if (pcmd->user_callback) @@ -63,7 +66,7 @@ static void ImGui_ImplSdl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_ { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); - glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); + glDrawArrays(GL_TRIANGLES, vtx_offset, (GLsizei)pcmd->vtx_count); } vtx_offset += pcmd->vtx_count; } @@ -117,7 +120,7 @@ bool ImGui_ImplSdl_EventCallback(const SDL_Event& event) ImGuiIO& io = ImGui::GetIO(); unsigned int c = event.text.text[0]; if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); + io.AddInputCharacter((unsigned short)event.text.text[0]); return true; } case SDL_KEYDOWN: @@ -153,6 +156,7 @@ bool ImGui_ImplSdl_CreateDeviceObjects() // Store our identifier io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + // Cleanup (don't clear the input data if you want to append new fonts later) io.Fonts->ClearInputData(); io.Fonts->ClearTexData(); @@ -224,18 +228,16 @@ void ImGui_ImplSdl_NewFrame(SDL_Window *window) SDL_GetWindowSize(window, &w, &h); io.DisplaySize = ImVec2((float)w, (float)h); - // Time + // Setup time step Uint32 time = SDL_GetTicks(); double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); g_Time = current_time; - int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - // Setup inputs // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) else @@ -249,7 +251,7 @@ void ImGui_ImplSdl_NewFrame(SDL_Window *window) io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; - // Hide/show hardware mouse cursor + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); // Start the frame diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h index 6d56b2e0e..1e8d91c4b 100644 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl_example/imgui_impl_sdl.h @@ -1,3 +1,6 @@ +// ImGui SDL2 binding with OpenGL +// https://github.com/ocornut/imgui + struct SDL_Window; typedef union SDL_Event SDL_Event; @@ -6,5 +9,6 @@ void ImGui_ImplSdl_Shutdown(); void ImGui_ImplSdl_NewFrame(SDL_Window *window); bool ImGui_ImplSdl_EventCallback(const SDL_Event& event); +// Use if you want to reset your rendering device without losing ImGui state. void ImGui_ImplSdl_InvalidateDeviceObjects(); bool ImGui_ImplSdl_CreateDeviceObjects();