ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.98k stars 10.19k forks source link

Window Resize Causing Blank Window with SDL2 + OpenGL Backend. #4989

Closed Fredrum closed 2 years ago

Fredrum commented 2 years ago

Dear ImGui 1.85 WIP (18418)

sizeof(size_t): 4, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20 define: cplusplus=201402 define: linux define: GNUC__=8

io.BackendPlatformName: imgui_impl_sdl io.BackendRendererName: imgui_impl_sdlrenderer io.ConfigFlags: 0x00000002 NavEnableGamepad io.ConfigInputTextCursorBlink io.ConfigWindowsResizeFromEdges io.ConfigMemoryCompactTimer = 60.0 io.BackendFlags: 0x00000007 HasGamepad HasMouseCursors HasSetMousePos

Using on Raspberry OS Buster 32bit Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux Using SDL2 2.0.17

SDL renderer opengles2

name of display: :0.0 display: :0 screen: 0 direct rendering: Yes Extended renderer info (GLX_MESA_query_renderer): Vendor: Broadcom (0x14e4) Device: V3D 4.2 (0xffffffff) Version: 21.3.0 Accelerated: yes Video memory: 7847MB Unified memory: yes Preferred profile: compat (0x2) Max core profile version: 0.0 Max compat profile version: 2.1 Max GLES1 profile version: 1.1 Max GLES[23] profile version: 3.1 OpenGL vendor string: Broadcom OpenGL renderer string: V3D 4.2 OpenGL version string: 2.1 Mesa 21.3.0-devel (git-c679dbe09c) OpenGL shading language version string: 1.20 OpenGL ES profile version string: OpenGL ES 3.1 Mesa 21.3.0-devel (git-c679dbe09c) OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10

I'm setting up backend using

gl_ctx = SDL_GL_CreateContext(sdl_window);
ImGui_ImplSDL2_InitForOpenGL(sdl_window, gl_ctx);
const char* glsl_version = "#version 300 es"; //was: 100
ImGui_ImplOpenGL3_Init(glsl_version);

====================================================================

Hello!

In my Imgui+SDL2+gles2 program I'm experiencing a problem that whenever I resize the window all Imgui widget graphics disappear and I am left with only the clear color. If I move the window, drawing works fine.

I have a main loop that looks like this,

while(!done)
{
    HandleSDLEvents(); 

    // Create Imgui Widgets;

    // Imgui + OpenGL render;
}

I have managed to get the imgui widgets to draw if I re-emit the window resize SDL event. But I then also get stuck in an infinite loop.

This works: (but with inf loop)

        while (SDL_PollEvent(&event))
        {
                        ImGui_ImplSDL2_ProcessEvent(&event);
            switch (event.type)
            {
                case SDL_WINDOWEVENT:
                if (event.window.event == SDL_WINDOWEVENT_RESIZED)
                {
                    resizeEvent(event.window.data1, event.window.data2); // just prints new size
                    SDL_PushEvent(&event);   // <<<-----   makes it draw but also cause never ending loop
                    break;
                }
            }
        }

This causes a clear colored blank window, no imgui widgets drawn after resize:

        while (SDL_PollEvent(&event))
        {
                        ImGui_ImplSDL2_ProcessEvent(&event);
            switch (event.type)
            {
                case SDL_WINDOWEVENT:
                if (event.window.event == SDL_WINDOWEVENT_RESIZED)
                {
                    resizeEvent(event.window.data1, event.window.data2); // just prints new size
                    break;
                }
            }
        }

I't seems like the SDL event get consumed whilst it really needs to live on to be consumed by Imgui? Is it not strange that the window move events don't cause the same issue?

EDIT: Thinking about it maybe the first snippet just looks like it's working but its really just stuck in a loop and not refreshing the window. Im back now looking in the imgui sdl+gl3 example source file.

Any ideas how I can work around this?

Cheers! Fred

Fredrum commented 2 years ago

By comparing my source code with the Imgui SDL+GL3 example ive just identified that it's these lines in my code that cause the behaviour,

SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1");
SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1");
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2");

Or rather I suppose, its it the 'opengles2' SDL render driver that is incompatible with something? When I get a 'opengl' SDL render driver the resize refresh works. UPDATE: Hmm though the Imgui example work even after forcing "opengles2". It does also have something to do with the SDL events. When I completely disable the while _(SDLPollEvent(&event)) loop the resize refresh also works.

rokups commented 2 years ago

Could you please test if issue persists if you switch to OpenGL ES 3.0?

Fredrum commented 2 years ago

Hm not sure how to make it do gles 3.0?

I tried a bunch of things like,

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);   //  ALSO TRIED 1 here

this returns, GL_VERSION : OpenGL ES 3.1 Mesa 21.3.0-devel (git-c679dbe09c) from,

printf("GL_VERSION  : %s\n", glGetString(GL_VERSION) );
printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER) );

actually my initial setting below also returns 'ES 3.1',

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);  // Note the '2'
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);

I tried changing this to, SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles3"); but the '3' seems to not be a thing.

The Imgui sdl+GL3 example which works also returns same GL version,

GL_VERSION  : OpenGL ES 3.1 Mesa 21.3.0-devel (git-c679dbe09c)
GL_RENDERER : V3D 4.2
Fredrum commented 2 years ago

I figured it out. I was doing the SDL_GL_CreateContext(sdl_window) and the other connecting calls in a slightly different order than was done in the Imgui example. After changing to match closely to that it started working!

rokups commented 2 years ago

So to clarify, correcting order of function calls fixed your issue on GLES2.0? Or did switching to GLES3.0 fix it?

Fredrum commented 2 years ago

Basically just shifting the place in the code and how I used the sdl generated GL context, was what solved it. I more closely mimicked the order of events around the gl context, to how it was done in the Imgui SDL+opengl3 example code. I was not able to get any other GLES version than 3.1. Maybe a raspberry Pi limitation in their OpenGL implementations/hardware.