chaos-framework 0.1.2

Game framework for creating games!
Documentation
use std::{collections::HashMap, ops::{Index, IndexMut}};

use gl::types::{GLint, GLsizei, GLuint, GLvoid};

use crate::Renderer;

#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
pub struct TextureHandle {
    pub id: usize,
}

impl<'a> Index<TextureHandle> for HashMap<TextureHandle, Texture<'a>> {
    type Output = Texture<'a>;

    fn index(&self, handle: TextureHandle) -> &Self::Output {
        self.get(&handle).expect("No entry found for key")
    }
}

impl<'a> IndexMut<TextureHandle> for HashMap<TextureHandle, Texture<'a>> {
    fn index_mut(&mut self, handle: TextureHandle) -> &mut Self::Output {
        self.get_mut(&handle).expect("No entry found for key")
    }
}

#[derive(PartialEq, Debug, Clone)]
pub enum Texture<'a> {
    Path(&'a str),
    Loaded(GLuint),
    None,
}

pub unsafe fn load_texture(path: &str) -> GLuint { 
    let img = image::open(path).expect("Failed to load image");
    
    let img = img.flipv();
    let width = img.width();
    let height = img.height();
    let raw_pixels = img.to_rgba8().into_raw();
    
    let mut texture: GLuint = 0;
    gl::GenTextures(1, &mut texture);
    gl::BindTexture(gl::TEXTURE_2D, texture);

    gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as GLint);
    gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as GLint);
    gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as GLint);
    gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as GLint);

    gl::TexImage2D(
        gl::TEXTURE_2D,
        0,
        gl::RGBA as GLint,
        width as GLsizei,
        height as GLsizei,
        0,
        gl::RGBA,
        gl::UNSIGNED_BYTE,
        raw_pixels.as_ptr() as *const GLvoid,
    );

    gl::GenerateMipmap(gl::TEXTURE_2D);

    texture
}

impl Renderer {
    pub fn add_texture(&mut self, path: &str) -> Option<TextureHandle> {
        let handle = TextureHandle {id: self.textures.len()};

        if self.textures.contains_key(&handle) {
            println!("Texture with handle {:?} already exists", handle);
            return None;
        }

        self.textures.insert(handle, unsafe {load_texture(path)});
        Some(handle)
    }

    pub fn destroy_texture(&mut self, handle: TextureHandle) {
        if self.textures.remove(&handle).is_some() {

        } else {
            println!("Failed to remove texture");
        }
    }
}

impl Drop for Texture<'_> {
    fn drop(&mut self) {
        unsafe {
            if let Texture::Loaded(id) = self {
                gl::DeleteTextures(1, id);
            }
        }
    }
}