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
use crate::prelude::*;
use crate::Context;
use crate::data::as_u8_slice;
use crate::data::as_u8_mut_slice;
use glow::HasContext;
use crate::TextureFormat;
use crate::ColorFormat;
use crate::Type;
use crate::Texture;
#[derive(Shrinkwrap)]
#[shrinkwrap(mutable)]
pub struct Texture3D {
#[shrinkwrap(main_field)]
pub texture : Texture,
dimensions : (usize,usize,usize)
}
impl Texture3D {
fn new(context:&Context) -> Self {
let format = TextureFormat::new(ColorFormat::RGBA, Type::F32);
let texture = Texture::new(context,format,glow::TEXTURE_3D);
let dimensions = (0,0,0);
Self {texture,dimensions}
}
pub fn dimensions(&self) -> (usize, usize, usize) {
self.dimensions
}
pub fn allocate
(context:&Context, dimensions: (usize, usize, usize), format: &TextureFormat) -> Self {
let mut texture = Self::new(context);
texture.reallocate(dimensions, &format);
texture
}
pub fn from_data<T>
(context:&Context, dimensions: (usize, usize, usize), format: &TextureFormat, data: &[T], data_format: &TextureFormat) -> Self {
let mut texture = Self::new(context);
texture.set_data(dimensions, &format, data, &data_format);
texture
}
pub fn reallocate(&mut self, dimensions: (usize, usize, usize), format: &TextureFormat) {
self.dimensions = dimensions;
self.format = format.clone();
self.bind();
unsafe {
let tex_type = self.typ();
let internal_format = format.internal_format();
self.gl.tex_storage_3d(tex_type, 1, internal_format, dimensions.0 as i32, dimensions.1 as
i32, dimensions.2 as i32);
}
}
pub fn set_data<T>(&mut self, dimensions: (usize, usize, usize), format: &TextureFormat,
data: &[T], data_format: &TextureFormat) {
self.dimensions = dimensions;
self.format = format.clone();
self.bind();
unsafe {
let (color, ty) = data_format.get_format_type();
let internal_format = format.internal_format() as i32;
let width = dimensions.0 as i32;
let height = dimensions.1 as i32;
let depth = dimensions.2 as i32;
let pixels = Some(as_u8_slice(data));
self.gl.tex_image_3d(self.typ(),0,internal_format,width,height,depth,0,color,ty,pixels);
}
}
pub fn data<T>(&self) -> Vec<T> {
let (width,height,depth) = self.dimensions();
let color_size = self.format().color_format().size();
let capacity = width * height * depth * color_size;
let mut data : Vec<T> = Vec::with_capacity(capacity);
let gl = &self.gl;
unsafe {
data.set_len(capacity);
let fb = gl.create_framebuffer().expect("Couldn't create Framebuffer");
for depth in 0..depth {
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(fb));
gl.framebuffer_texture_layer(glow::FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
Some(self.resource()),
0,
depth as i32);
let (format, ty) = self.format().get_format_type();
let offset = width * height * depth * color_size;
let pixels = glow::PixelPackData::Slice(&mut as_u8_mut_slice(data.as_mut())[offset..]);
let (width, height, _) = self.dimensions();
gl.read_pixels(0, 0, width as i32, height as i32, format, ty, pixels);
}
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
gl.delete_framebuffer(fb);
}
data
}
}