use std::convert::TryInto; use std::ffi::c_void; use std::fs::File; use std::path::Path; pub struct Texture { id: u32, } impl Texture { pub fn from_file

(name: P) -> Texture where P: AsRef { let decoder = png::Decoder::new (File::open (name).unwrap ()); let (info, mut reader) = decoder.read_info ().unwrap (); // Allocate the output buffer. let mut buf = vec! [0; info.buffer_size ()]; // Read the next frame. Currently this function should only called once. // The default options reader.next_frame (&mut buf).unwrap (); let id = unsafe { let mut id = 0; gl::GenTextures (1, &mut id); assert! (id != 0); let width = info.width.try_into ().unwrap (); let height = info.height.try_into ().unwrap (); let format = match info.color_type { png::ColorType::RGB => gl::RGB, png::ColorType::RGBA => gl::RGBA, _ => panic! ("ColorType not implemented"), }; gl::BindTexture (gl::TEXTURE_2D, id); gl::TexImage2D (gl::TEXTURE_2D, 0, format.try_into ().unwrap (), width, height, 0, format, gl::UNSIGNED_BYTE, &buf [0] as *const u8 as *const c_void); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32); id }; Texture { id, } } pub fn bind (&self) { unsafe { gl::BindTexture (gl::TEXTURE_2D, self.id); } } } impl Drop for Texture { fn drop (&mut self) { if self.id == 0 { return; } unsafe { gl::DeleteTextures (1, &self.id); } self.id = 0; } }