blue_engine_core/header.rs
1/*
2 * Blue Engine by Elham Aryanpur
3 *
4 * The license is Apache-2.0
5*/
6
7/// re-exports from dependencies that are useful
8pub mod imports;
9/// few commonly used uniform buffer structures
10pub mod uniform_buffer;
11pub use imports::*;
12pub use uniform_buffer::*;
13
14use downcast::{downcast, Any};
15
16/// The uint type used for indices and more
17#[cfg(feature = "u16")]
18pub type UnsignedIntType = u16;
19#[cfg(feature = "u32")]
20pub type UnsignedIntType = u32;
21
22macro_rules! impl_deref {
23 ($struct:ty,$type:ty) => {
24 impl std::ops::Deref for $struct {
25 type Target = $type;
26
27 fn deref(&self) -> &Self::Target {
28 &self.0
29 }
30 }
31 impl std::ops::DerefMut for $struct {
32 fn deref_mut(&mut self) -> &mut Self::Target {
33 &mut self.0
34 }
35 }
36 };
37}
38
39macro_rules! impl_deref_field {
40 ($struct:ty,$type:ty,$field:ident) => {
41 impl std::ops::Deref for $struct {
42 type Target = $type;
43
44 fn deref(&self) -> &Self::Target {
45 &self.$field
46 }
47 }
48 impl std::ops::DerefMut for $struct {
49 fn deref_mut(&mut self) -> &mut Self::Target {
50 &mut self.$field
51 }
52 }
53 };
54}
55
56/// Will contain all details about a vertex and will be sent to GPU
57// Will be turned to C code and sent to GPU
58#[repr(C)]
59#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
60pub struct Vertex {
61 /// Contains position data for the vertex in 3D space
62 pub position: Vector3,
63 /// Contains uv position data for the vertex
64 pub uv: Vector2,
65 /// Contains the normal face of the vertex
66 pub normal: Vector3,
67}
68impl Vertex {
69 pub(crate) fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
70 wgpu::VertexBufferLayout {
71 array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
72 step_mode: wgpu::VertexStepMode::Vertex,
73 attributes: &[
74 wgpu::VertexAttribute {
75 offset: 0,
76 shader_location: 0,
77 format: wgpu::VertexFormat::Float32x3,
78 },
79 wgpu::VertexAttribute {
80 // This should be replaced with `std::mem::size_of::<Vector3>() as wgpu::BufferAddress`
81 offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
82 shader_location: 1,
83 format: wgpu::VertexFormat::Float32x2,
84 },
85 wgpu::VertexAttribute {
86 offset: std::mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
87 shader_location: 2,
88 format: wgpu::VertexFormat::Float32x3,
89 },
90 ],
91 }
92 }
93}
94unsafe impl Send for Vertex {}
95unsafe impl Sync for Vertex {}
96
97/// Objects make it easier to work with Blue Engine, it automates most of work needed for
98/// creating 3D objects and showing them on screen. A range of default objects are available
99/// as well as ability to customize each of them and even create your own! You can also
100/// customize almost everything there is about them!
101pub struct Object {
102 /// Give your object a name, which can help later on for debugging.
103 pub name: std::sync::Arc<str>,
104 /// A list of Vertex
105 pub vertices: Vec<Vertex>,
106 /// A list of indices that dictates the order that vertices appear
107 pub indices: Vec<UnsignedIntType>,
108 /// Describes how to uniform buffer is structures
109 pub uniform_layout: wgpu::BindGroupLayout,
110 /// Pipeline holds all the data that is sent to GPU, including shaders and textures
111 pub pipeline: Pipeline,
112 /// List of instances of this object
113 pub instances: Vec<Instance>,
114 /// instance buffer
115 pub instance_buffer: wgpu::Buffer,
116 /// Dictates the size of your object in relation to the world
117 pub size: Vector3,
118 /// Dictates the position of your object in pixels
119 pub position: Vector3,
120 /// Dictates the rotation of your object
121 pub rotation: Vector3,
122 // flags the object to be updated until next frame
123 pub(crate) changed: bool,
124 /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
125 /// Best choice is to let the Object system handle it
126 pub position_matrix: nalgebra_glm::Mat4,
127 /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
128 /// Best choice is to let the Object system handle it
129 pub scale_matrix: nalgebra_glm::Mat4,
130 /// Transformation matrices helps to apply changes to your object, including position, orientation, ...
131 /// Best choice is to let the Object system handle it
132 pub rotation_matrix: nalgebra_glm::Mat4,
133 /// Transformation matrix, but inversed
134 pub inverse_transformation_matrix: crate::uniform_type::Matrix,
135 /// The main color of your object
136 pub color: crate::uniform_type::Array4,
137 /// A struct making it easier to manipulate specific parts of shader
138 pub shader_builder: crate::objects::ShaderBuilder,
139 /// Shader settings
140 pub shader_settings: ShaderSettings,
141 /// Camera have any effect on the object?
142 pub camera_effect: Option<std::sync::Arc<str>>,
143 /// Uniform Buffers to be sent to GPU. These are raw and not compiled for GPU yet
144 pub uniform_buffers: Vec<wgpu::Buffer>,
145 /// Should be rendered or not
146 pub is_visible: bool,
147 /// Objects with higher number get rendered later and appear "on top" when occupying the same space
148 pub render_order: usize,
149}
150unsafe impl Send for Object {}
151unsafe impl Sync for Object {}
152
153/// Extra settings to customize objects on time of creation
154#[derive(Debug, Clone)]
155pub struct ObjectSettings {
156 /// Should it be affected by camera?
157 pub camera_effect: Option<std::sync::Arc<str>>,
158 /// Shader Settings
159 pub shader_settings: ShaderSettings,
160}
161impl Default for ObjectSettings {
162 fn default() -> Self {
163 Self {
164 camera_effect: Some("main".into()),
165 shader_settings: ShaderSettings::default(),
166 }
167 }
168}
169unsafe impl Send for ObjectSettings {}
170unsafe impl Sync for ObjectSettings {}
171
172/// The engine is the main starting point of using the Blue Engine.
173/// Everything that runs on Blue Engine will be under this struct.
174/// The structure of engine is monolithic, but the underlying data and the way it works is not.
175/// It gives a set of default data to work with,
176/// but also allow you to go beyond that and work as low level as you wish to.
177///
178/// You can also use the Engine to build you own custom structure the way you wish for it to be.
179/// Possibilities are endless!
180///
181/// To start using the Blue Engine, you can start by creating a new Engine like follows:
182/// ```
183/// use blue_engine::header::{Engine, WindowDescriptor};
184///
185/// fn main() {
186/// let engine = Engine::new().expect("Couldn't create the engine");
187/// }
188/// ```
189/// The WindowDescriptor simply holds what features you would like for your window.
190/// If you are reading this on later version of
191/// the engine, you might be able to even run the engine in headless mode
192/// meaning there would not be a need for a window and the
193/// renders would come as image files.
194///
195/// If you so wish to have a window, you would need to start a window update loop.
196/// The update loop of window runs a frame every few millisecond,
197/// and gives you details of what is happening during this time, like input events.
198/// You can also modify existing parts of the engine during
199/// this update loop, such as changing camera to look differently,
200/// or creating a new object on the scene, or even changing window details!
201///
202/// The update loop is just a method of the Engine struct
203/// that have one argument which is a callback function.
204/// ```
205///
206/// ```
207/// [THE DATA HERE IS WORK IN PROGRESS!]
208pub struct Engine {
209 /// The renderer does exactly what it is called.
210 /// It works with the GPU to render frames according to the data you gave it.
211 pub renderer: Renderer,
212 /// The event_loop handles the events of the window and inputs.
213 ///
214 /// #### USED INTERNALLY
215 pub event_loop_control_flow: crate::winit::event_loop::ControlFlow,
216 /// The window handles everything about window and inputs.
217 /// This includes ability to modify window and listen toinput devices for changes.
218 ///
219 /// ### The window is not available before update_loop.
220 pub window: Window,
221 /// The object system is a way to make it easier to work with the engine.
222 /// Obviously you can work without it, but it's for those who
223 /// do not have the know-how, or wish to handle all the work of rendering data manually.
224 pub objects: ObjectStorage,
225 /// The camera handles the way the scene looks when rendered.
226 /// You can modify everything there is to camera through this.
227 pub camera: CameraContainer,
228 /// Handles all engine plugins
229 pub signals: SignalStorage,
230
231 /// holds the update_loop function
232 ///
233 /// #### USED INTERNALLY
234 #[allow(clippy::type_complexity)]
235 pub update_loop: Option<
236 Box<
237 dyn 'static
238 + FnMut(
239 // Core
240 &mut Renderer,
241 &mut Window,
242 &mut ObjectStorage,
243 &crate::utils::winit_input_helper::WinitInputHelper,
244 &mut CameraContainer,
245 &mut crate::SignalStorage,
246 ),
247 >,
248 >,
249
250 /// input events
251 ///
252 /// #### USED INTERNALLY
253 pub input_events: crate::utils::winit_input_helper::WinitInputHelper,
254}
255unsafe impl Send for Engine {}
256unsafe impl Sync for Engine {}
257
258/// Container for pipeline values. Each pipeline takes only 1 vertex shader,
259/// 1 fragment shader, 1 texture data, and optionally a vector of uniform data.
260#[derive(Debug)]
261pub struct Pipeline {
262 /// the shader buffer that's sent to the gpu
263 pub shader: PipelineData<crate::Shaders>,
264 /// The vertex buffer that's sent to the gpu. This includes indices as well
265 pub vertex_buffer: PipelineData<VertexBuffers>,
266 /// The texture that's sent to the gpu.
267 pub texture: PipelineData<crate::Textures>,
268 /// the Uniform buffers that are sent to the gpu
269 pub uniform: PipelineData<Option<crate::UniformBuffers>>,
270}
271unsafe impl Send for Pipeline {}
272unsafe impl Sync for Pipeline {}
273
274/// Container for pipeline data. Allows for sharing resources with other objects
275#[derive(Debug)]
276pub enum PipelineData<T> {
277 /// No data, just a reference to a buffer
278 Copy(String),
279 /// The actual data
280 Data(T),
281}
282
283/// Container for vertex and index buffer
284#[derive(Debug)]
285pub struct VertexBuffers {
286 /// An array of vertices. A vertex is a point in 3D space containing
287 /// an X, Y, and a Z coordinate between -1 and +1
288 pub vertex_buffer: wgpu::Buffer,
289 /// An array of indices. Indices are a way to reuse vertices,
290 /// this in turn helps greatly in reduction of amount of vertices needed to be sent to the GPU
291 pub index_buffer: wgpu::Buffer,
292 /// The length of the vertex buffer
293 pub length: u32,
294}
295unsafe impl Send for VertexBuffers {}
296unsafe impl Sync for VertexBuffers {}
297
298/// Main renderer class. this will contain all methods and data related to the renderer
299#[derive(Debug)]
300pub struct Renderer {
301 /// A [`wgpu::Surface`] represents a platform-specific surface
302 /// (e.g. a window) onto which rendered images may be presented.
303 pub surface: Option<wgpu::Surface<'static>>,
304 /// Context for all of the gpu objects
305 pub instance: wgpu::Instance,
306 /// Handle to a physical graphics and/or compute device.
307 #[allow(unused)]
308 pub adapter: wgpu::Adapter,
309 /// Open connection to a graphics and/or compute device.
310 pub device: wgpu::Device,
311 /// Handle to a command queue on a device.
312 pub queue: wgpu::Queue,
313 /// Describes a [`wgpu::Surface`]
314 pub config: wgpu::SurfaceConfiguration,
315 /// The size of the window
316 pub size: winit::dpi::PhysicalSize<u32>,
317 /// The texture bind group layout
318 pub texture_bind_group_layout: wgpu::BindGroupLayout,
319 /// The uniform bind group layout
320 pub default_uniform_bind_group_layout: wgpu::BindGroupLayout,
321 /// The depth buffer, used to render object depth
322 pub depth_buffer: (wgpu::Texture, wgpu::TextureView, wgpu::Sampler),
323 /// The default data used within the renderer
324 pub default_data: Option<(crate::Textures, crate::Shaders, crate::UniformBuffers)>,
325 /// The camera used in the engine
326 pub camera: Option<crate::UniformBuffers>,
327 /// Background clear color
328 pub clear_color: wgpu::Color,
329 /// Scissor cut section of the screen to render to
330 /// (x, y, width, height)
331 pub scissor_rect: Option<(u32, u32, u32, u32)>,
332}
333unsafe impl Sync for Renderer {}
334unsafe impl Send for Renderer {}
335
336/// Descriptor and settings for a window.
337#[derive(Debug, Clone)]
338pub struct WindowDescriptor {
339 /// The width of the window
340 pub width: u32,
341 /// The height of the window
342 pub height: u32,
343 /// The title of the window
344 pub title: &'static str,
345 /// Should the window contain the keys like minimize, maximize, or resize?
346 pub decorations: bool,
347 /// Should the window be resizable
348 pub resizable: bool,
349 /// Define how much power should the app ask for
350 pub power_preference: crate::PowerPreference,
351 /// The backend to use for the draw
352 pub backends: crate::Backends,
353 /// The features to be enabled on a backend
354 ///
355 /// read more at [wgpu::Features]
356 pub features: crate::wgpu::Features,
357 /// Controls how the events are processed
358 ///
359 /// read more at [winit::event_loop::ControlFlow]
360 pub control_flow: crate::winit::event_loop::ControlFlow,
361 /// The presentation mode of renderer for things like VSync
362 ///
363 /// read more at [wgpu::PresentMode]
364 pub present_mode: crate::wgpu::PresentMode,
365 /// Limits to be required based on the generation of the GPU and the API.
366 ///
367 /// read more at [wgpu::Limits]
368 pub limits: crate::wgpu::Limits,
369 /// The alpha mode which specifies how the alpha channel of
370 /// the textures should be handled during compositing.
371 pub alpha_mode: crate::wgpu::CompositeAlphaMode,
372 /// The desired frame latency.
373 ///
374 /// read more at [wgpu::SurfaceConfiguration::desired_maximum_frame_latency]
375 pub desired_maximum_frame_latency: u32,
376 /// How the memory should be utilized
377 ///
378 /// read more at [wgpu::MemoryHints]
379 pub memory_hints: crate::wgpu::MemoryHints,
380}
381impl std::default::Default for WindowDescriptor {
382 /// Will quickly create a window with default settings
383 fn default() -> Self {
384 let backends = crate::Backends::all();
385 Self {
386 width: 800,
387 height: 600,
388 title: "Blue Engine",
389 decorations: true,
390 resizable: true,
391 power_preference: crate::PowerPreference::LowPower,
392 backends,
393 features: if backends == wgpu::Backends::VULKAN {
394 wgpu::Features::POLYGON_MODE_LINE | wgpu::Features::POLYGON_MODE_POINT
395 } else if backends
396 .contains(wgpu::Backends::VULKAN | wgpu::Backends::METAL | wgpu::Backends::DX12)
397 {
398 wgpu::Features::POLYGON_MODE_LINE
399 } else {
400 wgpu::Features::empty()
401 },
402 control_flow: crate::winit::event_loop::ControlFlow::Poll,
403 present_mode: crate::wgpu::PresentMode::AutoNoVsync,
404 limits: crate::wgpu::Limits::default(),
405 alpha_mode: crate::wgpu::CompositeAlphaMode::Auto,
406 desired_maximum_frame_latency: 2,
407 memory_hints: crate::MemoryHints::Performance,
408 }
409 }
410}
411unsafe impl Send for WindowDescriptor {}
412unsafe impl Sync for WindowDescriptor {}
413
414/// Container for the projection used by the camera
415#[derive(Debug, Clone, PartialEq, PartialOrd)]
416pub enum Projection {
417 /// Perspective projection
418 ///
419 /// This is the default project used by the video games and majority of graphics
420 Perspective {
421 /// The field of view
422 fov: f32,
423 },
424 /// Orthographic projection
425 ///
426 /// This projection gives you a 2D view of the scene
427 Orthographic {
428 /// The size of the view
429 zoom: f32,
430 },
431}
432
433/// Container for the camera feature. The settings here are needed for
434/// algebra equations needed for camera vision and movement. Please leave it to the renderer to handle
435#[derive(Debug)]
436pub struct Camera {
437 /// The position of the camera in 3D space
438 pub position: Vector3,
439 /// The target at which the camera should be looking
440 pub target: Vector3,
441 /// The up vector of the camera. This defines the elevation of the camera
442 pub up: Vector3,
443 /// The resolution of the camera view
444 pub resolution: (f32, f32), //maybe this should be a Vector2i
445 /// The projection of the camera
446 pub projection: Projection,
447 /// The closest view of camera
448 pub near: f32,
449 /// The furthest view of camera
450 pub far: f32,
451 /// The final data that will be sent to GPU
452 pub view_data: nalgebra_glm::Mat4,
453 // For checking and rebuilding it's uniform buffer
454 pub(crate) changed: bool,
455 /// The uniform data of the camera to be sent to the gpu
456 pub uniform_data: UniformBuffers,
457 /// The position and target of the camera
458 pub(crate) add_position_and_target: bool,
459}
460unsafe impl Send for Camera {}
461unsafe impl Sync for Camera {}
462
463/// Container for Cameras
464///
465/// This allows for different objects have a different camera perspective.
466#[derive(Debug)]
467pub struct CameraContainer {
468 /// The list of cameras
469 // Arc<str> is used instead of String for performance
470 pub cameras: std::collections::HashMap<std::sync::Arc<str>, Camera>,
471}
472impl_deref_field!(
473 CameraContainer,
474 std::collections::HashMap<std::sync::Arc<str>, Camera>,
475 cameras
476);
477
478/// These definitions are taken from wgpu API docs
479#[derive(Debug, Clone, Copy)]
480pub struct ShaderSettings {
481 // ===== PRIMITIVE ===== //
482 /// The primitive topology used to interpret vertices
483 pub topology: crate::ShaderPrimitive,
484 /// When drawing strip topologies with indices, this is the
485 /// required format for the index buffer. This has no effect
486 /// on non-indexed or non-strip draws.
487 pub strip_index_format: Option<crate::IndexFormat>,
488 /// The face to consider the front for the purpose of
489 /// culling and stencil operations.
490 pub front_face: crate::FrontFace,
491 /// The face culling mode
492 pub cull_mode: Option<crate::CullMode>,
493 /// Controls the way each polygon is rasterized. Can be
494 /// either `Fill` (default), `Line` or `Point`
495 ///
496 /// Setting this to something other than `Fill` requires
497 /// `NON_FILL_POLYGON_MODE` feature to be enabled
498 pub polygon_mode: crate::PolygonMode,
499 /// If set to true, the polygon depth is clamped to 0-1
500 /// range instead of being clipped.
501 ///
502 /// Enabling this requires the `DEPTH_CLAMPING` feature
503 /// to be enabled
504 pub clamp_depth: bool,
505 /// If set to true, the primitives are rendered with
506 /// conservative overestimation. I.e. any rastered
507 /// pixel touched by it is filled. Only valid for PolygonMode::Fill!
508 ///
509 /// Enabling this requires `CONSERVATIVE_RASTERIZATION`
510 /// features to be enabled.
511 pub conservative: bool,
512
513 // ===== Multisample ===== //
514 /// The number of samples calculated per pixel (for MSAA).
515 /// For non-multisampled textures, this should be `1`
516 pub count: u32,
517 /// Bitmask that restricts the samples of a pixel modified
518 /// by this pipeline. All samples can be enabled using the
519 /// value `!0`
520 pub mask: u64,
521 /// When enabled, produces another sample mask per pixel
522 /// based on the alpha output value, that is ANDead with the
523 /// sample_mask and the primitive coverage to restrict the
524 /// set of samples affected by a primitive.
525
526 /// The implicit mask produced for alpha of zero is guaranteed
527 /// to be zero, and for alpha of one is guaranteed to be all
528 /// 1-s.
529 pub alpha_to_coverage_enabled: bool,
530}
531impl Default for ShaderSettings {
532 fn default() -> Self {
533 Self {
534 topology: wgpu::PrimitiveTopology::TriangleList,
535 strip_index_format: None,
536 front_face: wgpu::FrontFace::Ccw,
537 cull_mode: Some(wgpu::Face::Back),
538 polygon_mode: wgpu::PolygonMode::Fill,
539 clamp_depth: false,
540 conservative: false,
541 count: 1,
542 mask: !0,
543 alpha_to_coverage_enabled: true,
544 }
545 }
546}
547unsafe impl Send for ShaderSettings {}
548unsafe impl Sync for ShaderSettings {}
549
550/// Instance buffer data that is sent to GPU
551#[repr(C)]
552#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
553pub struct InstanceRaw {
554 /// The transformation matrix of the instance
555 pub model: uniform_type::Matrix,
556}
557
558/// Instance buffer data storage
559#[derive(Debug, Clone, Copy)]
560pub struct Instance {
561 /// The position of the instance
562 pub position: Vector3,
563 /// The rotation of the instance
564 pub rotation: Vector3,
565 /// The scale of the instance
566 pub scale: Vector3,
567}
568
569/// Allows all events to be fetched directly, making it easier to add custom additions to the engine.
570pub trait Signal: Any {
571 /// This is ran as soon as the engine is properly initialized and all components are ready
572 #[allow(clippy::too_many_arguments)]
573 fn init(
574 &mut self,
575 _renderer: &mut crate::Renderer,
576 _window: &crate::Window,
577 _objects: &mut ObjectStorage,
578 _camera: &mut crate::CameraContainer,
579 ) {
580 }
581
582 /// This is ran at the device events when available
583 #[allow(clippy::too_many_arguments)]
584 fn device_events(
585 &mut self,
586 _renderer: &mut crate::Renderer,
587 _window: &crate::Window,
588 _objects: &mut ObjectStorage,
589 _events: &crate::DeviceEvent,
590 _input: &crate::InputHelper,
591 _camera: &mut crate::CameraContainer,
592 ) {
593 }
594
595 /// This is ran at the window events when available
596 #[allow(clippy::too_many_arguments)]
597 fn window_events(
598 &mut self,
599 _renderer: &mut crate::Renderer,
600 _window: &crate::Window,
601 _objects: &mut ObjectStorage,
602 _events: &crate::WindowEvent,
603 _input: &crate::InputHelper,
604 _camera: &mut crate::CameraContainer,
605 ) {
606 }
607
608 /// ran before the frame is rendered
609 #[allow(clippy::too_many_arguments)]
610 fn frame(
611 &mut self,
612 _renderer: &mut crate::Renderer,
613 _window: &crate::Window,
614 _objects: &mut ObjectStorage,
615 _camera: &mut crate::CameraContainer,
616 _input: &crate::InputHelper,
617 _encoder: &mut crate::CommandEncoder,
618 _view: &crate::TextureView,
619 ) {
620 }
621}
622// The engine needs to know the functions of Signal to do things internally,
623// so we use downcast and not the std::any::Any
624downcast!(dyn Signal);
625
626/// Defines how the rotation axis is
627#[derive(Debug, Clone, Copy, PartialEq, Eq)]
628pub enum RotateAxis {
629 #[doc(hidden)]
630 X,
631 #[doc(hidden)]
632 Y,
633 #[doc(hidden)]
634 Z,
635}
636unsafe impl Send for RotateAxis {}
637unsafe impl Sync for RotateAxis {}
638
639/// Defines how the rotation amount is
640#[derive(Debug, Clone, Copy, PartialEq)]
641pub enum RotateAmount {
642 #[doc(hidden)]
643 Radians(f32),
644 #[doc(hidden)]
645 Degrees(f32),
646}
647unsafe impl Send for RotateAmount {}
648unsafe impl Sync for RotateAmount {}
649
650/// Defines how the texture data is
651#[derive(Debug, Clone)]
652pub enum TextureData {
653 /// the texture file bytes directly
654 Bytes(Vec<u8>),
655 /// the texture as a [`image::DynamicImage`]
656 Image(image::DynamicImage),
657 /// path to a texture file to load
658 Path(String),
659}
660unsafe impl Send for TextureData {}
661unsafe impl Sync for TextureData {}
662
663/// Defines how the borders of texture would look like
664#[derive(Debug, Clone, Copy, PartialEq, Eq)]
665pub enum TextureMode {
666 /// Expands the texture to fit the object
667 Clamp,
668 /// Repeats the texture instead of stretching
669 Repeat,
670 /// Repeats the texture, but mirrors it on edges
671 MirrorRepeat,
672}
673unsafe impl Send for TextureMode {}
674unsafe impl Sync for TextureMode {}
675
676/// This function helps in converting pixel value to the value that is between -1 and +1
677pub fn pixel_to_cartesian(value: f32, max: u32) -> f32 {
678 let mut result = value / max as f32;
679
680 if value == max as f32 {
681 result = 0.0;
682 } else if result < max as f32 / 2.0 {
683 }
684
685 if result > -1.0 {
686 result
687 } else {
688 -1.0
689 }
690}
691
692/// A unified way to handle strings
693pub trait StringBuffer: StringBufferTrait + Clone {}
694/// A trait for [StringBuffer]
695pub trait StringBufferTrait {
696 /// Returns the string as &[`str`]
697 fn as_str(&self) -> &str;
698 /// Returns the string as [`String`]
699 fn as_string(&self) -> String;
700 /// Returns Arc<str> for ease of computation
701 fn as_arc(&self) -> std::sync::Arc<str>;
702}
703
704impl StringBufferTrait for String {
705 fn as_str(&self) -> &str {
706 self.as_ref()
707 }
708 fn as_string(&self) -> String {
709 self.clone()
710 }
711 fn as_arc(&self) -> std::sync::Arc<str> {
712 self.as_str().into()
713 }
714}
715impl StringBuffer for String {}
716impl StringBufferTrait for &str {
717 fn as_str(&self) -> &str {
718 self
719 }
720 fn as_string(&self) -> String {
721 self.to_string()
722 }
723 fn as_arc(&self) -> std::sync::Arc<str> {
724 self.as_str().into()
725 }
726}
727impl StringBuffer for &str {}
728
729/// A unified way to handle objects
730///
731/// This is a container for objects that is used to apply different operations on the objects at the same time.
732/// It can deref to the object hashmap itself when needed.
733pub struct ObjectStorage(std::collections::HashMap<String, Object>);
734impl ObjectStorage {
735 /// Creates a new object storage
736 pub fn new() -> Self {
737 ObjectStorage(std::collections::HashMap::new())
738 }
739}
740impl Default for ObjectStorage {
741 fn default() -> Self {
742 Self::new()
743 }
744}
745unsafe impl Send for ObjectStorage {}
746unsafe impl Sync for ObjectStorage {}
747
748impl_deref!(ObjectStorage, std::collections::HashMap<String, Object>);
749
750/// Depth format
751pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
752
753/// Handles the live events in the engine
754pub struct SignalStorage {
755 /// list of events with key and the event
756 pub events: Vec<(String, Box<dyn Signal>)>,
757}
758
759/// Handles the order in which a functionality in the engine should be executed
760pub enum ExecuteOrder {
761 /// The main function that is the update_loop
762 UpdateLoopFunction,
763}
764
765/// A wrapper for winit window to make it easier to use and more ergonomic.
766#[derive(Debug)]
767pub struct Window {
768 /// The winit window itself.
769 pub window: Option<std::sync::Arc<crate::winit::window::Window>>,
770 /// Default attributes of the window
771 pub default_attributes: winit::window::WindowAttributes,
772 /// Whether the engine should close.
773 pub should_close: bool,
774}
775impl_deref_field!(
776 Window,
777 Option<std::sync::Arc<crate::winit::window::Window>>,
778 window
779);
780
781#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default, Zeroable)]
782#[repr(C)]
783/// General purposes 3D vector
784pub struct Vector3 {
785 /// X coordinate in 3D space
786 pub x: f32,
787 /// Y coordinate in 3D space
788 pub y: f32,
789 /// Z coordinate in 3D space
790 pub z: f32,
791}
792
793#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default, Zeroable)]
794#[repr(C)]
795/// General purposes 2D vector
796pub struct Vector2 {
797 /// X coordinate in 2D space
798 pub x: f32,
799 /// Y coordinate in 2D space
800 pub y: f32,
801}