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}