use ranga::gpu::{GpuChain, GpuContext, gpu_brightness_contrast, gpu_invert};
use ranga::pixel::{PixelBuffer, PixelFormat};
fn main() {
match run() {
Ok(()) => {}
Err(e) => {
eprintln!("GPU example failed: {e}");
eprintln!("(This is expected if no GPU adapter is available.)");
std::process::exit(1);
}
}
}
fn run() -> ranga::Result<()> {
let mut ctx = GpuContext::new().map_err(ranga::RangaError::from)?;
println!("GPU adapter: {}", ctx.adapter_name());
println!("Backend: {}", ctx.backend_name());
let w = 4u32;
let h = 4u32;
let pixel_count = (w * h) as usize;
let mut data = Vec::with_capacity(pixel_count * 4);
for i in 0..pixel_count {
let t = i as f32 / (pixel_count - 1) as f32;
let v = (t * 255.0) as u8;
data.extend_from_slice(&[v, v / 2, 255 - v, 255]);
}
let mut buf = PixelBuffer::new(data, w, h, PixelFormat::Rgba8).unwrap();
println!("\nOriginal (first 4 pixels):");
print_pixels(&buf, 4);
gpu_invert(&mut ctx, &mut buf)?;
println!("\nAfter gpu_invert:");
print_pixels(&buf, 4);
gpu_brightness_contrast(&mut ctx, &mut buf, 0.1, 1.3)?;
println!("\nAfter gpu_brightness_contrast(+0.1, 1.3x):");
print_pixels(&buf, 4);
let chain_data: Vec<u8> = (0..pixel_count)
.flat_map(|i| {
let t = i as f32 / (pixel_count - 1) as f32;
let v = (t * 255.0) as u8;
[v, v / 2, 255 - v, 255]
})
.collect();
let chain_input = PixelBuffer::new(chain_data, w, h, PixelFormat::Rgba8).unwrap();
println!("\nGpuChain input (first 4 pixels):");
print_pixels(&chain_input, 4);
let chain = GpuChain::new(&mut ctx, &chain_input)?;
let result = chain
.invert()? .grayscale()? .finish()?;
println!("\nGpuChain result (invert -> grayscale):");
print_pixels(&result, 4);
let all_gray = result
.data()
.chunks_exact(4)
.all(|p| p[0] == p[1] && p[1] == p[2]);
println!("All pixels are grayscale: {all_gray}");
Ok(())
}
fn print_pixels(buf: &PixelBuffer, n: usize) {
for (i, pixel) in buf.data().chunks_exact(4).enumerate().take(n) {
println!(
" pixel[{i}]: R={:>3} G={:>3} B={:>3} A={:>3}",
pixel[0], pixel[1], pixel[2], pixel[3]
);
}
}