emoon / rust_minifb

Cross platfrom window and framebuffer crate for Rust
MIT License
980 stars 92 forks source link

Is it possible to update the window while resizing it? #314

Open nuclearcodecat opened 1 year ago

nuclearcodecat commented 1 year ago

Hey, I was trying out minifb, playing around with the ScaleMode properties. I tried getting the window size to update the buffer size, which works, but only if I stop resizing the window. There definitely is a way to get the window size while not released, as I've tested it with other programs and they do that just fine. Is there some way to do that with minifb or is it not implemented?

github_minifb.webm

Here's my code if I'm doing something wrong:

use std::default::Default;

use minifb::{
    Key,
    Window,
    WindowOptions,
    ScaleMode,
    // CursorStyle,
    // MouseMode
};

const DEFSIZE_WIDTH: usize = 800;
const DEFSIZE_HEIGHT: usize = 600;

// const DEFOPT_CURSOR_STYLE: CursorStyle = CursorStyle::Arrow;

fn main() {
    let mut winopt: CurrentWindowOptions = CurrentWindowOptions {
        x: DEFSIZE_WIDTH,
        y: DEFSIZE_HEIGHT,
        bg_color: 0xffffff,
    };

    let mut pixel_buffer: Vec<u32> = vec![winopt.bg_color; winopt.x * winopt.y];

    let mut window = Window::new(
        "this is absolutely NOT the title",
        winopt.x,
        winopt.y,
        WindowOptions {
            resize: true,
            scale_mode: ScaleMode::Stretch,
            ..WindowOptions::default()
        },
    )
    .unwrap_or_else(|e| {
        panic!("{}", e);
    });

    let mut rects = [
        Rect {
            w: 50,
            h: 50,
            color: 0xff_00_ff,
            ..Default::default()
        },

        Rect {
            x: 50,
            w: 50,
            h: 50,
            ..Default::default()
        },

        Rect {
            x: 50,
            y: 50,
            w: 50,
            h: 50,
            color: 0xff_00_ff,
            ..Default::default()
        },

        Rect {
            y: 50,
            w: 50,
            h: 50,
            ..Default::default()
        },
    ];

    // Limit to max ~60 fps update rate
    window.limit_update_rate(Some(std::time::Duration::from_micros(16600)));

    while window.is_open() && !window.is_key_pressed(Key::Escape, minifb::KeyRepeat::No) {
        let new_window_size = (window.get_size().0, window.get_size().1);
        if new_window_size.0 != winopt.x || new_window_size.1 != winopt.y  {
            winopt.x = new_window_size.0;
            winopt.y = new_window_size.1;
            pixel_buffer.reserve_exact(winopt.x * winopt.y);
            pixel_buffer.resize(winopt.x * winopt.y, winopt.bg_color);
            for n in 0..(winopt.x * winopt.y) {
                pixel_buffer[n] = winopt.bg_color;
            }
        }

        for rect in &mut rects {
            rect.fill(&mut pixel_buffer, (winopt.x, winopt.y));
        }

            .update_with_buffer(&pixel_buffer, winopt.x, winopt.y)
            .unwrap();
    }
}

struct Rect {
    x: usize,
    y: usize,
    w: usize,
    h: usize,
    color: u32,
}

impl Default for Rect {
    fn default() -> Self {
        Self { x: 0, y: 0, w: 0, h: 0, color: 0x00_00_00 }
    }
}

impl Rect {
    fn fill(&self, buffer: &mut [u32], window_size: (usize, usize)) {
        for y in 0..self.h {
            for x in 0..self.w {
                let index = (self.y + y) * window_size.0 + (self.x + x);
                if let Some(pixel) = buffer.get_mut(index) {
                    *pixel = self.color;
                }
            }
        }
    }
}

// more like last known windows options
struct CurrentWindowOptions {
    x: usize,
    y: usize,
    bg_color: u32,
}
emoon commented 1 year ago

I think you are doing the correct thing. What likely needs to happen is that the redraw call inside minifb has to be done while resizing. My guess is that WM_PAINT https://github.com/emoon/rust_minifb/blob/master/src/os/windows/mod.rs#L308 isn't called when resizing happens. So the best would likely be to separate the WM_PAINT code to a separate function and look at the events that happens when resizing and call that code at the correct time.

Is this something you would be willing to do a PR for?

nuclearcodecat commented 1 year ago

Is this something you would be willing to do a PR for?

I don't think I have the skills but I may look into it later