1use crate::core::texture::*;
2pub struct Texture3D {
6 context: Context,
7 id: crate::context::Texture,
8 width: u32,
9 height: u32,
10 depth: u32,
11 number_of_mip_maps: u32,
12 data_byte_size: usize,
13}
14
15impl Texture3D {
16 pub fn new(context: &Context, cpu_texture: &CpuTexture3D) -> Self {
22 match cpu_texture.data {
23 TextureData::RU8(ref data) => Self::new_with_data(context, cpu_texture, data),
24 TextureData::RgU8(ref data) => Self::new_with_data(context, cpu_texture, data),
25 TextureData::RgbU8(ref data) => Self::new_with_data(context, cpu_texture, data),
26 TextureData::RgbaU8(ref data) => Self::new_with_data(context, cpu_texture, data),
27 TextureData::RF16(ref data) => Self::new_with_data(context, cpu_texture, data),
28 TextureData::RgF16(ref data) => Self::new_with_data(context, cpu_texture, data),
29 TextureData::RgbF16(ref data) => Self::new_with_data(context, cpu_texture, data),
30 TextureData::RgbaF16(ref data) => Self::new_with_data(context, cpu_texture, data),
31 TextureData::RF32(ref data) => Self::new_with_data(context, cpu_texture, data),
32 TextureData::RgF32(ref data) => Self::new_with_data(context, cpu_texture, data),
33 TextureData::RgbF32(ref data) => Self::new_with_data(context, cpu_texture, data),
34 TextureData::RgbaF32(ref data) => Self::new_with_data(context, cpu_texture, data),
35 }
36 }
37
38 fn new_with_data<T: TextureDataType>(
39 context: &Context,
40 cpu_texture: &CpuTexture3D,
41 data: &[T],
42 ) -> Self {
43 let mut texture = Self::new_empty::<T>(
44 context,
45 cpu_texture.width,
46 cpu_texture.height,
47 cpu_texture.depth,
48 cpu_texture.min_filter,
49 cpu_texture.mag_filter,
50 cpu_texture.mipmap,
51 cpu_texture.wrap_s,
52 cpu_texture.wrap_t,
53 cpu_texture.wrap_r,
54 );
55 texture.fill(data);
56 texture
57 }
58
59 pub fn new_empty<T: TextureDataType>(
65 context: &Context,
66 width: u32,
67 height: u32,
68 depth: u32,
69 min_filter: Interpolation,
70 mag_filter: Interpolation,
71 mipmap: Option<Mipmap>,
72 wrap_s: Wrapping,
73 wrap_t: Wrapping,
74 wrap_r: Wrapping,
75 ) -> Self {
76 let id = generate(context);
77 let number_of_mip_maps =
78 calculate_number_of_mip_maps::<T>(mipmap, width, height, Some(depth));
79 let texture = Self {
80 context: context.clone(),
81 id,
82 width,
83 height,
84 depth,
85 number_of_mip_maps,
86 data_byte_size: std::mem::size_of::<T>(),
87 };
88 texture.bind();
89 set_parameters(
90 context,
91 crate::context::TEXTURE_3D,
92 min_filter,
93 mag_filter,
94 if number_of_mip_maps == 1 {
95 None
96 } else {
97 mipmap
98 },
99 wrap_s,
100 wrap_t,
101 Some(wrap_r),
102 );
103 unsafe {
104 context.tex_storage_3d(
105 crate::context::TEXTURE_3D,
106 number_of_mip_maps as i32,
107 T::internal_format(),
108 width as i32,
109 height as i32,
110 depth as i32,
111 );
112 }
113 texture.generate_mip_maps();
114 texture
115 }
116
117 pub fn fill<T: TextureDataType>(&mut self, data: &[T]) {
125 check_data_length::<T>(
126 self.width,
127 self.height,
128 self.depth,
129 self.data_byte_size,
130 data.len(),
131 );
132 self.bind();
133 unsafe {
134 self.context.tex_sub_image_3d(
135 crate::context::TEXTURE_3D,
136 0,
137 0,
138 0,
139 0,
140 self.width as i32,
141 self.height as i32,
142 self.depth as i32,
143 format_from_data_type::<T>(),
144 T::data_type(),
145 crate::context::PixelUnpackData::Slice(to_byte_slice(data)),
146 );
147 }
148 self.generate_mip_maps();
149 }
150
151 pub fn width(&self) -> u32 {
153 self.width
154 }
155
156 pub fn height(&self) -> u32 {
158 self.height
159 }
160
161 pub fn depth(&self) -> u32 {
163 self.depth
164 }
165
166 pub fn number_of_mip_maps(&self) -> u32 {
168 self.number_of_mip_maps
169 }
170
171 fn generate_mip_maps(&self) {
172 if self.number_of_mip_maps > 1 {
173 self.bind();
174 unsafe {
175 self.context.generate_mipmap(crate::context::TEXTURE_3D);
176 }
177 }
178 }
179 pub(in crate::core) fn bind(&self) {
180 unsafe {
181 self.context
182 .bind_texture(crate::context::TEXTURE_3D, Some(self.id));
183 }
184 }
185}
186
187impl Drop for Texture3D {
188 fn drop(&mut self) {
189 unsafe {
190 self.context.delete_texture(self.id);
191 }
192 }
193}