glium/texture/
pixel_buffer.rs

1/*!
2Pixel buffers are buffers that contain two-dimensional texture data.
3
4Contrary to textures, pixel buffers are stored in a client-defined format. They are used
5to transfer data to or from the video memory, before or after being turned into a texture.
6*/
7use std::borrow::Cow;
8use std::cell::Cell;
9use std::ops::{Deref, DerefMut};
10
11use crate::backend::Facade;
12
13use crate::GlObject;
14use crate::buffer::{ReadError, Buffer, BufferType, BufferMode};
15use crate::gl;
16
17use crate::texture::PixelValue;
18use crate::texture::Texture2dDataSink;
19
20/// Buffer that stores the content of a texture.
21///
22/// The generic type represents the type of pixels that the buffer contains.
23pub struct PixelBuffer<T> where T: PixelValue {
24    buffer: Buffer<[T]>,
25    dimensions: Cell<Option<(u32, u32)>>,
26}
27
28impl<T> PixelBuffer<T> where T: PixelValue {
29    /// Builds a new buffer with an uninitialized content.
30    #[inline]
31    pub fn new_empty<F: ?Sized>(facade: &F, capacity: usize) -> PixelBuffer<T> where F: Facade {
32        PixelBuffer {
33            buffer: Buffer::empty_array(facade, BufferType::PixelPackBuffer, capacity,
34                                            BufferMode::Default).unwrap(),
35            dimensions: Cell::new(None),
36        }
37    }
38
39    /// Reads the content of the pixel buffer.
40    #[inline]
41    pub fn read_as_texture_2d<S>(&self) -> Result<S, ReadError> where S: Texture2dDataSink<T> {
42        let dimensions = self.dimensions.get().expect("The pixel buffer is empty");
43        let data = self.read()?;
44        Ok(S::from_raw(Cow::Owned(data), dimensions.0, dimensions.1))
45    }
46}
47
48impl<T> Deref for PixelBuffer<T> where T: PixelValue {
49    type Target = Buffer<[T]>;
50
51    #[inline]
52    fn deref(&self) -> &Buffer<[T]> {
53        &self.buffer
54    }
55}
56
57impl<T> DerefMut for PixelBuffer<T> where T: PixelValue {
58    #[inline]
59    fn deref_mut(&mut self) -> &mut Buffer<[T]> {
60        &mut self.buffer
61    }
62}
63
64// TODO: rework this
65impl<T> GlObject for PixelBuffer<T> where T: PixelValue {
66    type Id = gl::types::GLuint;
67
68    #[inline]
69    fn get_id(&self) -> gl::types::GLuint {
70        self.buffer.get_id()
71    }
72}
73
74// TODO: remove this hack
75#[doc(hidden)]
76#[inline]
77pub fn store_infos<T>(b: &PixelBuffer<T>, dimensions: (u32, u32)) where T: PixelValue {
78    b.dimensions.set(Some(dimensions));
79}