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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use gl::types::*;
use std::path::Path;
pub struct Texture {
id: GLuint,
}
impl Texture {
/// Generate a new OpenGL texture handle and create a `Texture` instance wrapping it.
pub fn new() -> Self {
let mut id = 0;
unsafe {
gl::GenTextures(1, &mut id);
}
Self { id }
}
/// Bind the texture to the given active texture unit.
///
/// # OpenGL Functions
///
/// This function is a wrapper around `glActiveTexture(unit)` and `glBindTexture(GL_TEXTURE_2D, id)`.
/// It binds the texture to the given active texture unit.
///
/// # Arguments
///
/// * `unit` - The active texture unit to bind the texture to.
pub fn bind(&self, unit: GLenum) {
unsafe {
gl::ActiveTexture(unit);
gl::BindTexture(gl::TEXTURE_2D, self.id);
}
}
/// Set a parameter of the texture.
///
/// # OpenGL Functions
///
/// This function is a wrapper around `glTexParameteri(GL_TEXTURE_2D, param, value)`.
/// It sets a parameter of the texture.
///
/// # Arguments
///
/// * `param` - The parameter to set. See the OpenGL documentation for the list of possible parameters.
/// * `value` - The value to set the parameter to.
pub fn set_parameters(&self, param: GLenum, value: GLint) {
unsafe {
gl::TexParameteri(gl::TEXTURE_2D, param, value);
}
}
/// Load a texture from a file into the texture object.
///
/// # Errors
///
/// This function will return an error if the image cannot be opened or decoded.
///
/// # OpenGL Functions
///
/// This function is a wrapper around `glTexImage2D(GL_TEXTURE_2D, 0, gl::RGBA, width, height, 0, gl::RGBA, gl::UNSIGNED_BYTE, img.as_ptr() as *const _)`.
/// It loads a texture from a file into the texture object.
///
/// # Arguments
///
/// * `path` - The path to the image file to load.
///
/// # Returns
///
/// A `Result` containing a unit value if successful, or an error string otherwise.
pub fn load_from_file<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
let img = image::open(path).map_err(|e| e.to_string())?;
let img = img.to_rgba8();
let (width, height) = img.dimensions();
unsafe {
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGBA as i32,
width as i32,
height as i32,
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
img.as_ptr() as *const _,
);
gl::GenerateMipmap(gl::TEXTURE_2D);
}
Ok(())
}
/// Load a texture from raw data into the texture object.
///
/// # OpenGL Functions
///
/// This function is a wrapper around `glTexImage2D(GL_TEXTURE_2D, 0, gl::RGBA, width, height, 0, gl::RGBA, gl::UNSIGNED_BYTE, data.as_ptr() as *const _)`.
/// It loads a texture from raw data into the texture object.
///
/// # Arguments
///
/// * `width` - The width of the texture in pixels.
/// * `height` - The height of the texture in pixels.
/// * `data` - The raw pixel data to load into the texture.
pub fn load_from_data(&self, width: u32, height: u32, data: &[u8]) {
unsafe {
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGBA as i32,
width as i32,
height as i32,
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
data.as_ptr() as *const _,
);
gl::GenerateMipmap(gl::TEXTURE_2D);
}
}
}
impl Drop for Texture {
fn drop(&mut self) {
unsafe {
gl::DeleteTextures(1, &self.id);
}
}
}