luminance/backend/
texture.rs

1//! Texture backend interface.
2//!
3//! This interface defines the low-level API textures must implement to be usable.
4//!
5//! In order to add support for textures, you have to implement two traits:
6//!
7//! - [`TextureBase`], which is a _type family_ providing the backend representation of a texture. This is needed so
8//!   that other part of the crate don’t have to rely on a too abstraction.
9//! - The rest of the abstraction, bigger, is [`Texture`].
10//!
11//! You will have to implement both traits to be able to use textures.
12
13use crate::{
14  pixel::Pixel,
15  texture::{Dimensionable, Sampler, TexelUpload, TextureError},
16};
17
18/// Type family giving the backend representation type.
19///
20/// This type family is type-erased: it doesn’t know whether the texture is a 2D texture or a 3D one or a cubemap.
21pub unsafe trait TextureBase {
22  /// Backend representation of a texture.
23  type TextureRepr;
24}
25
26/// Texture interface.
27///
28/// Implementing this trait requires implementing [`TextureBase`].
29///
30/// `D` is the _dimension_ of the texture, and must then implement [`Dimensionable`]. `P` is the format of the carried
31/// pixels and must then implement [`Pixel`].
32pub unsafe trait Texture<D, P>: TextureBase
33where
34  D: Dimensionable,
35  P: Pixel,
36{
37  /// Create a new texture.
38  unsafe fn new_texture(
39    &mut self,
40    size: D::Size,
41    sampler: Sampler,
42    texels: TexelUpload<[P::Encoding]>,
43  ) -> Result<Self::TextureRepr, TextureError>;
44
45  /// Create a new texture from raw texels.
46  unsafe fn new_texture_raw(
47    &mut self,
48    size: D::Size,
49    sampler: Sampler,
50    texels: TexelUpload<[P::RawEncoding]>,
51  ) -> Result<Self::TextureRepr, TextureError>;
52
53  /// Get the number of mimaps associated with the texture.
54  unsafe fn mipmaps(texture: &Self::TextureRepr) -> usize;
55
56  /// Upload texels to a part of a texture.
57  ///
58  /// This method will use the input texels and will copy them everywhere in the part formed with `offset` and `size`. For
59  /// instance, for 2D textures, `offset` and `size` form a rectangle: that rectangle of pixels will be filled with the
60  /// provided input texels.
61  unsafe fn upload_part(
62    texture: &mut Self::TextureRepr,
63    offset: D::Offset,
64    size: D::Size,
65    texels: TexelUpload<[P::Encoding]>,
66  ) -> Result<(), TextureError>;
67
68  /// Upload texels to a whole texture.
69  ///
70  /// This method is similar to [`Texture::upload_part`] but instead of uploading a part of it, it will upload to the
71  /// whole texture at once. The size will match the size of the texture so you do not have to cache it and simply can use
72  /// the input `size` value.
73  unsafe fn upload(
74    texture: &mut Self::TextureRepr,
75    size: D::Size,
76    texels: TexelUpload<[P::Encoding]>,
77  ) -> Result<(), TextureError>;
78
79  /// Upload texels to a part of a texture.
80  ///
81  /// This method will use the input texels and will copy them everywhere in the part formed with `offset` and `size`. For
82  /// instance, for 2D textures, `offset` and `size` form a rectangle: that rectangle of pixels will be filled with the
83  /// provided input texels.
84  ///
85  /// > This is very similar to [`Texture::upload_part_raw`], but the key difference is that this method works with the
86  /// > _raw encoding_ of the texels, which is often the case with crates that provide you with a contiguous array of raw
87  /// > data instead of rich texels.
88  unsafe fn upload_part_raw(
89    texture: &mut Self::TextureRepr,
90    offset: D::Offset,
91    size: D::Size,
92    texels: TexelUpload<[P::RawEncoding]>,
93  ) -> Result<(), TextureError>;
94
95  /// Upload texels to a whole texture.
96  ///
97  /// This method is similar to [`Texture::upload_part`] but instead of uploading a part of it, it will upload to the
98  /// whole texture at once. The size will match the size of the texture so you do not have to cache it and simply can use
99  /// the input `size` value.
100  ///
101  /// > This is very similar to [`Texture::upload`], but the key difference is that this method works with the _raw
102  /// > encoding_ of the texels, which is often the case with crates that provide you with a contiguous array of raw
103  /// > data instead of rich texels.
104  unsafe fn upload_raw(
105    texture: &mut Self::TextureRepr,
106    size: D::Size,
107    texels: TexelUpload<[P::RawEncoding]>,
108  ) -> Result<(), TextureError>;
109
110  /// Get a copy of the raw texels stored in the texture.
111  ///
112  /// `size` will match the actual size of the texture, you do not need to cache it.
113  unsafe fn get_raw_texels(
114    texture: &Self::TextureRepr,
115    size: D::Size,
116  ) -> Result<Vec<P::RawEncoding>, TextureError>
117  where
118    P::RawEncoding: Copy + Default;
119
120  /// Resize the texture.
121  ///
122  /// Once the texture is resized, pixels are left in an unknown state. Depending on the implementation of the backend,
123  /// it is likely that texels will either be old ones, or completely random data.
124  unsafe fn resize(
125    texture: &mut Self::TextureRepr,
126    size: D::Size,
127    texel: TexelUpload<[P::Encoding]>,
128  ) -> Result<(), TextureError>;
129
130  /// Resize the texture with raw texels.
131  ///
132  /// Once the texture is resized, pixels are left in an unknown state. Depending on the implementation of the backend,
133  /// it is likely that texels will either be old ones, or completely random data.
134  unsafe fn resize_raw(
135    texture: &mut Self::TextureRepr,
136    size: D::Size,
137    texel: TexelUpload<[P::RawEncoding]>,
138  ) -> Result<(), TextureError>;
139}