nannou
nannou copied to clipboard
Grayscale textures (LumaU8) showing up in red
I am trying to render a calibration background, but the black and white marker textures are being drawn in red instead of white for some reason.
I don't think it's a problem with wgpu because I got it to work in bevy earlier.
This is a minimum reproducible version. I'm on MacOS with Arm64 M1. These images were created with the opencv api.
use std::path::PathBuf;
use nannou::prelude::*;
struct Model {
marker: wgpu::Texture,
}
pub fn main() {
nannou::app(model).run();
}
fn model(app: &App) -> Model {
app.new_window().fullscreen().view(view).build().unwrap();
let marker =
wgpu::Texture::from_path(app, PathBuf::from("assets/markers/marker0.png")).unwrap();
Model { marker }
}
fn view(app: &App, model: &Model, frame: Frame) {
frame.clear(WHITE);
let draw = app.draw();
draw.texture(&model.marker).x_y(0., 0.).w_h(100., 100.);
draw.to_frame(app, &frame).unwrap();
}
Here is a screenshot of the app running
It seems to be related to images producted from numpy arrays with python's PIL library
This could be fixed by either rendering with a special shader for grayscale images, or since many other common formats like rgb8, bgr8 and rgb16 all have a clone and convert step, "unsupported" image types like Luma could be converted as well.
A PR would involved changing
// line 511 nannou_wgpu/src/texture/image.rs
pub fn load_texture_from_image(
device: &wgpu::Device,
queue: &wgpu::Queue,
usage: wgpu::TextureUsages,
image: &image::DynamicImage,
) -> wgpu::Texture {
use image::DynamicImage::*;
match image {
ImageLuma8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageLumaA8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageRgba8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageBgra8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageLuma16(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageLumaA16(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageRgba16(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageRgb8(_img) => {
let img = image.to_rgba8();
load_texture_from_image_buffer(device, queue, usage, &img)
}
ImageBgr8(_img) => {
let img = image.to_bgra8();
load_texture_from_image_buffer(device, queue, usage, &img)
}
ImageRgb16(_img) => {
let img = image.to_rgba16();
load_texture_from_image_buffer(device, queue, usage, &img)
}
}
}
pub fn load_texture_from_image(
device: &wgpu::Device,
queue: &wgpu::Queue,
usage: wgpu::TextureUsages,
image: &image::DynamicImage,
) -> wgpu::Texture {
use image::DynamicImage::*;
match image {
ImageRgba8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageBgra8(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageRgba16(img) => load_texture_from_image_buffer(device, queue, usage, img),
ImageRgb8(_img) => {
let img = image.to_rgba8();
load_texture_from_image_buffer(device, queue, usage, &img)
}
ImageBgr8(_img) => {
let img = image.to_bgra8();
load_texture_from_image_buffer(device, queue, usage, &img)
}
ImageRgb16(_img) => {
let img = image.to_rgba16();
load_texture_from_image_buffer(device, queue, usage, &img)
}
_ => {
let img = image.to_rgba8();
load_texture_from_image_buffer(device, queue, usage, &img)
}
}
}