30 } |
30 } |
31 } |
31 } |
32 |
32 |
33 #[derive(Debug)] |
33 #[derive(Debug)] |
34 pub struct Texture2D { |
34 pub struct Texture2D { |
35 pub handle: u32, |
35 pub handle: Option<NonZeroU32>, |
36 } |
36 } |
37 |
37 |
38 impl Drop for Texture2D { |
38 impl Drop for Texture2D { |
39 fn drop(&mut self) { |
39 fn drop(&mut self) { |
40 if self.handle != 0 { |
40 if let Some(handle) = self.handle { |
41 unsafe { |
41 unsafe { |
42 gl::DeleteTextures(1, &self.handle); |
42 gl::DeleteTextures(1, &handle.get()); |
43 } |
43 } |
44 } |
44 } |
|
45 } |
|
46 } |
|
47 |
|
48 fn new_texture() -> Option<NonZeroU32> { |
|
49 let mut handle = 0; |
|
50 unsafe { |
|
51 gl::GenTextures(1, &mut handle); |
|
52 } |
|
53 NonZeroU32::new(handle) |
|
54 } |
|
55 |
|
56 fn tex_params(filter: u32) { |
|
57 unsafe { |
|
58 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); |
|
59 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); |
|
60 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, filter as i32); |
|
61 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, filter as i32); |
45 } |
62 } |
46 } |
63 } |
47 |
64 |
48 impl Texture2D { |
65 impl Texture2D { |
|
66 pub fn new(size: Size, internal_format: u32, format: u32, ty: u32, filter: u32) -> Self { |
|
67 if let Some(handle) = new_texture() { |
|
68 unsafe { |
|
69 gl::BindTexture(gl::TEXTURE_2D, handle.get()); |
|
70 gl::TexImage2D( |
|
71 gl::TEXTURE_2D, |
|
72 0, |
|
73 internal_format as i32, |
|
74 size.width as i32, |
|
75 size.height as i32, |
|
76 0, |
|
77 format as u32, |
|
78 ty, |
|
79 std::ptr::null(), |
|
80 ) |
|
81 } |
|
82 |
|
83 tex_params(filter); |
|
84 Self { |
|
85 handle: Some(handle), |
|
86 } |
|
87 } else { |
|
88 Self { handle: None } |
|
89 } |
|
90 } |
|
91 |
49 pub fn with_data( |
92 pub fn with_data( |
50 data: &[u8], |
93 data: &[u8], |
51 data_stride: u32, |
94 data_stride: u32, |
52 width: u32, |
95 size: Size, |
53 height: u32, |
|
54 internal_format: u32, |
96 internal_format: u32, |
55 format: u32, |
97 format: u32, |
56 ty: u32, |
98 ty: u32, |
57 filter: u32, |
99 filter: u32, |
58 ) -> Self { |
100 ) -> Self { |
59 let mut handle = 0; |
101 if let Some(handle) = new_texture() { |
60 |
102 unsafe { |
61 unsafe { |
103 gl::BindTexture(gl::TEXTURE_2D, handle.get()); |
62 gl::GenTextures(1, &mut handle); |
104 gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); |
63 |
105 gl::TexImage2D( |
64 gl::BindTexture(gl::TEXTURE_2D, handle); |
106 gl::TEXTURE_2D, |
65 gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); |
107 0, |
66 gl::TexImage2D( |
108 internal_format as i32, |
67 gl::TEXTURE_2D, |
109 size.width as i32, |
68 0, |
110 size.height as i32, |
69 internal_format as i32, |
111 0, |
70 width as i32, |
112 format as u32, |
71 height as i32, |
113 ty, |
72 0, |
114 data.as_ptr() as *const _, |
73 format as u32, |
115 ) |
74 ty, |
116 } |
75 data.as_ptr() as *const _, |
117 |
76 ); |
118 tex_params(filter); |
77 |
119 Self { |
78 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); |
120 handle: Some(handle), |
79 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); |
121 } |
80 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, filter as i32); |
122 } else { |
81 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, filter as i32); |
123 Self { handle: None } |
82 } |
124 } |
83 |
|
84 Texture2D { handle } |
|
85 } |
125 } |
86 |
126 |
87 pub fn update(&self, region: Rect, data: &[u8], data_stride: u32, format: u32, ty: u32) { |
127 pub fn update(&self, region: Rect, data: &[u8], data_stride: u32, format: u32, ty: u32) { |
88 unsafe { |
128 if let Some(handle) = self.handle { |
89 gl::BindTexture(gl::TEXTURE_2D, self.handle); |
129 unsafe { |
90 gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); |
130 gl::BindTexture(gl::TEXTURE_2D, handle.get()); |
91 gl::TexSubImage2D( |
131 gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); |
92 gl::TEXTURE_2D, |
132 gl::TexSubImage2D( |
93 0, // texture level |
133 gl::TEXTURE_2D, |
94 region.left(), // texture region |
134 0, // texture level |
95 region.top(), |
135 region.left(), // texture region |
96 region.width() as i32 - 1, |
136 region.top(), |
97 region.height() as i32 - 1, |
137 region.right(), |
98 format, // data format |
138 region.bottom(), |
99 ty, // data type |
139 format, // data format |
100 data.as_ptr() as *const _, // data ptr |
140 ty, // data type |
101 ); |
141 data.as_ptr() as *const _, // data ptr |
|
142 ); |
|
143 } |
102 } |
144 } |
103 } |
145 } |
104 } |
146 } |
105 |
147 |
106 #[derive(Debug)] |
148 #[derive(Debug)] |