From e130b09d9182641d7ca4995b5cfd6bc0d5ca9852 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Wed, 30 Sep 2015 15:12:00 +0100 Subject: [PATCH 1/5] Previous SDL implementation didn't work with my OpenGL 3.3 project, spliced the GLFW OpenGL examples on top of the SDL example to create an option that works for me. Could be useful for others. --- examples/sdl_opengl3_example/README.md | 8 + .../imgui_impl_sdlogl3.cpp | 379 ++++++++++++++++++ .../sdl_opengl3_example/imgui_impl_sdlogl3.h | 14 + examples/sdl_opengl3_example/main.cpp | 108 +++++ 4 files changed, 509 insertions(+) create mode 100644 examples/sdl_opengl3_example/README.md create mode 100644 examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp create mode 100644 examples/sdl_opengl3_example/imgui_impl_sdlogl3.h create mode 100644 examples/sdl_opengl3_example/main.cpp diff --git a/examples/sdl_opengl3_example/README.md b/examples/sdl_opengl3_example/README.md new file mode 100644 index 00000000..f0b83b24 --- /dev/null +++ b/examples/sdl_opengl3_example/README.md @@ -0,0 +1,8 @@ + +# How to Build + +Link +=== +OpenGL +SDL2 +GLEW \ No newline at end of file diff --git a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp new file mode 100644 index 00000000..16a773f9 --- /dev/null +++ b/examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp @@ -0,0 +1,379 @@ +// ImGui SDL2 binding with OpenGL3 +// https://github.com/ocornut/imgui + +#include +#include +#include +#include "imgui.h" +#include "imgui_impl_sdlogl3.h" + +// Data +static SDL_Window* g_Window = NULL; +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; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 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) +void ImGui_ImplSdlOgl3_RenderDrawLists(ImDrawData* draw_data) +{ + // Backup GL state + GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); + GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); + GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); + GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); + GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) + ImGuiIO& io = ImGui::GetIO(); + float fb_height = io.DisplaySize.y * io.DisplayFramebufferScale.y; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // Setup orthographic projection matrix + const float ortho_projection[4][4] = + { + { 2.0f / io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f / -io.DisplaySize.y, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawIdx* idx_buffer_offset = 0; + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.size() * sizeof(ImDrawVert), (GLvoid*)&cmd_list->VtxBuffer.front(), GL_STREAM_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx), (GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer_offset); + } + idx_buffer_offset += pcmd->ElemCount; + } + } + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); + glBindVertexArray(last_vertex_array); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFunc(last_blend_src, last_blend_dst); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); +} + +static const char* ImGui_ImplSdlOgl3_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdlOgl3_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdlOgl3_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + 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(); + io.AddInputCharactersUTF8(event->text.text); + 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; +} + +void ImGui_ImplSdlOgl3_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Build texture atlas + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Create OpenGL 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_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // 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(); +} + +bool ImGui_ImplSdlOgl3_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer, last_vertex_array; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + + const GLchar *vertex_shader = + "#version 330\n" + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "#version 330\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + glCompileShader(g_FragHandle); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + + ImGui_ImplSdlOgl3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindVertexArray(last_vertex_array); + + return true; +} + +void ImGui_ImplSdlOgl3_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdlOgl3_Init(SDL_Window *window) +{ + g_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_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; + 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_ImplSdlOgl3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdlOgl3_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdlOgl3_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#endif + + return true; +} + +void ImGui_ImplSdlOgl3_Shutdown() +{ + if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); + if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); + if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); + g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + + glDetachShader(g_ShaderHandle, g_VertHandle); + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + + glDetachShader(g_ShaderHandle, g_FragHandle); + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } + ImGui::Shutdown(); +} + +void ImGui_ImplSdlOgl3_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdlOgl3_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + // 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; + + // 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 + io.MousePos = ImVec2(-1, -1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} \ No newline at end of file diff --git a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h b/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h new file mode 100644 index 00000000..812efce2 --- /dev/null +++ b/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h @@ -0,0 +1,14 @@ +// ImGui SDL2 binding with OpenGL3 +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdlOgl3_Init(SDL_Window *window); +IMGUI_API void ImGui_ImplSdlOgl3_Shutdown(); +IMGUI_API void ImGui_ImplSdlOgl3_NewFrame(SDL_Window *window); +IMGUI_API bool ImGui_ImplSdlOgl3_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdlOgl3_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdlOgl3_CreateDeviceObjects(); diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp new file mode 100644 index 00000000..0c5438f3 --- /dev/null +++ b/examples/sdl_opengl3_example/main.cpp @@ -0,0 +1,108 @@ +// ImGui - standalone example application for SDL2 + OpenGL + +#include +#include "imgui_impl_sdlogl3.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // 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_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); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdlOgl3_Init(window); + + // Load Fonts + // (see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + // Merge glyphs from multiple fonts into one (e.g. combine default font with another with Chinese glyphs, or add icons) + //ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; + //ImFontConfig icons_config; icons_config.MergeMode = true; icons_config.PixelSnapH = true; + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 18.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/fontawesome-webfont.ttf", 18.0f, &icons_config, icons_ranges); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdlOgl3_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdlOgl3_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_ImplSdlOgl3_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} From 624adb1b23f99c0bdfc6647a717453d25a9c516c Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Nov 2015 22:03:13 +0100 Subject: [PATCH 2/5] Tweak build batch files and readmes --- examples/.gitignore | 1 + examples/allegro5_example/README.md | 5 ++--- examples/opengl3_example/build_win32.bat | 2 +- examples/opengl_example/build_win32.bat | 2 +- examples/sdl_opengl_example/README.md | 5 ++--- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/.gitignore b/examples/.gitignore index acd8b013..61704991 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -28,6 +28,7 @@ opengl3_example/opengl3_example *.o *.obj *.exe +*.pdb ## Ini files imgui.ini diff --git a/examples/allegro5_example/README.md b/examples/allegro5_example/README.md index a444e5b2..d891982b 100644 --- a/examples/allegro5_example/README.md +++ b/examples/allegro5_example/README.md @@ -9,8 +9,7 @@ g++ -I ../imgui main.cpp imgui_impl_a5.cpp ../imgui/imgui*.cpp -lallegro -lalleg - On Windows with Visual Studio's CLI -\ is your allegro5 folder. - ``` -cl /MD /I /I ..\imgui main.cpp imgui_impl_a5.cpp ..\imgui\imgui*.cpp /link /LIBPATH: allegro-5.0.10-monolith-md.lib user32.lib +set ALLEGRODIR=path_to_your_allegro5_folder +cl /Zi /MD /I %ALLEGRODIR%\include /I ..\.. main.cpp imgui_impl_a5.cpp ..\..\imgui*.cpp /link /LIBPATH:%ALLEGRODIR%\lib allegro-5.0.10-monolith-md.lib user32.lib ``` diff --git a/examples/opengl3_example/build_win32.bat b/examples/opengl3_example/build_win32.bat index 9cb86e0b..93115918 100644 --- a/examples/opengl3_example/build_win32.bat +++ b/examples/opengl3_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. -I ..\libs\glfw\include -I ..\libs\gl3w *.cpp ..\..\*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/opengl_example3.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I ..\libs\gl3w *.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/opengl_example3.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat index a214a4b8..278381c7 100644 --- a/examples/opengl_example/build_win32.bat +++ b/examples/opengl_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. -I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md index d89ebb45..aada45d6 100644 --- a/examples/sdl_opengl_example/README.md +++ b/examples/sdl_opengl_example/README.md @@ -3,10 +3,9 @@ - On Windows with Visual Studio's CLI -\ is your SDL2 folder. - ``` -cl /MD /I /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH: SDL2.lib SDL2main.lib +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib ``` - On Linux and similar Unixes From 9d0caa2e6649cc7f058f5d684251109b8d9a4f59 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Nov 2015 22:05:22 +0100 Subject: [PATCH 3/5] Examples: SDL+OpenGL3: Using glew like existing example + renaming (#356) --- examples/sdl_opengl3_example/README.md | 24 ++++++++++--- ...mpl_sdlogl3.cpp => imgui_impl_sdl_gl3.cpp} | 34 +++++++++---------- .../sdl_opengl3_example/imgui_impl_sdl_gl3.h | 14 ++++++++ .../sdl_opengl3_example/imgui_impl_sdlogl3.h | 14 -------- examples/sdl_opengl3_example/main.cpp | 15 ++++---- 5 files changed, 58 insertions(+), 43 deletions(-) rename examples/sdl_opengl3_example/{imgui_impl_sdlogl3.cpp => imgui_impl_sdl_gl3.cpp} (93%) create mode 100644 examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h delete mode 100644 examples/sdl_opengl3_example/imgui_impl_sdlogl3.h diff --git a/examples/sdl_opengl3_example/README.md b/examples/sdl_opengl3_example/README.md index f0b83b24..a0d94cfe 100644 --- a/examples/sdl_opengl3_example/README.md +++ b/examples/sdl_opengl3_example/README.md @@ -1,8 +1,22 @@ # How to Build -Link -=== -OpenGL -SDL2 -GLEW \ No newline at end of file +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp similarity index 93% rename from examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp rename to examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 16a773f9..fdf3ff5a 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -3,9 +3,9 @@ #include #include -#include +#include #include "imgui.h" -#include "imgui_impl_sdlogl3.h" +#include "imgui_impl_sdl_gl3.h" // Data static SDL_Window* g_Window = NULL; @@ -21,7 +21,7 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 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) -void ImGui_ImplSdlOgl3_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) { // Backup GL state GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); @@ -106,17 +106,17 @@ void ImGui_ImplSdlOgl3_RenderDrawLists(ImDrawData* draw_data) if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); } -static const char* ImGui_ImplSdlOgl3_GetClipboardText() +static const char* ImGui_ImplSdlGL3_GetClipboardText() { return SDL_GetClipboardText(); } -static void ImGui_ImplSdlOgl3_SetClipboardText(const char* text) +static void ImGui_ImplSdlGL3_SetClipboardText(const char* text) { SDL_SetClipboardText(text); } -bool ImGui_ImplSdlOgl3_ProcessEvent(SDL_Event* event) +bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); switch (event->type) @@ -156,7 +156,7 @@ bool ImGui_ImplSdlOgl3_ProcessEvent(SDL_Event* event) return false; } -void ImGui_ImplSdlOgl3_CreateFontsTexture() +void ImGui_ImplSdlGL3_CreateFontsTexture() { ImGuiIO& io = ImGui::GetIO(); @@ -180,7 +180,7 @@ void ImGui_ImplSdlOgl3_CreateFontsTexture() io.Fonts->ClearTexData(); } -bool ImGui_ImplSdlOgl3_CreateDeviceObjects() +bool ImGui_ImplSdlGL3_CreateDeviceObjects() { // Backup GL state GLint last_texture, last_array_buffer, last_vertex_array; @@ -247,7 +247,7 @@ bool ImGui_ImplSdlOgl3_CreateDeviceObjects() glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); #undef OFFSETOF - ImGui_ImplSdlOgl3_CreateFontsTexture(); + ImGui_ImplSdlGL3_CreateFontsTexture(); // Restore modified GL state glBindTexture(GL_TEXTURE_2D, last_texture); @@ -257,7 +257,7 @@ bool ImGui_ImplSdlOgl3_CreateDeviceObjects() return true; } -void ImGui_ImplSdlOgl3_InvalidateDeviceObjects() +void ImGui_ImplSdlGL3_InvalidateDeviceObjects() { if (g_FontTexture) { @@ -267,7 +267,7 @@ void ImGui_ImplSdlOgl3_InvalidateDeviceObjects() } } -bool ImGui_ImplSdlOgl3_Init(SDL_Window *window) +bool ImGui_ImplSdlGL3_Init(SDL_Window *window) { g_Window = window; @@ -292,9 +292,9 @@ bool ImGui_ImplSdlOgl3_Init(SDL_Window *window) io.KeyMap[ImGuiKey_Y] = SDLK_y; io.KeyMap[ImGuiKey_Z] = SDLK_z; - io.RenderDrawListsFn = ImGui_ImplSdlOgl3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdlOgl3_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdlOgl3_GetClipboardText; + io.RenderDrawListsFn = ImGui_ImplSdlGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdlGL3_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; #ifdef _WIN32 SDL_SysWMinfo wmInfo; @@ -306,7 +306,7 @@ bool ImGui_ImplSdlOgl3_Init(SDL_Window *window) return true; } -void ImGui_ImplSdlOgl3_Shutdown() +void ImGui_ImplSdlGL3_Shutdown() { if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); @@ -333,10 +333,10 @@ void ImGui_ImplSdlOgl3_Shutdown() ImGui::Shutdown(); } -void ImGui_ImplSdlOgl3_NewFrame(SDL_Window *window) +void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window) { if (!g_FontTexture) - ImGui_ImplSdlOgl3_CreateDeviceObjects(); + ImGui_ImplSdlGL3_CreateDeviceObjects(); ImGuiIO& io = ImGui::GetIO(); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h new file mode 100644 index 00000000..e324b3da --- /dev/null +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -0,0 +1,14 @@ +// ImGui SDL2 binding with OpenGL3 +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window *window); +IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); +IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window); +IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdlGL3_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdlGL3_CreateDeviceObjects(); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h b/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h deleted file mode 100644 index 812efce2..00000000 --- a/examples/sdl_opengl3_example/imgui_impl_sdlogl3.h +++ /dev/null @@ -1,14 +0,0 @@ -// ImGui SDL2 binding with OpenGL3 -// https://github.com/ocornut/imgui - -struct SDL_Window; -typedef union SDL_Event SDL_Event; - -IMGUI_API bool ImGui_ImplSdlOgl3_Init(SDL_Window *window); -IMGUI_API void ImGui_ImplSdlOgl3_Shutdown(); -IMGUI_API void ImGui_ImplSdlOgl3_NewFrame(SDL_Window *window); -IMGUI_API bool ImGui_ImplSdlOgl3_ProcessEvent(SDL_Event* event); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplSdlOgl3_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplSdlOgl3_CreateDeviceObjects(); diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 0c5438f3..24c37dbe 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -1,10 +1,10 @@ // ImGui - standalone example application for SDL2 + OpenGL #include -#include "imgui_impl_sdlogl3.h" +#include "imgui_impl_sdl_gl3.h" #include +#include #include -#include int main(int, char**) { @@ -23,11 +23,12 @@ int main(int, char**) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 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); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); SDL_GLContext glcontext = SDL_GL_CreateContext(window); + gl3wInit(); // Setup ImGui binding - ImGui_ImplSdlOgl3_Init(window); + ImGui_ImplSdlGL3_Init(window); // Load Fonts // (see extra_fonts/README.txt for more details) @@ -56,11 +57,11 @@ int main(int, char**) SDL_Event event; while (SDL_PollEvent(&event)) { - ImGui_ImplSdlOgl3_ProcessEvent(&event); + ImGui_ImplSdlGL3_ProcessEvent(&event); if (event.type == SDL_QUIT) done = true; } - ImGui_ImplSdlOgl3_NewFrame(window); + ImGui_ImplSdlGL3_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" @@ -99,7 +100,7 @@ int main(int, char**) } // Cleanup - ImGui_ImplSdlOgl3_Shutdown(); + ImGui_ImplSdlGL3_Shutdown(); SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(window); SDL_Quit(); From ab7e91b65eb9e823006ccb16058b8fc5d515b123 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Nov 2015 22:12:18 +0100 Subject: [PATCH 4/5] Examples: SDL+OpenGL3: Various fixes to example to make it matches current GL3 example (#356) --- .../imgui_impl_sdl_gl3.cpp | 85 ++++++++++--------- .../sdl_opengl3_example/imgui_impl_sdl_gl3.h | 5 +- examples/sdl_opengl3_example/main.cpp | 2 +- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index fdf3ff5a..3ba31798 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -1,11 +1,16 @@ // ImGui SDL2 binding with OpenGL3 +// You can copy and use unmodified imgui_impl_* files in your project. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// See main.cpp for an example of using this. // https://github.com/ocornut/imgui +#include "imgui.h" +#include "imgui_impl_sdl_gl3.h" + +// SDL,GL3W #include #include #include -#include "imgui.h" -#include "imgui_impl_sdl_gl3.h" // Data static SDL_Window* g_Window = NULL; @@ -33,6 +38,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); @@ -53,12 +59,13 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Setup orthographic projection matrix + glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y); const float ortho_projection[4][4] = { - { 2.0f / io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f / -io.DisplaySize.y, 0.0f, 0.0f }, + { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f, 1.0f }, + {-1.0f, 1.0f, 0.0f, 1.0f }, }; glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); @@ -86,7 +93,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer_offset); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } idx_buffer_offset += pcmd->ElemCount; } @@ -104,6 +111,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); } static const char* ImGui_ImplSdlGL3_GetClipboardText() @@ -165,7 +173,7 @@ void ImGui_ImplSdlGL3_CreateFontsTexture() int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. - // Create OpenGL texture + // Create OpenGL texture glGenTextures(1, &g_FontTexture); glBindTexture(GL_TEXTURE_2D, g_FontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -259,12 +267,28 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() void ImGui_ImplSdlGL3_InvalidateDeviceObjects() { - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } + if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); + if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); + if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); + g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + + glDetachShader(g_ShaderHandle, g_VertHandle); + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + + glDetachShader(g_ShaderHandle, g_FragHandle); + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } } bool ImGui_ImplSdlGL3_Init(SDL_Window *window) @@ -308,32 +332,11 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window *window) void ImGui_ImplSdlGL3_Shutdown() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); - if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); - if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; - - glDetachShader(g_ShaderHandle, g_VertHandle); - glDeleteShader(g_VertHandle); - g_VertHandle = 0; - - glDetachShader(g_ShaderHandle, g_FragHandle); - glDeleteShader(g_FragHandle); - g_FragHandle = 0; - - glDeleteProgram(g_ShaderHandle); - g_ShaderHandle = 0; - - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } + ImGui_ImplSdlGL3_InvalidateDeviceObjects(); ImGui::Shutdown(); } -void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window) +void ImGui_ImplSdlGL3_NewFrame() { if (!g_FontTexture) ImGui_ImplSdlGL3_CreateDeviceObjects(); @@ -342,11 +345,9 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window) // Setup display size (every frame to accommodate for window resizing) int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GetWindowSize(window, &display_w, &display_h); + SDL_GetWindowSize(g_Window, &w, &h); io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); // Setup time step Uint32 time = SDL_GetTicks(); @@ -358,7 +359,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window) // (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) + if (SDL_GetWindowFlags(g_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); @@ -376,4 +377,4 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window) // Start the frame ImGui::NewFrame(); -} \ No newline at end of file +} diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index e324b3da..ef4757cc 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -1,4 +1,7 @@ // ImGui SDL2 binding with OpenGL3 +// You can copy and use unmodified imgui_impl_* files in your project. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// See main.cpp for an example of using this. // https://github.com/ocornut/imgui struct SDL_Window; @@ -6,7 +9,7 @@ typedef union SDL_Event SDL_Event; IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window *window); IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); -IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window *window); +IMGUI_API void ImGui_ImplSdlGL3_NewFrame(); IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event); // Use if you want to reset your rendering device without losing ImGui state. diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 24c37dbe..ca640699 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -61,7 +61,7 @@ int main(int, char**) if (event.type == SDL_QUIT) done = true; } - ImGui_ImplSdlGL3_NewFrame(window); + ImGui_ImplSdlGL3_NewFrame(); // 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 899cb3b4e968d9b292f69695e3eb65771f8a047a Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Nov 2015 22:13:06 +0100 Subject: [PATCH 5/5] Examples: SDL+OpenGL3: Fixed readme (#356) --- examples/sdl_opengl3_example/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl3_example/README.md b/examples/sdl_opengl3_example/README.md index a0d94cfe..30d3a09c 100644 --- a/examples/sdl_opengl3_example/README.md +++ b/examples/sdl_opengl3_example/README.md @@ -11,12 +11,12 @@ cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl - On Linux and similar Unixes ``` -c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -lGL -o sdl2example +c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl_gl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -lGL -o sdl2example ``` - On Mac OS X ``` brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -o sdl2example +c++ `sdl2-config --cflags` -I ../.. -I ../libs/gl3w main.cpp imgui_impl_sdl_gl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -o sdl2example ```