diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 1713bd5c..63eb3ab9 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -42,15 +42,18 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) 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 width = ImGui::GetIO().DisplaySize.x; - const float height = ImGui::GetIO().DisplaySize.y; const float ortho_projection[4][4] = { - { 2.0f/width, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f/-height, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f, 1.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 }, }; glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); @@ -77,7 +80,7 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + 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; @@ -307,7 +310,8 @@ void ImGui_ImplGlfwGL3_NewFrame() int display_w, display_h; glfwGetWindowSize(g_Window, &w, &h); glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); // Setup time step double current_time = glfwGetTime(); @@ -320,9 +324,7 @@ void ImGui_ImplGlfwGL3_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels - mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) } else { diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 211dcb81..38288fe8 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -53,7 +53,6 @@ int main(int, char**) // Main loop while (!glfwWindowShouldClose(window)) { - ImGuiIO& io = ImGui::GetIO(); glfwPollEvents(); ImGui_ImplGlfwGL3_NewFrame(); @@ -86,7 +85,9 @@ int main(int, char**) } // Rendering - glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index 331c7776..088be115 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -40,13 +40,16 @@ static void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) glEnable(GL_TEXTURE_2D); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + // 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 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); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); @@ -72,7 +75,7 @@ static void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + 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); } idx_buffer += pcmd->ElemCount; @@ -231,7 +234,8 @@ void ImGui_ImplGlfw_NewFrame() int display_w, display_h; glfwGetWindowSize(g_Window, &w, &h); glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); // Setup time step double current_time = glfwGetTime(); @@ -244,9 +248,7 @@ void ImGui_ImplGlfw_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels - mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) } else { diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp index d7765892..64bd1feb 100644 --- a/examples/opengl_example/main.cpp +++ b/examples/opengl_example/main.cpp @@ -77,7 +77,9 @@ int main(int, char**) } // Rendering - glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); diff --git a/imgui.cpp b/imgui.cpp index bd07324c..c5bdb47a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -678,6 +678,7 @@ ImGuiIO::ImGuiIO() LogFilename = "imgui_log.txt"; Fonts = &GImDefaultFontAtlas; FontGlobalScale = 1.0f; + DisplayFramebufferScale = ImVec2(1.0f, 1.0f); MousePos = ImVec2(-1,-1); MousePosPrev = ImVec2(-1,-1); MouseDoubleClickTime = 0.30f; diff --git a/imgui.h b/imgui.h index 9dd0d073..cb040762 100644 --- a/imgui.h +++ b/imgui.h @@ -676,6 +676,7 @@ struct ImGuiIO ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. float FontGlobalScale; // = 1.0f // Global scale all fonts bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. + ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui. ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize