0

I'm developing an application using the imgui-rs library in Rust with SDL2 and OpenGL. However, I'm experiencing an issue where the UI elements are constantly blinking during the application's execution. I've tried various approaches, but the blinking persists. I came across this GitHub issue (https://github.com/ocornut/imgui/issues/5835), which discusses a similar problem in the C++ version of imgui. However, I couldn't find any information specific to the Rust version.

Here is a simplified version of my code:

use glow::HasContext;
use imgui::Context;
use imgui_glow_renderer::AutoRenderer;
use imgui_sdl2_support::SdlPlatform;
use sdl2::{
    event::Event,
    video::{GLProfile, Window}
};
use sdl2::image::LoadTexture;
use std::path::Path;

// Create a new glow context.
fn glow_context(window: &Window) -> glow::Context {
    unsafe {
        glow::Context::from_loader_function(|s| window.subsystem().gl_get_proc_address(s) as _)
    }
}

fn main() {
    /* initialize SDL and its video subsystem */
    let sdl = sdl2::init().unwrap();
    let video_subsystem = sdl.video().unwrap();

    /* hint SDL to initialize an OpenGL 3.3 core profile context */
    let gl_attr = video_subsystem.gl_attr();

    gl_attr.set_context_version(3, 3);
    gl_attr.set_context_profile(GLProfile::Core);
    gl_attr.set_double_buffer(true);
    gl_attr.set_multisample_samples(4);
    gl_attr.set_framebuffer_srgb_compatible(true);

    /* create a new window, be sure to call opengl method on the builder when using glow! */
    let window = video_subsystem
        .window("Hello imgui-rs!", 1280, 720)
        .allow_highdpi()
        .opengl()
        .position_centered()
        .resizable()
        .build()
        .unwrap();

    /* create a new OpenGL context and make it current */
    let gl_context = window.gl_create_context().unwrap();
    window.gl_make_current(&gl_context).unwrap();
    unsafe { 
        sdl2::sys::SDL_GL_SetAttribute(sdl2_sys::SDL_GLattr::SDL_GL_DEPTH_SIZE, 24);
        sdl2::sys::SDL_GL_SetAttribute(sdl2_sys::SDL_GLattr::SDL_GL_STENCIL_SIZE, 8);
        sdl2::sys::SDL_GL_SetAttribute(sdl2_sys::SDL_GLattr::SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
    }

    let mut canvas = window.into_canvas().present_vsync().build().unwrap();

    /* enable vsync to cap framerate */
    canvas.window().subsystem().gl_set_swap_interval(1).unwrap();

    /* create new glow and imgui contexts */
    let gl = glow_context(&canvas.window());

    /* create context */
    let mut imgui = Context::create();

    /* disable creation of files on disc */
    imgui.set_ini_filename(None);
    imgui.set_log_filename(None);

    /* setup platform and renderer, and fonts to imgui */
    imgui
        .fonts()
        .add_font(&[imgui::FontSource::DefaultFontData { config: None }]);

    /* create platform and renderer */
    let mut platform = SdlPlatform::init(&mut imgui);
    let mut renderer = AutoRenderer::initialize(gl, &mut imgui).unwrap();

    /* load texture from PNG file */
    let texture_creator = canvas.texture_creator();
    let texture = texture_creator.load_texture(Path::new("path/to/texture.png")).unwrap();
    let texture_rect = Some(sdl2::rect::Rect::new(0, 0, 50, 50));

    /* start main loop */
    let mut event_pump = sdl.event_pump().unwrap();

    'main: loop {
        for event in event_pump.poll_iter() {
            /* pass all events to imgui platform */
            platform.handle_event(&mut imgui, &event);

            if let Event::Quit { .. } = event {
                break 'main;
            }
        }

        /* call prepare_frame before calling imgui.new_frame() */
        platform.prepare_frame(&mut imgui, &canvas.window(), &event_pump);

        let ui = imgui.new_frame();
        /* create imgui UI here */
        ui.show_demo_window(&mut true);

        /* render texture */
        canvas.clear();
        canvas.copy(&texture, None, texture_rect).unwrap();

        /* render */
        let draw_data = imgui.render();

        unsafe { renderer.gl_context().clear(glow::COLOR_BUFFER_BIT) };
        renderer.render(draw_data).unwrap();
        canvas.window().gl_swap_window();

        canvas.present();
    }
}

Could you please help me understand why the UI components are blinking and suggest a way to avoid this issue?

What I've Tried:

  • I have checked my OpenGL settings and ensured that the double buffering is enabled.
  • I have set the swap interval to 1 to enable VSync and cap the framerate.
  • I have made sure to call platform.prepare_frame() before imgui.new_frame().
  • I have attempted to render the UI after rendering the texture.

Expected Behavior:

I expect the UI components to be displayed without any blinking or flickering.

What could be causing this blinking issue in my ImGui application? How can I avoid it? Any insights or suggestions would be greatly appreciated.

totta
  • 1
  • 3

0 Answers0