1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use gl;
use image;
use image::DynamicImage::*;
use image::GenericImageView;
use log::{debug, error};
use std::os::raw::c_void;
use std::path::Path;
pub struct Texture {
pub id: u32,
}
impl Texture {
pub fn new(path: &str) -> Texture {
unsafe { Texture { id: load_texture(path) } }
}
}
impl Default for Texture {
fn default() -> Texture {
Texture { id: 0 }
}
}
unsafe fn load_texture(path: &str) -> u32 {
let path_str = format!("{}{}", "res/textures/", path);
debug!("New from {}", path_str);
let path = Path::new(&path_str);
let mut tex_id = 0;
gl::GenTextures(1, &mut tex_id);
let img = image::open(&path).expect("ERROR: Failed to load texture!").flipv();
let image_format = match img {
ImageRgb8(_) => {
debug!("Format: RGB8");
gl::RGB
}
ImageRgba8(_) => {
debug!("Format: RGBA8");
gl::RGBA
}
_ => {
error!("Format wrong");
panic!("ERROR: Wrong image format!")
}
};
let data = img.raw_pixels();
gl::BindTexture(gl::TEXTURE_2D, tex_id);
gl::TexImage2D(
gl::TEXTURE_2D,
0,
image_format as i32,
img.width() as i32,
img.height() as i32,
0,
image_format,
gl::UNSIGNED_BYTE,
&data[0] as *const u8 as *const c_void,
);
gl::GenerateMipmap(gl::TEXTURE_2D);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT 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);
debug!("id:{}, width:{}px, height:{}px", tex_id, img.width(), img.height());
tex_id
}
impl Drop for Texture {
fn drop(&mut self) {
unsafe {
gl::DeleteTextures(1, self.id as *const u32);
}
}
}