1#[cfg(feature = "opengl")]
5pub mod gl;
6
7#[cfg(feature = "vulkan")]
9pub mod vk;
10
11#[cfg(feature = "wgpu")]
13pub mod wgpu;
14
15#[cfg(all(target_os = "windows", feature = "dxgi"))]
17pub mod dxgi;
18
19#[cfg(all(target_os = "windows", feature = "d3d9"))]
21pub mod d3d9;
22
23#[cfg(all(target_os = "windows", feature = "d3d11"))]
25pub mod d3d11;
26
27#[cfg(all(target_os = "windows", feature = "d3d12"))]
29pub mod d3d12;
30
31#[cfg(all(target_vendor = "apple", feature = "metal"))]
32pub mod metal;
33
34mod viewport;
35
36#[doc(hidden)]
37pub mod map;
38pub mod shader_features;
39
40pub use viewport::Viewport;
41
42use num_traits::{AsPrimitive, Num};
43use std::convert::Infallible;
44use std::ops::{Add, Sub};
45use std::str::FromStr;
46
47#[repr(u32)]
48#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50pub enum ImageFormat {
52 #[default]
53 Unknown = 0,
54
55 R8Unorm,
57 R8Uint,
58 R8Sint,
59 R8G8Unorm,
60 R8G8Uint,
61 R8G8Sint,
62 R8G8B8A8Unorm,
63 R8G8B8A8Uint,
64 R8G8B8A8Sint,
65 R8G8B8A8Srgb,
66
67 A2B10G10R10UnormPack32,
69 A2B10G10R10UintPack32,
70
71 R16Uint,
73 R16Sint,
74 R16Sfloat,
75 R16G16Uint,
76 R16G16Sint,
77 R16G16Sfloat,
78 R16G16B16A16Uint,
79 R16G16B16A16Sint,
80 R16G16B16A16Sfloat,
81
82 R32Uint,
84 R32Sint,
85 R32Sfloat,
86 R32G32Uint,
87 R32G32Sint,
88 R32G32Sfloat,
89 R32G32B32A32Uint,
90 R32G32B32A32Sint,
91 R32G32B32A32Sfloat,
92}
93
94#[repr(i32)]
95#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)]
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97pub enum FilterMode {
99 Linear = 0,
101
102 #[default]
103 Nearest,
105}
106
107impl FromStr for WrapMode {
108 type Err = Infallible;
109
110 fn from_str(s: &str) -> Result<Self, Self::Err> {
111 Ok(match s {
112 "clamp_to_border" => WrapMode::ClampToBorder,
113 "clamp_to_edge" => WrapMode::ClampToEdge,
114 "repeat" => WrapMode::Repeat,
115 "mirrored_repeat" => WrapMode::MirroredRepeat,
116 _ => WrapMode::ClampToBorder,
117 })
118 }
119}
120
121impl FromStr for FilterMode {
122 type Err = Infallible;
123
124 fn from_str(s: &str) -> Result<Self, Self::Err> {
125 Ok(match s {
126 "linear" => FilterMode::Linear,
127 "nearest" => FilterMode::Nearest,
128 _ => FilterMode::Nearest,
129 })
130 }
131}
132
133#[repr(i32)]
134#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)]
135#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
136pub enum WrapMode {
138 #[default]
139 ClampToBorder = 0,
141 ClampToEdge,
143 Repeat,
145 MirroredRepeat,
147}
148
149impl FromStr for ImageFormat {
150 type Err = Infallible;
151
152 fn from_str(s: &str) -> Result<Self, Self::Err> {
153 Ok(match s {
154 "UNKNOWN" => Self::Unknown,
155
156 "R8_UNORM" => Self::R8Unorm,
157 "R8_UINT" => Self::R8Uint,
158 "R8_SINT" => Self::R8Sint,
159 "R8G8_UNORM" => Self::R8G8Unorm,
160 "R8G8_UINT" => Self::R8Uint,
161 "R8G8_SINT" => Self::R8G8Sint,
162 "R8G8B8A8_UNORM" => Self::R8G8B8A8Unorm,
163 "R8G8B8A8_UINT" => Self::R8G8B8A8Uint,
164 "R8G8B8A8_SINT" => Self::R8G8B8A8Sint,
165 "R8G8B8A8_SRGB" => Self::R8G8B8A8Srgb,
166
167 "A2B10G10R10_UNORM_PACK32" => Self::A2B10G10R10UnormPack32,
168 "A2B10G10R10_UINT_PACK32" => Self::A2B10G10R10UintPack32,
169
170 "R16_UINT" => Self::R16Uint,
171 "R16_SINT" => Self::R16Sint,
172 "R16_SFLOAT" => Self::R16Sfloat,
173 "R16G16_UINT" => Self::R16G16Uint,
174 "R16G16_SINT" => Self::R16G16Sint,
175 "R16G16_SFLOAT" => Self::R16G16Sfloat,
176 "R16G16B16A16_UINT" => Self::R16G16B16A16Uint,
177 "R16G16B16A16_SINT" => Self::R16G16B16A16Sint,
178 "R16G16B16A16_SFLOAT" => Self::R16G16B16A16Sfloat,
179
180 "R32_UINT" => Self::R32Uint,
181 "R32_SINT" => Self::R32Sint,
182 "R32_SFLOAT" => Self::R32Sfloat,
183 "R32G32_UINT" => Self::R32G32Uint,
184 "R32G32_SINT" => Self::R32G32Sint,
185 "R32G32_SFLOAT" => Self::R32G32Sfloat,
186 "R32G32B32A32_UINT" => Self::R32G32B32A32Uint,
187 "R32G32B32A32_SINT" => Self::R32G32B32A32Sint,
188 "R32G32B32A32_SFLOAT" => Self::R32G32B32A32Sfloat,
189 _ => Self::Unknown,
190 })
191 }
192}
193
194#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
196#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
197pub struct Size<T> {
198 pub width: T,
199 pub height: T,
200}
201
202impl<T> Size<T> {
203 pub fn new(width: T, height: T) -> Self {
205 Size { width, height }
206 }
207}
208
209impl<T: AsPrimitive<f32>> Size<T> {
210 #[inline(always)]
212 pub fn aspect_ratio(&self) -> f32 {
213 self.width.as_() / self.height.as_()
214 }
215}
216
217impl<T: Sub<Output = T>> Sub for Size<T> {
218 type Output = Size<T>;
219
220 fn sub(self, rhs: Self) -> Self::Output {
221 Self {
222 width: self.width - rhs.width,
223 height: self.height - rhs.height,
224 }
225 }
226}
227
228impl<T: Sub<T, Output = T> + Copy> Sub<T> for Size<T> {
229 type Output = Size<T>;
230
231 fn sub(self, rhs: T) -> Self::Output {
232 Self {
233 width: self.width - rhs,
234 height: self.height - rhs,
235 }
236 }
237}
238
239impl<T: Add<Output = T>> Add for Size<T> {
240 type Output = Size<T>;
241
242 fn add(self, rhs: Self) -> Self::Output {
243 Self {
244 width: self.width + rhs.width,
245 height: self.height + rhs.height,
246 }
247 }
248}
249
250impl<T: Add<T, Output = T> + Copy> Add<T> for Size<T> {
251 type Output = Size<T>;
252
253 fn add(self, rhs: T) -> Self::Output {
254 Self {
255 width: self.width + rhs,
256 height: self.height + rhs,
257 }
258 }
259}
260
261impl<T> From<Size<T>> for [f32; 4]
262where
263 T: Copy + AsPrimitive<f32>,
264{
265 fn from(value: Size<T>) -> Self {
267 [
268 value.width.as_(),
269 value.height.as_(),
270 1.0 / value.width.as_(),
271 1.0 / value.height.as_(),
272 ]
273 }
274}
275
276pub trait GetSize<C: Num> {
278 type Error;
279 fn size(&self) -> Result<Size<C>, Self::Error>;
281}
282
283impl<T: GetSize<u32>> GetSize<f32> for T {
284 type Error = T::Error;
285
286 fn size(&self) -> Result<Size<f32>, Self::Error> {
287 let size = <T as GetSize<u32>>::size(self)?;
288 Ok(Size {
289 width: size.width as f32,
290 height: size.height as f32,
291 })
292 }
293}