Minimal Pixels example isn't working

Hi,
I've been trying to re-do the pixels "minimal" example, except I tried to make it much more minimal. I think I over-minimalized it since it's just showing a black screen on my device (Pop!_OS 21.04). Any help would be appreciated. Here's my code:

use winit::event::{Event, WindowEvent};
use winit::event_loop::ControlFlow;

fn draw(frame: &mut [u8]) {
    for pixel in frame {
        *pixel = 255;
    }
}

fn main() {
    let event_loop = winit::event_loop::EventLoop::new();
    let window = {
        let size = winit::dpi::LogicalSize::new(320.0, 240.0);
        winit::window::WindowBuilder::new()
            .with_title("Pixels Test")
            .with_inner_size(size)
            .with_min_inner_size(size)
            .build(&event_loop)
            .unwrap()
    };
        
    let mut pixels = {
        let window_size = window.inner_size();
        let surface_texture = pixels::SurfaceTexture::new(window_size.width, window_size.height, &window);
        pixels::Pixels::new(window_size.width, window_size.height, surface_texture).unwrap()
    };

    draw(pixels.get_frame());

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Poll;

        match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                ..
            } => *control_flow = ControlFlow::Exit,
            Event::RedrawRequested(_) => {
                if pixels.render().is_err() {
                    *control_flow = ControlFlow::Exit;
                }
            },
            _ => {}
        };

        window.request_redraw();
    });
}

Thanks!

Edit: I wanted to note that the screen isn't frozen; I can quit out of it perfectly fine. It's just showing a black screen.

I get a white window on my linux box. If I change the

*pixel = 255;
into
*pixel = 126
the window is grey.

Your code as posted appears to work.
I get a grey square

1 Like

Your comment inspired me to do some digging. Pop!_OS has a feature where you can turn off window title bars. Turns out, if this feature is enabled, winit fails to show anything.

Thanks

Edit: Okay, I found an actual solution to this. The problem was that the program didn't properly handle resizing.

Event::WindowEvent{event: e, ..} => match e {
                WindowEvent::CloseRequested => 
                    *control_flow = ControlFlow::Exit,

                WindowEvent::Resized(new_size) => 
                    pixels.resize_surface(new_size.width, new_size.height),

                _ => {}
            },

Adding this to the program makes it work, even if window title bars are off.

Oh hey, I didn't see this earlier. (Honestly, I don't check the forum nearly as often as I should.)

That is an interesting issue you have stumbled upon. And this is the first time I've heard of Pop!_OS. I guess I shouldn't be surprised that the bare minimum example behaves uniquely with winit in that environment. I've noticed several instances of similar behavior with it on various platforms.

Anyway, I don't think this would have solved the initial problem, but I noticed that you have a bug in how you are creating your pixel buffer. You are passing the inner window size to Pixels::new(), which is almost certainly wrong. It looks like you want a 320x240 pixel buffer, not whatever the inner window size is. The code as provided creates a pixel buffer whose size depends on the display environment's DPI scaling factor. Pass an explicit size instead.

It's good that you handle resize events, now. The resize_surface method synchronizes the internal renderer and wgpu with the window surface. This is necessary any time the window size changes for any reason.

Ah, thanks for the advice!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.