Как заставить SDL(2) обновлять содержимое convas при изменении размера?

(предпосылка: (псевдо) код написан на Rust, однако принимаются ответы на любом языке, поскольку библиотека Rust SDL очень похожа на стандартную).

У меня есть очень минимальный шаблон SDL2, который я использую, когда мне нужно нарисовать изображение, отобразить его (в развернутом окне) и дождаться нажатия клавиши.

Текущая логика работает, однако у нее есть придирка: после того, как окно развернуто (и холст обновлен), если я изменяю размер окна, перерисовка не происходит.

Это мой текущий псевдокод:

let sdl_context = sdl2::init().unwrap();

let window = sdl_context
    .video()
    .unwrap()
    .window(""window_title"", width as u32, height as u32)
    .maximized()
    .position_centered()
    .resizable()
    .build()
    .unwrap();

let mut event_pump = sdl_context.event_pump().unwrap();

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

canvas.set_logical_size(640, 480).unwrap();

// Needed to redraw, as the window has been maximized above.
//
event_pump.pump_events();

////////////////////////////////////////
// Here some pixels are drawn.
////////////////////////////////////////

canvas.present();

// Wait for a keypress or quit event.
//
for event in event_pump.wait_iter() {
    match event {
        Event::KeyDown { .. } => std::process::exit(0),
        Event::KeyUp { .. } => std::process::exit(0),
        Event::Quit { .. } => std::process::exit(0),
        _ => {}
    }
}

Если я запускаю этот код и изменяю размер окна, не нажимая никаких клавиш (или не выходя из него), холст не перерисовывается.

Как мне изменить код, чтобы он перерисовывался?

(обратите внимание, что я не использую текстуры, потому что они усложняют код, и в случаях, когда я использую этот шаблон, либо скорость не имеет значения, либо нет заметного улучшения скорости)


person Marcus    schedule 28.10.2020    source источник


Ответы (1)


Существует WindowEvent::Resized событие, поэтому следующее должно работать (непроверено):

for event in event_pump.wait_iter() {
    match event {
        Event::KeyDown { .. } => std::process::exit(0),
        Event::KeyUp { .. } => std::process::exit(0),
        Event::Quit { .. } => std::process::exit(0),
        Event::WindowEvent (WindowEvent::Resized (w, h)) => unimplemented!(), // Redraw the window
        _ => {}
    }
}
person Jmb    schedule 29.10.2020
comment
Означает ли перерисовка, что мне нужно сохранить внутреннюю копию изображения, которое нужно нарисовать? Или есть функция SDL для обновления? - person Marcus; 29.10.2020
comment
Вам необходимо сохранить копию изображения или переделать операции рисования с учетом нового размера окна. - person Jmb; 29.10.2020
comment
Я понимаю; это то, чего я хотел избежать, но оказалось, что это необходимо. Спасибо! - person Marcus; 29.10.2020