use std::{path::PathBuf, rc::Rc};
use image::ImageReader;
use sdl3::{render::Texture, pixels::PixelFormat, surface::Surface};
use crate::{graphics::Graphics, resources::LoadableResource};
unsafe impl Send for Image {}
unsafe impl Sync for Image {}
#[derive(Clone)]
pub struct Image {
pub name: String,
pub texture: Rc<Texture<'static>>,
pub width: u32,
pub height: u32,
}
impl Image {
pub fn load_from_surface(
name: String,
graphics: &mut Graphics,
surface: Surface,
) -> anyhow::Result<Box<dyn LoadableResource>> {
let texture = unsafe {
std::mem::transmute::<sdl3::render::Texture<'_>, sdl3::render::Texture<'static>>(
graphics
.texture_creator
.create_texture_from_surface(&surface)?,
)
};
Ok(Box::new(Self {
name,
texture: Rc::new(texture),
width: surface.width(),
height: surface.height(),
}))
}
}
impl LoadableResource for Image {
fn load(
path: PathBuf,
name: String,
graphics: &mut Graphics,
_size: Option<f32>,
) -> anyhow::Result<Box<dyn LoadableResource>> {
let img = ImageReader::open(&path)?.decode()?;
let mut buffer = img.to_rgba8().into_raw();
let surface = sdl3::surface::Surface::from_data(
&mut buffer,
img.width(),
img.height(),
img.width() * 4,
PixelFormat::RGBA32,
)?;
let texture = unsafe {
std::mem::transmute::<sdl3::render::Texture<'_>, sdl3::render::Texture<'static>>(
graphics
.texture_creator
.create_texture_from_surface(surface)?,
)
};
Ok(Box::new(Self {
name,
texture: Rc::new(texture),
width: img.width(),
height: img.height(),
}))
}
fn name(&self) -> String {
self.name.clone()
}
}