Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLFW window Resize effect on Imgui UI #7225

Closed
kowalski100 opened this issue Jan 15, 2024 · 5 comments
Closed

GLFW window Resize effect on Imgui UI #7225

kowalski100 opened this issue Jan 15, 2024 · 5 comments

Comments

@kowalski100
Copy link

kowalski100 commented Jan 15, 2024

Version/Branch of Dear ImGui:

master

Back-ends:

imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp

Compiler, OS:

MSVC 2022

Full config/build information:

No response

Details:

Hi,

I am trying to explore IMGUI for our next project. First of all great efforts. Really appreciable. Since I new so I created a quick UI with the code below. All I wanted was to create a side panel that should stick to the left top and upon resizing the window it should remain stick during mouse resize drag. I tried many methods but couldn't figure it out I also searched online and repo but couldn't get any clue. Maybe I am new to this library but experts here can best guide me.

Also the resolution looks very different on various screens like very tiny on one screen and satisfactory on another.

`
#include "imgui/imgui.h"
#include "imgui/imgui_impl_glfw.h"
#include "imgui/imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>

float sidePanelWidth = 200.0f;

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
// You can adjust this multiplier as needed
const float panelWidthMultiplier = 0.25f;
sidePanelWidth = static_cast(width) * panelWidthMultiplier;
}

void renderSidePanel() {
// Your side panel rendering code goes here
ImGui::Text("Side Panel Content");
// Add more ImGui widgets as needed
}

int main() {
// Initialize GLFW and create a window
if (!glfwInit()) return -1;

GLFWwindow* window = glfwCreateWindow(800, 600, "ImGui Resizable Left Side Panel Example", NULL, NULL);
if (!window) {
    glfwTerminate();
    return -1;
}

glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

// Initialize ImGui
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;

// Initialize ImGui for GLFW and OpenGL
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");

// Main loop
while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();

    // Start the ImGui frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // Render your main content here

    // Render the side panel
    ImGui::SetNextWindowSize(ImVec2(sidePanelWidth, 600), ImGuiCond_Always);
    ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
    ImGui::Begin("Side Panel", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);

    renderSidePanel();  // Call your function to render the side panel content

    ImGui::End();

    // Rendering
    ImGui::Render();
    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);
}

// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

glfwDestroyWindow(window);
glfwTerminate();

return 0;

}
`

Screenshots/Video:

WhatsApp Image 2024-01-15 at 7 47 28 PM
WhatsApp Image 2024-01-15 at 7 47 29 PM

Minimal, Complete and Verifiable Example code:

// Here's some code anyone can copy and paste to reproduce your issue
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
@ocornut
Copy link
Owner

ocornut commented Jan 15, 2024

The logic you posted seems to work here so I think you omitted something.

By the way the better sizing logic (simpler for width, correct for height) would be:

ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y));
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::Begin("Side Panel", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);

@kowalski100
Copy link
Author

kowalski100 commented Jan 16, 2024

Hi ocornut,

Thanks for the reply and my apologies for the late reply. Unfortunately I still see the same effect.

int main() {
    // Initialize GLFW and create a window
    if (!glfwInit()) return -1;

    GLFWwindow* window = glfwCreateWindow(800, 600, "ImGui Resizable Left Side Panel Example", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // Initialize ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    // Initialize ImGui for GLFW and OpenGL
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    // Main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();

        // Start the ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // Render your main content here

        // Render the side panel
        ImGuiViewport* viewport = ImGui::GetMainViewport();
        ImGui::SetNextWindowSize(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y));
        ImGui::SetNextWindowPos(viewport->Pos);
        ImGui::Begin("Side Panel", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);

        renderSidePanel();  // Call your function to render the side panel content

        ImGui::End();

        // Rendering
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Video attached.

WhatsApp.Video.2024-01-16.at.10.41.12.PM.mp4

@ocornut
Copy link
Owner

ocornut commented Jan 16, 2024

If you are referring to the effect DURING resize, it is a known Windows API issue unrelated to Dear ImGui or GLFW.
See #3672 #5728 #5076 #6010 #5728 7003

@ocornut ocornut closed this as completed Jan 16, 2024
@kowalski100
Copy link
Author

Thank @ocornut,

I was able to make it work with solutions mentioned in your suggested thread - though I still see resolution problem on various screens and while resizing. any comment on that? how to handle imgui resolution on different density screens?

I am pasting code for other's reference.

float sidePanelWidth = 200.0f;

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    // You can adjust this multiplier as needed
    const float panelWidthMultiplier = 0.25f;
    sidePanelWidth = static_cast<float>(width) * panelWidthMultiplier;
}

void renderSidePanel() {
    // Your side panel rendering code goes here
    ImGui::Text("Side Panel Content");
    // Add more ImGui widgets as needed
}

void window_size_callback(GLFWwindow* window, int width, int height)
{
    std::cout << "width: " << width << " height: " << height << "\n";
}

void window_refresh_callback(GLFWwindow* window)
{
    glfwSwapBuffers(window);
}


int main() {
    // Initialize GLFW and create a window
    if (!glfwInit()) return -1;

    GLFWwindow* window = glfwCreateWindow(800, 600, "ImGui Resizable Left Side Panel Example", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glfwSetWindowSizeCallback(window, window_size_callback);
    glfwSetWindowRefreshCallback(window, window_refresh_callback);

    // Initialize ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    // Initialize ImGui for GLFW and OpenGL
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    // Main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();

        // Start the ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // Render your main content here

        // Render the side panel
        ImGuiViewport* viewport = ImGui::GetMainViewport();
        ImGui::SetNextWindowSize(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y));
        ImGui::SetNextWindowPos(ImVec2(0, 0));
        ImGui::Begin("Side Panel", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);

        renderSidePanel();  // Call your function to render the side panel content

        ImGui::End();

        // Rendering
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

@ocornut
Copy link
Owner

ocornut commented Jan 16, 2024

though I still see resolution problem on various screens and while resizing. any comment on that? how to handle imgui resolution on different density screens?

Sorry that's too vague. Feel free to details and check other issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants