fennel_core/resources/
image.rs1use std::{path::PathBuf, rc::Rc};
2
3use image::ImageReader;
4use sdl3::{render::Texture, pixels::PixelFormat, surface::Surface};
5
6use crate::{graphics::Graphics, resources::LoadableResource};
7
8
9unsafe impl Send for Image {}
10unsafe impl Sync for Image {}
11
12#[derive(Clone)]
15pub struct Image {
16 pub name: String,
18 pub texture: Rc<Texture<'static>>,
20 pub width: u32,
22 pub height: u32,
24}
25
26impl Image {
27 pub fn load_from_surface(
28 name: String,
29 graphics: &mut Graphics,
30 surface: Surface,
31 ) -> anyhow::Result<Box<dyn LoadableResource>> {
32 let texture = unsafe {
33 std::mem::transmute::<sdl3::render::Texture<'_>, sdl3::render::Texture<'static>>(
34 graphics
35 .texture_creator
36 .create_texture_from_surface(&surface)?,
37 )
38 };
39
40 Ok(Box::new(Self {
41 name,
42 texture: Rc::new(texture),
43 width: surface.width(),
44 height: surface.height(),
45 }))
46 }
47}
48
49impl LoadableResource for Image {
50 fn load(
52 path: PathBuf,
53 name: String,
54 graphics: &mut Graphics,
55 _size: Option<f32>,
56 ) -> anyhow::Result<Box<dyn LoadableResource>> {
57 let img = ImageReader::open(&path)?.decode()?;
58 let mut buffer = img.to_rgba8().into_raw();
59 let surface = sdl3::surface::Surface::from_data(
60 &mut buffer,
61 img.width(),
62 img.height(),
63 img.width() * 4,
64 PixelFormat::RGBA32,
65 )?;
66
67 let texture = unsafe {
68 std::mem::transmute::<sdl3::render::Texture<'_>, sdl3::render::Texture<'static>>(
69 graphics
70 .texture_creator
71 .create_texture_from_surface(surface)?,
72 )
73 };
74
75 Ok(Box::new(Self {
76 name,
77 texture: Rc::new(texture),
78 width: img.width(),
79 height: img.height(),
80 }))
81 }
82
83 fn name(&self) -> String {
84 self.name.clone()
85 }
86}