fyrox_graphics/
lib.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! This crate is an abstraction layer for graphical services like OpenGL.
22//! See the [`server::GraphicsServer`] trait for the rendering features that are available through
23//! this abstraction layer.
24//! The `fyrox-graphics-gl` crate provides an OpenGL implementation of `GraphicsServer`.
25
26#![allow(clippy::too_many_arguments)]
27#![warn(missing_docs)]
28
29pub use fyrox_core as core;
30use std::fmt::Debug;
31
32use crate::core::{reflect::prelude::*, type_traits::prelude::*, visitor::prelude::*};
33use serde::{Deserialize, Serialize};
34use strum_macros::{AsRefStr, EnumString, VariantNames};
35
36pub mod buffer;
37pub mod error;
38pub mod framebuffer;
39pub mod geometry_buffer;
40pub mod gpu_program;
41pub mod gpu_texture;
42pub mod query;
43pub mod read_buffer;
44pub mod sampler;
45pub mod server;
46pub mod stats;
47pub mod uniform;
48
49/// Define a wrapper struct that holds an `Rc` containing the given type.
50/// It implements `Clone` to copy the `Rc` and
51/// implements `Deref` to access the value inside the `Rc`.
52///
53/// For example: `define_shared_wrapper!(Example<usize>)` would expand to:
54/// ```
55/// #[derive(Clone)]
56/// #[doc(hidden)]
57/// pub struct Example(pub std::rc::Rc<usize>);
58///
59/// impl std::ops::Deref for Example {
60///      type Target = usize;
61///
62///      fn deref(&self) -> &Self::Target {
63///         self.0.deref()
64///      }
65/// }
66/// ```
67#[macro_export]
68macro_rules! define_shared_wrapper {
69    ($name:ident<$ty:ty>) => {
70        #[derive(Clone)]
71        #[doc(hidden)]
72        pub struct $name(pub std::rc::Rc<$ty>);
73
74        impl std::ops::Deref for $name {
75            type Target = $ty;
76
77            fn deref(&self) -> &Self::Target {
78                self.0.deref()
79            }
80        }
81    };
82}
83
84/// A set of possible polygon filling modes.
85#[derive(
86    Copy,
87    Clone,
88    PartialOrd,
89    PartialEq,
90    Hash,
91    Debug,
92    Deserialize,
93    Visit,
94    Eq,
95    Reflect,
96    AsRefStr,
97    EnumString,
98    VariantNames,
99    TypeUuidProvider,
100    Default,
101)]
102#[type_uuid(id = "47aff01a-7daa-427c-874c-87464a7ffe28")]
103pub enum PolygonFillMode {
104    /// Only vertices of polygons are rendered. Their size is 1px by default.
105    Point,
106    /// Only edges of polygons are rendered using 1px lines. This mode is useful for wireframe
107    /// drawing.
108    Line,
109    /// The entire polygon surface is rendered. This is default rendering mode.
110    #[default]
111    Fill,
112}
113
114/// A function used to compare two values. Usually it is used for depth and stencil testing.
115#[derive(
116    Copy,
117    Clone,
118    PartialOrd,
119    PartialEq,
120    Eq,
121    Ord,
122    Hash,
123    Visit,
124    Serialize,
125    Deserialize,
126    Debug,
127    Reflect,
128    AsRefStr,
129    EnumString,
130    VariantNames,
131    Default,
132)]
133pub enum CompareFunc {
134    /// Never passes.
135    Never,
136
137    /// Passes if the incoming value is less than the stored value.
138    Less,
139
140    /// Passes if the incoming value is equal to the stored value.
141    Equal,
142
143    /// Passes if the incoming value is less than or equal to the stored value.
144    #[default]
145    LessOrEqual,
146
147    /// Passes if the incoming value is greater than the stored value.
148    Greater,
149
150    /// Passes if the incoming value is not equal to the stored value.
151    NotEqual,
152
153    /// Passes if the incoming value is greater than or equal to the stored value.
154    GreaterOrEqual,
155
156    /// Always passes.
157    Always,
158}
159
160/// Defines how some color will be multiplied before being blended.
161/// The destination color is the color that is currently in the frame buffer,
162/// and the source color is the color that is produced by the fragment shader.
163/// See [`BlendFunc`] for more about how to use these.
164#[derive(
165    Copy,
166    Clone,
167    Hash,
168    PartialOrd,
169    PartialEq,
170    Eq,
171    Ord,
172    Serialize,
173    Deserialize,
174    Visit,
175    Debug,
176    Reflect,
177    AsRefStr,
178    EnumString,
179    VariantNames,
180    Default,
181)]
182pub enum BlendFactor {
183    /// The color is multiplied by zero, turning it black.
184    #[default]
185    Zero,
186    /// The color is multiplied by one, leaving it unchanged.
187    One,
188    /// The color is multiplied by the source color.
189    SrcColor,
190    /// The color is multiplied by (1 - src), the inverted source color.
191    OneMinusSrcColor,
192    /// The color is multiplied by the destination color.
193    DstColor,
194    /// The color is multiplied by (1 - dst), the inverted destination color.
195    OneMinusDstColor,
196    /// The color is multiplied by the alpha of the source color.
197    SrcAlpha,
198    /// The color is multiplied by (1 - alpha), the inverted alpha of the source color.
199    OneMinusSrcAlpha,
200    /// The color is multiplied by the alpha of the destination color.
201    DstAlpha,
202    /// The color is multiplied by (1 - alpha), the inverted alpha of the destination color.
203    OneMinusDstAlpha,
204    /// The color is multiplied by the blend constant.
205    ConstantColor,
206    /// The color is multiplied by (1 - constant), the inverted blend constant.
207    OneMinusConstantColor,
208    /// The color is multiplied by the alpha of the blend constant.
209    ConstantAlpha,
210    /// The color is multiplied by (1 - alpha), the inverted alpha of the blend constant.
211    OneMinusConstantAlpha,
212    /// Red, green, and blue channels are multiplied by min(src alpha, 1 - dst alpha),
213    /// and the alpha channel is multiplied by 1.
214    SrcAlphaSaturate,
215    /// The color is multiplied by the color of the second source.
216    Src1Color,
217    /// The color is multiplied by (1 - src1), the inverted color of the second source.
218    OneMinusSrc1Color,
219    /// The color is multiplied by the alpha of the second source.
220    Src1Alpha,
221    /// The color is multiplied by (1 - alpha), the inverted alpha of the second source.
222    OneMinusSrc1Alpha,
223}
224
225/// Defines an operation used in blending equation.
226#[derive(
227    Copy,
228    Clone,
229    Hash,
230    PartialOrd,
231    PartialEq,
232    Eq,
233    Ord,
234    Serialize,
235    Deserialize,
236    Visit,
237    Debug,
238    Reflect,
239    Default,
240)]
241pub enum BlendMode {
242    /// Addition of two operands (`Source + Dest`). This is default operation.
243    #[default]
244    Add,
245    /// Subtraction of two operands (`Source - Dest`).
246    Subtract,
247    /// Reverse subtraction of two operands (`Dest - Source`).
248    ReverseSubtract,
249    /// Per-component min function of two operands (`min(Source, Dest)`).
250    Min,
251    /// Per-component max function of two operands (`max(Source, Dest)`).
252    Max,
253}
254
255/// An equation used for blending a source pixel color with the destination color (the one that is
256/// already in a frame buffer). This equation has different modes for rgb/alpha parts.
257#[derive(
258    Copy,
259    Clone,
260    Default,
261    PartialOrd,
262    PartialEq,
263    Ord,
264    Eq,
265    Hash,
266    Serialize,
267    Deserialize,
268    Visit,
269    Debug,
270    Reflect,
271)]
272pub struct BlendEquation {
273    /// An operation for RGB part.
274    pub rgb: BlendMode,
275    /// An operation for alpha part.
276    pub alpha: BlendMode,
277}
278
279/// Blending function defines factors for both operands in blending equation (separately
280/// for RGB and Alpha parts). Default blending function is replacing destination values with the
281/// source ones.
282#[derive(
283    Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Serialize, Deserialize, Visit, Debug, Reflect,
284)]
285pub struct BlendFunc {
286    /// Factor for the source (the value that is produced by a shader) in the blending equation (RGB part).
287    pub sfactor: BlendFactor,
288    /// Factor for the destination (the value that is already in a frame buffer) in the blending equation
289    /// (RGB part).
290    pub dfactor: BlendFactor,
291    /// Factor for the source (the value that is produced by a shader) in the blending equation (alpha part).
292    pub alpha_sfactor: BlendFactor,
293    /// Factor for the destination (the value that is already in a frame buffer) in the blending equation
294    /// (alpha part).
295    pub alpha_dfactor: BlendFactor,
296}
297
298impl BlendFunc {
299    /// Creates a new blending function where both RGB and Alpha parts have the same blending factor.
300    pub fn new(sfactor: BlendFactor, dfactor: BlendFactor) -> Self {
301        Self {
302            sfactor,
303            dfactor,
304            alpha_sfactor: sfactor,
305            alpha_dfactor: dfactor,
306        }
307    }
308
309    /// Creates a new blending function where RGB and Alpha parts have different blending factor.
310    pub fn new_separate(
311        sfactor: BlendFactor,
312        dfactor: BlendFactor,
313        alpha_sfactor: BlendFactor,
314        alpha_dfactor: BlendFactor,
315    ) -> Self {
316        Self {
317            sfactor,
318            dfactor,
319            alpha_sfactor,
320            alpha_dfactor,
321        }
322    }
323}
324
325impl Default for BlendFunc {
326    fn default() -> Self {
327        Self {
328            sfactor: BlendFactor::One,
329            dfactor: BlendFactor::Zero,
330            alpha_sfactor: BlendFactor::One,
331            alpha_dfactor: BlendFactor::Zero,
332        }
333    }
334}
335
336/// A mask that defines which colors will be stored in a frame buffer during rendering operation.
337/// By default, all colors are stored (every field is set to `true`).
338#[derive(
339    Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
340)]
341pub struct ColorMask {
342    /// A flag, that defines whether the red channel is written or not in a frame buffer.
343    pub red: bool,
344    /// A flag, that defines whether the green channel is written or not in a frame buffer.
345    pub green: bool,
346    /// A flag, that defines whether the blue channel is written or not in a frame buffer.
347    pub blue: bool,
348    /// A flag, that defines whether the alpha channel is written or not in a frame buffer.
349    pub alpha: bool,
350}
351
352impl Default for ColorMask {
353    fn default() -> Self {
354        Self {
355            red: true,
356            green: true,
357            blue: true,
358            alpha: true,
359        }
360    }
361}
362
363impl ColorMask {
364    /// Creates a new color mask where all the components will have the specified value.
365    pub fn all(value: bool) -> Self {
366        Self {
367            red: value,
368            green: value,
369            blue: value,
370            alpha: value,
371        }
372    }
373}
374
375/// Defines a polygon face that will be rendered. This is usually used for back face culling.
376/// Default value is [`PolygonFace::FrontAndBack`].
377#[derive(
378    Copy,
379    Clone,
380    PartialOrd,
381    PartialEq,
382    Hash,
383    Debug,
384    Deserialize,
385    Visit,
386    Eq,
387    Reflect,
388    AsRefStr,
389    EnumString,
390    VariantNames,
391    Default,
392)]
393pub enum PolygonFace {
394    /// Only front faces will be rendered.
395    Front,
396    /// Only back faces will be rendered.
397    Back,
398    /// Both, back and front faces will be rendered.
399    #[default]
400    FrontAndBack,
401}
402
403/// Defines a function that used in a stencil test by comparing the `ref_value` to the stencil buffer.
404#[derive(
405    Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
406)]
407pub struct StencilFunc {
408    /// The function that is used to compare the stencil buffer value against `ref_value`.
409    /// In this case the incoming value is `ref_value` and the stored value is the stencil buffer value
410    /// for the pixel. So [`CompareFunc::Less`] which means `ref_value` must be less than the stencil buffer value
411    /// or else the pixel will not draw.
412    /// Default value is [`CompareFunc::Always`], which means draw every pixel.
413    pub func: CompareFunc,
414    /// Reference value that is used to compare against the current value in the stencil buffer.
415    /// Default value is 0.
416    pub ref_value: u32,
417    /// A mask value that is used to filter out some bits (using logical AND operation) of a value
418    /// in the stencil buffer and the ref value (for example if a [`CompareFunc::Less`] is used
419    /// then the entire equation will look like `(ref & mask) < (stencil & mask)`). Default value
420    /// is `0xFFFFFFFF`.
421    pub mask: u32,
422}
423
424impl Default for StencilFunc {
425    fn default() -> Self {
426        Self {
427            func: CompareFunc::Always,
428            ref_value: 0,
429            mask: 0xFFFF_FFFF,
430        }
431    }
432}
433
434/// An action with the stencil value in the stencil buffer is the stencil test passed.
435#[derive(
436    Copy,
437    Clone,
438    PartialOrd,
439    PartialEq,
440    Hash,
441    Debug,
442    Serialize,
443    Deserialize,
444    Visit,
445    Eq,
446    Reflect,
447    AsRefStr,
448    EnumString,
449    VariantNames,
450    Default,
451)]
452pub enum StencilAction {
453    /// Keeps the current value. This is the default variant.
454    #[default]
455    Keep,
456
457    /// Sets the stencil buffer value to 0.
458    Zero,
459
460    /// Sets the stencil buffer value to ref value.
461    Replace,
462
463    /// Increments the current stencil buffer value.
464    /// Clamps to the maximum representable unsigned value.
465    Incr,
466
467    /// Increments the current stencil buffer value.
468    /// Wraps stencil buffer value to zero when incrementing the maximum representable
469    /// unsigned value.
470    IncrWrap,
471
472    /// Decrements the current stencil buffer value.
473    /// Clamps to 0.
474    Decr,
475
476    /// Decrements the current stencil buffer value.
477    /// Wraps stencil buffer value to the maximum representable unsigned value when
478    /// decrementing a stencil buffer value of zero.
479    DecrWrap,
480
481    /// Bitwise inverts the current stencil buffer value.
482    Invert,
483}
484
485/// A set of actions that will be performed with the stencil buffer during various testing stages.
486#[derive(
487    Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
488)]
489pub struct StencilOp {
490    /// An action that happens when the stencil test has failed.
491    pub fail: StencilAction,
492    /// An action that happens when the depth test has failed.
493    pub zfail: StencilAction,
494    /// An action that happens when the depth test has passed.
495    pub zpass: StencilAction,
496    /// Specifies a bit mask to enable and disable writing of individual bits in the stencil planes. Initially, the mask is all 1's,
497    /// which means that all bits of the stencil buffer may be written by the stencil operations specified in `stencil_op`.
498    /// 0 bits protect the corresponding bits of the stencil from changing.
499    pub write_mask: u32,
500}
501
502impl StencilOp {
503    /// Compare the actions of this `StencilOp` with the actions of another `StencilOp`. True if all actions match.
504    /// This comparison ignores the `write_mask`.
505    pub fn eq_actions(&self, other: &StencilOp) -> bool {
506        self.fail == other.fail && self.zfail == other.zfail && self.zpass == other.zpass
507    }
508}
509
510impl Default for StencilOp {
511    fn default() -> Self {
512        Self {
513            fail: Default::default(),
514            zfail: Default::default(),
515            zpass: Default::default(),
516            write_mask: 0xFFFF_FFFF,
517        }
518    }
519}
520
521/// A face side to cull.
522#[derive(
523    Copy,
524    Clone,
525    PartialOrd,
526    PartialEq,
527    Hash,
528    Debug,
529    Serialize,
530    Deserialize,
531    Visit,
532    Eq,
533    Reflect,
534    Default,
535)]
536pub enum CullFace {
537    /// Cull only back faces.
538    #[default]
539    Back,
540    /// Cull only front faces.
541    Front,
542}
543
544/// Blending parameters (such as blending function and its equation).
545#[derive(Serialize, Deserialize, Default, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
546pub struct BlendParameters {
547    /// Blending function, see [`BlendFunc`] for more info.
548    pub func: BlendFunc,
549    /// Blending equation, see [`BlendEquation`] for more info.
550    pub equation: BlendEquation,
551}
552
553/// A rectangular area that defines which pixels will be rendered in a frame buffer or not.
554#[derive(Serialize, Deserialize, Default, Visit, Debug, PartialEq, Clone, Copy, Eq, Reflect)]
555pub struct ScissorBox {
556    /// X coordinate of the box's origin.
557    pub x: i32,
558    /// Y coordinate of the box's origin. Located at the bottom of the rectangle.
559    pub y: i32,
560    /// Width of the box.
561    pub width: i32,
562    /// Height of the box.
563    pub height: i32,
564}
565
566/// A set of drawing parameters, that are used during draw call. It defines pretty much all pipeline
567/// settings all at once.
568#[derive(Serialize, Deserialize, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
569pub struct DrawParameters {
570    /// An optional cull face. If [`None`], then the culling is disabled.
571    pub cull_face: Option<CullFace>,
572    /// Color write mask.
573    pub color_write: ColorMask,
574    /// A flag, that defines whether the depth values should be written to the depth buffer or not.
575    pub depth_write: bool,
576    /// Stencil test options. If [`None`], then the stencil test is disabled.
577    pub stencil_test: Option<StencilFunc>,
578    /// Depth test options. If [`None`], then the depth test is disabled.
579    pub depth_test: Option<CompareFunc>,
580    /// Blending options. If [`None`], then the blending is disabled.
581    pub blend: Option<BlendParameters>,
582    /// Stencil operation.
583    pub stencil_op: StencilOp,
584    /// Optional scissor box. If [`None`], then the scissor test is disabled.
585    pub scissor_box: Option<ScissorBox>,
586}
587
588impl Default for DrawParameters {
589    fn default() -> Self {
590        Self {
591            cull_face: Some(CullFace::Back),
592            color_write: Default::default(),
593            depth_write: true,
594            stencil_test: None,
595            depth_test: Some(CompareFunc::Less),
596            blend: None,
597            stencil_op: Default::default(),
598            scissor_box: None,
599        }
600    }
601}
602
603/// A range of elements (usually it's triangles) to draw in a draw call.
604#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
605pub enum ElementRange {
606    /// All available elements. This is the default option.
607    #[default]
608    Full,
609    /// Specific range of elements. Useful if you have a large buffer that contains multiple smaller
610    /// elements at once.
611    Specific {
612        /// Offset (in elements) from the beginning of the buffer.
613        offset: usize,
614        /// Total count of elements to draw.
615        count: usize,
616    },
617}
618
619/// Element kind of geometry.
620#[derive(Copy, Clone, PartialEq, Eq, Debug)]
621pub enum ElementKind {
622    /// Triangles.
623    Triangle,
624    /// Lines.
625    Line,
626    /// Points.
627    Point,
628}
629
630impl ElementKind {
631    /// The number of indices that are required to represent the element.
632    pub fn index_per_element(self) -> usize {
633        match self {
634            ElementKind::Triangle => 3,
635            ElementKind::Line => 2,
636            ElementKind::Point => 1,
637        }
638    }
639}