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;
39pub mod string;
40
41pub use viewport::Viewport;
42
43use num_traits::{AsPrimitive, Num};
44use std::convert::Infallible;
45use std::ops::{Add, Sub};
46use std::str::FromStr;
47
48#[repr(u32)]
49#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
50#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51pub enum ImageFormat {
53 #[default]
54 Unknown = 0,
55
56 R8Unorm,
58 R8Uint,
59 R8Sint,
60 R8G8Unorm,
61 R8G8Uint,
62 R8G8Sint,
63 R8G8B8A8Unorm,
64 R8G8B8A8Uint,
65 R8G8B8A8Sint,
66 R8G8B8A8Srgb,
67
68 A2B10G10R10UnormPack32,
70 A2B10G10R10UintPack32,
71
72 R16Uint,
74 R16Sint,
75 R16Sfloat,
76 R16G16Uint,
77 R16G16Sint,
78 R16G16Sfloat,
79 R16G16B16A16Uint,
80 R16G16B16A16Sint,
81 R16G16B16A16Sfloat,
82
83 R32Uint,
85 R32Sint,
86 R32Sfloat,
87 R32G32Uint,
88 R32G32Sint,
89 R32G32Sfloat,
90 R32G32B32A32Uint,
91 R32G32B32A32Sint,
92 R32G32B32A32Sfloat,
93}
94
95#[repr(i32)]
96#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)]
97#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
98pub enum FilterMode {
100 Linear = 0,
102
103 #[default]
104 Nearest,
106}
107
108impl FromStr for WrapMode {
109 type Err = Infallible;
110
111 fn from_str(s: &str) -> Result<Self, Self::Err> {
112 Ok(match s {
113 "clamp_to_border" => WrapMode::ClampToBorder,
114 "clamp_to_edge" => WrapMode::ClampToEdge,
115 "repeat" => WrapMode::Repeat,
116 "mirrored_repeat" => WrapMode::MirroredRepeat,
117 _ => WrapMode::ClampToBorder,
118 })
119 }
120}
121
122impl FromStr for FilterMode {
123 type Err = Infallible;
124
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 Ok(match s {
127 "linear" => FilterMode::Linear,
128 "nearest" => FilterMode::Nearest,
129 _ => FilterMode::Nearest,
130 })
131 }
132}
133
134#[repr(u32)]
136#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138pub enum ColorSpace {
139 #[default]
141 Sdr = 0,
142 Hdr10 = 1,
145 ScRgb = 2,
148 PqScRgb = 3,
150}
151
152impl ColorSpace {
153 pub fn is_hdr(&self) -> bool {
155 !matches!(*self, ColorSpace::Sdr)
156 }
157}
158
159#[repr(i32)]
160#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Hash)]
161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
162pub enum WrapMode {
164 #[default]
165 ClampToBorder = 0,
167 ClampToEdge,
169 Repeat,
171 MirroredRepeat,
173}
174
175impl FromStr for ImageFormat {
176 type Err = Infallible;
177
178 fn from_str(s: &str) -> Result<Self, Self::Err> {
179 Ok(match s {
180 "UNKNOWN" => Self::Unknown,
181
182 "R8_UNORM" => Self::R8Unorm,
183 "R8_UINT" => Self::R8Uint,
184 "R8_SINT" => Self::R8Sint,
185 "R8G8_UNORM" => Self::R8G8Unorm,
186 "R8G8_UINT" => Self::R8Uint,
187 "R8G8_SINT" => Self::R8G8Sint,
188 "R8G8B8A8_UNORM" => Self::R8G8B8A8Unorm,
189 "R8G8B8A8_UINT" => Self::R8G8B8A8Uint,
190 "R8G8B8A8_SINT" => Self::R8G8B8A8Sint,
191 "R8G8B8A8_SRGB" => Self::R8G8B8A8Srgb,
192
193 "A2B10G10R10_UNORM_PACK32" => Self::A2B10G10R10UnormPack32,
194 "A2B10G10R10_UINT_PACK32" => Self::A2B10G10R10UintPack32,
195
196 "R16_UINT" => Self::R16Uint,
197 "R16_SINT" => Self::R16Sint,
198 "R16_SFLOAT" => Self::R16Sfloat,
199 "R16G16_UINT" => Self::R16G16Uint,
200 "R16G16_SINT" => Self::R16G16Sint,
201 "R16G16_SFLOAT" => Self::R16G16Sfloat,
202 "R16G16B16A16_UINT" => Self::R16G16B16A16Uint,
203 "R16G16B16A16_SINT" => Self::R16G16B16A16Sint,
204 "R16G16B16A16_SFLOAT" => Self::R16G16B16A16Sfloat,
205
206 "R32_UINT" => Self::R32Uint,
207 "R32_SINT" => Self::R32Sint,
208 "R32_SFLOAT" => Self::R32Sfloat,
209 "R32G32_UINT" => Self::R32G32Uint,
210 "R32G32_SINT" => Self::R32G32Sint,
211 "R32G32_SFLOAT" => Self::R32G32Sfloat,
212 "R32G32B32A32_UINT" => Self::R32G32B32A32Uint,
213 "R32G32B32A32_SINT" => Self::R32G32B32A32Sint,
214 "R32G32B32A32_SFLOAT" => Self::R32G32B32A32Sfloat,
215 _ => Self::Unknown,
216 })
217 }
218}
219
220#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223pub struct Size<T> {
224 pub width: T,
225 pub height: T,
226}
227
228impl<T> Size<T> {
229 pub fn new(width: T, height: T) -> Self {
231 Size { width, height }
232 }
233}
234
235impl<T: AsPrimitive<f32>> Size<T> {
236 #[inline(always)]
238 pub fn aspect_ratio(&self) -> f32 {
239 self.width.as_() / self.height.as_()
240 }
241}
242
243impl<T: Sub<Output = T>> Sub for Size<T> {
244 type Output = Size<T>;
245
246 fn sub(self, rhs: Self) -> Self::Output {
247 Self {
248 width: self.width - rhs.width,
249 height: self.height - rhs.height,
250 }
251 }
252}
253
254impl<T: Sub<T, Output = T> + Copy> Sub<T> for Size<T> {
255 type Output = Size<T>;
256
257 fn sub(self, rhs: T) -> Self::Output {
258 Self {
259 width: self.width - rhs,
260 height: self.height - rhs,
261 }
262 }
263}
264
265impl<T: Add<Output = T>> Add for Size<T> {
266 type Output = Size<T>;
267
268 fn add(self, rhs: Self) -> Self::Output {
269 Self {
270 width: self.width + rhs.width,
271 height: self.height + rhs.height,
272 }
273 }
274}
275
276impl<T: Add<T, Output = T> + Copy> Add<T> for Size<T> {
277 type Output = Size<T>;
278
279 fn add(self, rhs: T) -> Self::Output {
280 Self {
281 width: self.width + rhs,
282 height: self.height + rhs,
283 }
284 }
285}
286
287impl<T> From<Size<T>> for [f32; 4]
288where
289 T: Copy + AsPrimitive<f32>,
290{
291 fn from(value: Size<T>) -> Self {
293 [
294 value.width.as_(),
295 value.height.as_(),
296 1.0 / value.width.as_(),
297 1.0 / value.height.as_(),
298 ]
299 }
300}
301
302pub trait GetSize<C: Num> {
304 type Error;
305 fn size(&self) -> Result<Size<C>, Self::Error>;
307}
308
309impl<T: GetSize<u32>> GetSize<f32> for T {
310 type Error = T::Error;
311
312 fn size(&self) -> Result<Size<f32>, Self::Error> {
313 let size = <T as GetSize<u32>>::size(self)?;
314 Ok(Size {
315 width: size.width as f32,
316 height: size.height as f32,
317 })
318 }
319}