Skip to main content

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    TypeUuidProvider,
133)]
134#[type_uuid(id = "95922b07-d532-4183-8f3f-89ebe058b6f1")]
135pub enum CompareFunc {
136    /// Never passes.
137    Never,
138
139    /// Passes if the incoming value is less than the stored value.
140    Less,
141
142    /// Passes if the incoming value is equal to the stored value.
143    Equal,
144
145    /// Passes if the incoming value is less than or equal to the stored value.
146    #[default]
147    LessOrEqual,
148
149    /// Passes if the incoming value is greater than the stored value.
150    Greater,
151
152    /// Passes if the incoming value is not equal to the stored value.
153    NotEqual,
154
155    /// Passes if the incoming value is greater than or equal to the stored value.
156    GreaterOrEqual,
157
158    /// Always passes.
159    Always,
160}
161
162/// Defines how some color will be multiplied before being blended.
163/// The destination color is the color that is currently in the frame buffer,
164/// and the source color is the color that is produced by the fragment shader.
165/// See [`BlendFunc`] for more about how to use these.
166#[derive(
167    Copy,
168    Clone,
169    Hash,
170    PartialOrd,
171    PartialEq,
172    Eq,
173    Ord,
174    Serialize,
175    Deserialize,
176    Visit,
177    Debug,
178    Reflect,
179    AsRefStr,
180    EnumString,
181    VariantNames,
182    Default,
183    TypeUuidProvider,
184)]
185#[type_uuid(id = "8d99d682-8993-4a42-bdab-77bee84e62c9")]
186pub enum BlendFactor {
187    /// The color is multiplied by zero, turning it black.
188    #[default]
189    Zero,
190    /// The color is multiplied by one, leaving it unchanged.
191    One,
192    /// The color is multiplied by the source color.
193    SrcColor,
194    /// The color is multiplied by (1 - src), the inverted source color.
195    OneMinusSrcColor,
196    /// The color is multiplied by the destination color.
197    DstColor,
198    /// The color is multiplied by (1 - dst), the inverted destination color.
199    OneMinusDstColor,
200    /// The color is multiplied by the alpha of the source color.
201    SrcAlpha,
202    /// The color is multiplied by (1 - alpha), the inverted alpha of the source color.
203    OneMinusSrcAlpha,
204    /// The color is multiplied by the alpha of the destination color.
205    DstAlpha,
206    /// The color is multiplied by (1 - alpha), the inverted alpha of the destination color.
207    OneMinusDstAlpha,
208    /// The color is multiplied by the blend constant.
209    ConstantColor,
210    /// The color is multiplied by (1 - constant), the inverted blend constant.
211    OneMinusConstantColor,
212    /// The color is multiplied by the alpha of the blend constant.
213    ConstantAlpha,
214    /// The color is multiplied by (1 - alpha), the inverted alpha of the blend constant.
215    OneMinusConstantAlpha,
216    /// Red, green, and blue channels are multiplied by min(src alpha, 1 - dst alpha),
217    /// and the alpha channel is multiplied by 1.
218    SrcAlphaSaturate,
219    /// The color is multiplied by the color of the second source.
220    Src1Color,
221    /// The color is multiplied by (1 - src1), the inverted color of the second source.
222    OneMinusSrc1Color,
223    /// The color is multiplied by the alpha of the second source.
224    Src1Alpha,
225    /// The color is multiplied by (1 - alpha), the inverted alpha of the second source.
226    OneMinusSrc1Alpha,
227}
228
229/// Defines an operation used in blending equation.
230#[derive(
231    Copy,
232    Clone,
233    Hash,
234    PartialOrd,
235    PartialEq,
236    Eq,
237    Ord,
238    Serialize,
239    Deserialize,
240    Visit,
241    Debug,
242    Reflect,
243    Default,
244    AsRefStr,
245    EnumString,
246    VariantNames,
247    TypeUuidProvider,
248)]
249#[type_uuid(id = "2c7b09ab-d2b1-4fbb-9c5f-95b31584b048")]
250pub enum BlendMode {
251    /// Addition of two operands (`Source + Dest`). This is default operation.
252    #[default]
253    Add,
254    /// Subtraction of two operands (`Source - Dest`).
255    Subtract,
256    /// Reverse subtraction of two operands (`Dest - Source`).
257    ReverseSubtract,
258    /// Per-component min function of two operands (`min(Source, Dest)`).
259    Min,
260    /// Per-component max function of two operands (`max(Source, Dest)`).
261    Max,
262}
263
264/// An equation used for blending a source pixel color with the destination color (the one that is
265/// already in a frame buffer). This equation has different modes for rgb/alpha parts.
266#[derive(
267    Copy,
268    Clone,
269    Default,
270    PartialOrd,
271    PartialEq,
272    Ord,
273    Eq,
274    Hash,
275    Serialize,
276    Deserialize,
277    Visit,
278    Debug,
279    Reflect,
280    TypeUuidProvider,
281)]
282#[type_uuid(id = "83403a0b-b16f-42a4-ba62-4d72c3318691")]
283pub struct BlendEquation {
284    /// An operation for RGB part.
285    pub rgb: BlendMode,
286    /// An operation for alpha part.
287    pub alpha: BlendMode,
288}
289
290/// Blending function defines factors for both operands in blending equation (separately
291/// for RGB and Alpha parts). Default blending function is replacing destination values with the
292/// source ones.
293#[derive(
294    Copy,
295    Clone,
296    PartialOrd,
297    PartialEq,
298    Ord,
299    Eq,
300    Hash,
301    Serialize,
302    Deserialize,
303    Visit,
304    Debug,
305    Reflect,
306    TypeUuidProvider,
307)]
308#[type_uuid(id = "42021d36-fdd7-4c14-9a8a-9598c13dbf96")]
309pub struct BlendFunc {
310    /// Factor for the source (the value that is produced by a shader) in the blending equation (RGB part).
311    pub sfactor: BlendFactor,
312    /// Factor for the destination (the value that is already in a frame buffer) in the blending equation
313    /// (RGB part).
314    pub dfactor: BlendFactor,
315    /// Factor for the source (the value that is produced by a shader) in the blending equation (alpha part).
316    pub alpha_sfactor: BlendFactor,
317    /// Factor for the destination (the value that is already in a frame buffer) in the blending equation
318    /// (alpha part).
319    pub alpha_dfactor: BlendFactor,
320}
321
322impl BlendFunc {
323    /// Creates a new blending function where both RGB and Alpha parts have the same blending factor.
324    pub fn new(sfactor: BlendFactor, dfactor: BlendFactor) -> Self {
325        Self {
326            sfactor,
327            dfactor,
328            alpha_sfactor: sfactor,
329            alpha_dfactor: dfactor,
330        }
331    }
332
333    /// Creates a new blending function where RGB and Alpha parts have different blending factor.
334    pub fn new_separate(
335        sfactor: BlendFactor,
336        dfactor: BlendFactor,
337        alpha_sfactor: BlendFactor,
338        alpha_dfactor: BlendFactor,
339    ) -> Self {
340        Self {
341            sfactor,
342            dfactor,
343            alpha_sfactor,
344            alpha_dfactor,
345        }
346    }
347}
348
349impl Default for BlendFunc {
350    fn default() -> Self {
351        Self {
352            sfactor: BlendFactor::One,
353            dfactor: BlendFactor::Zero,
354            alpha_sfactor: BlendFactor::One,
355            alpha_dfactor: BlendFactor::Zero,
356        }
357    }
358}
359
360/// A mask that defines which colors will be stored in a frame buffer during rendering operation.
361/// By default, all colors are stored (every field is set to `true`).
362#[derive(
363    Copy, Clone, PartialOrd, PartialEq, Hash, Debug, Serialize, Deserialize, Visit, Eq, Reflect,
364)]
365pub struct ColorMask {
366    /// A flag, that defines whether the red channel is written or not in a frame buffer.
367    pub red: bool,
368    /// A flag, that defines whether the green channel is written or not in a frame buffer.
369    pub green: bool,
370    /// A flag, that defines whether the blue channel is written or not in a frame buffer.
371    pub blue: bool,
372    /// A flag, that defines whether the alpha channel is written or not in a frame buffer.
373    pub alpha: bool,
374}
375
376impl Default for ColorMask {
377    fn default() -> Self {
378        Self {
379            red: true,
380            green: true,
381            blue: true,
382            alpha: true,
383        }
384    }
385}
386
387impl ColorMask {
388    /// Creates a new color mask where all the components will have the specified value.
389    pub fn all(value: bool) -> Self {
390        Self {
391            red: value,
392            green: value,
393            blue: value,
394            alpha: value,
395        }
396    }
397}
398
399/// Defines a polygon face that will be rendered. This is usually used for back face culling.
400/// Default value is [`PolygonFace::FrontAndBack`].
401#[derive(
402    Copy,
403    Clone,
404    PartialOrd,
405    PartialEq,
406    Hash,
407    Debug,
408    Deserialize,
409    Visit,
410    Eq,
411    Reflect,
412    AsRefStr,
413    EnumString,
414    VariantNames,
415    Default,
416    TypeUuidProvider,
417)]
418#[type_uuid(id = "30a58aa9-eda9-4673-bc50-046f6d46d122")]
419pub enum PolygonFace {
420    /// Only front faces will be rendered.
421    Front,
422    /// Only back faces will be rendered.
423    Back,
424    /// Both, back and front faces will be rendered.
425    #[default]
426    FrontAndBack,
427}
428
429/// Defines a function that used in a stencil test by comparing the `ref_value` to the stencil buffer.
430#[derive(
431    Copy,
432    Clone,
433    PartialOrd,
434    PartialEq,
435    Hash,
436    Debug,
437    Serialize,
438    Deserialize,
439    Visit,
440    Eq,
441    Reflect,
442    TypeUuidProvider,
443)]
444#[type_uuid(id = "9d03366d-2537-4ef2-8e19-54f06d81d05e")]
445pub struct StencilFunc {
446    /// The function that is used to compare the stencil buffer value against `ref_value`.
447    /// In this case the incoming value is `ref_value` and the stored value is the stencil buffer value
448    /// for the pixel. So [`CompareFunc::Less`] which means `ref_value` must be less than the stencil buffer value
449    /// or else the pixel will not draw.
450    /// Default value is [`CompareFunc::Always`], which means draw every pixel.
451    pub func: CompareFunc,
452    /// Reference value that is used to compare against the current value in the stencil buffer.
453    /// Default value is 0.
454    pub ref_value: u32,
455    /// A mask value that is used to filter out some bits (using logical AND operation) of a value
456    /// in the stencil buffer and the ref value (for example if a [`CompareFunc::Less`] is used
457    /// then the entire equation will look like `(ref & mask) < (stencil & mask)`). Default value
458    /// is `0xFFFFFFFF`.
459    pub mask: u32,
460}
461
462impl Default for StencilFunc {
463    fn default() -> Self {
464        Self {
465            func: CompareFunc::Always,
466            ref_value: 0,
467            mask: 0xFFFF_FFFF,
468        }
469    }
470}
471
472/// An action with the stencil value in the stencil buffer is the stencil test passed.
473#[derive(
474    Copy,
475    Clone,
476    PartialOrd,
477    PartialEq,
478    Hash,
479    Debug,
480    Serialize,
481    Deserialize,
482    Visit,
483    Eq,
484    Reflect,
485    AsRefStr,
486    EnumString,
487    VariantNames,
488    Default,
489    TypeUuidProvider,
490)]
491#[type_uuid(id = "3e057392-6900-4506-880d-21391e6b4787")]
492pub enum StencilAction {
493    /// Keeps the current value. This is the default variant.
494    #[default]
495    Keep,
496
497    /// Sets the stencil buffer value to 0.
498    Zero,
499
500    /// Sets the stencil buffer value to ref value.
501    Replace,
502
503    /// Increments the current stencil buffer value.
504    /// Clamps to the maximum representable unsigned value.
505    Incr,
506
507    /// Increments the current stencil buffer value.
508    /// Wraps stencil buffer value to zero when incrementing the maximum representable
509    /// unsigned value.
510    IncrWrap,
511
512    /// Decrements the current stencil buffer value.
513    /// Clamps to 0.
514    Decr,
515
516    /// Decrements the current stencil buffer value.
517    /// Wraps stencil buffer value to the maximum representable unsigned value when
518    /// decrementing a stencil buffer value of zero.
519    DecrWrap,
520
521    /// Bitwise inverts the current stencil buffer value.
522    Invert,
523}
524
525/// A set of actions that will be performed with the stencil buffer during various testing stages.
526#[derive(
527    Copy,
528    Clone,
529    PartialOrd,
530    PartialEq,
531    Hash,
532    Debug,
533    Serialize,
534    Deserialize,
535    Visit,
536    Eq,
537    Reflect,
538    TypeUuidProvider,
539)]
540#[type_uuid(id = "5eec1018-60aa-4ebb-8884-547ba5f4b398")]
541pub struct StencilOp {
542    /// An action that happens when the stencil test has failed.
543    pub fail: StencilAction,
544    /// An action that happens when the depth test has failed.
545    pub zfail: StencilAction,
546    /// An action that happens when the depth test has passed.
547    pub zpass: StencilAction,
548    /// Specifies a bit mask to enable and disable writing of individual bits in the stencil planes. Initially, the mask is all 1's,
549    /// which means that all bits of the stencil buffer may be written by the stencil operations specified in `stencil_op`.
550    /// 0 bits protect the corresponding bits of the stencil from changing.
551    pub write_mask: u32,
552}
553
554impl StencilOp {
555    /// Compare the actions of this `StencilOp` with the actions of another `StencilOp`. True if all actions match.
556    /// This comparison ignores the `write_mask`.
557    pub fn eq_actions(&self, other: &StencilOp) -> bool {
558        self.fail == other.fail && self.zfail == other.zfail && self.zpass == other.zpass
559    }
560}
561
562impl Default for StencilOp {
563    fn default() -> Self {
564        Self {
565            fail: Default::default(),
566            zfail: Default::default(),
567            zpass: Default::default(),
568            write_mask: 0xFFFF_FFFF,
569        }
570    }
571}
572
573/// A face side to cull.
574#[derive(
575    Copy,
576    Clone,
577    PartialOrd,
578    PartialEq,
579    Hash,
580    Debug,
581    Serialize,
582    Deserialize,
583    Visit,
584    Eq,
585    Reflect,
586    AsRefStr,
587    EnumString,
588    VariantNames,
589    Default,
590    TypeUuidProvider,
591)]
592#[type_uuid(id = "9f467cd4-0a65-435d-b5d6-301493dbdc9b")]
593pub enum CullFace {
594    /// Cull only back faces.
595    #[default]
596    Back,
597    /// Cull only front faces.
598    Front,
599}
600
601/// Blending parameters (such as blending function and its equation).
602#[derive(
603    Serialize, Deserialize, Default, Visit, Debug, PartialEq, Clone, Eq, Reflect, TypeUuidProvider,
604)]
605#[type_uuid(id = "4c0afa4d-5b67-43b3-b486-5ec64cc20e7d")]
606pub struct BlendParameters {
607    /// Blending function, see [`BlendFunc`] for more info.
608    pub func: BlendFunc,
609    /// Blending equation, see [`BlendEquation`] for more info.
610    pub equation: BlendEquation,
611}
612
613/// A rectangular area that defines which pixels will be rendered in a frame buffer or not.
614#[derive(
615    Serialize,
616    Deserialize,
617    Default,
618    Visit,
619    Debug,
620    PartialEq,
621    Clone,
622    Copy,
623    Eq,
624    Reflect,
625    TypeUuidProvider,
626)]
627#[type_uuid(id = "22be6d48-772e-4dc0-bae5-37f5e8f3a3db")]
628pub struct ScissorBox {
629    /// X coordinate of the box's origin.
630    pub x: i32,
631    /// Y coordinate of the box's origin. Located at the bottom of the rectangle.
632    pub y: i32,
633    /// Width of the box.
634    pub width: i32,
635    /// Height of the box.
636    pub height: i32,
637}
638
639/// A set of drawing parameters, that are used during draw call. It defines pretty much all pipeline
640/// settings all at once.
641#[derive(Serialize, Deserialize, Visit, Debug, PartialEq, Clone, Eq, Reflect)]
642pub struct DrawParameters {
643    /// An optional cull face. If [`None`], then the culling is disabled.
644    pub cull_face: Option<CullFace>,
645    /// Color write mask.
646    pub color_write: ColorMask,
647    /// A flag, that defines whether the depth values should be written to the depth buffer or not.
648    pub depth_write: bool,
649    /// Stencil test options. If [`None`], then the stencil test is disabled.
650    pub stencil_test: Option<StencilFunc>,
651    /// Depth test options. If [`None`], then the depth test is disabled.
652    pub depth_test: Option<CompareFunc>,
653    /// Blending options. If [`None`], then the blending is disabled.
654    pub blend: Option<BlendParameters>,
655    /// Stencil operation.
656    pub stencil_op: StencilOp,
657    /// Optional scissor box. If [`None`], then the scissor test is disabled.
658    pub scissor_box: Option<ScissorBox>,
659}
660
661impl Default for DrawParameters {
662    fn default() -> Self {
663        Self {
664            cull_face: Some(CullFace::Back),
665            color_write: Default::default(),
666            depth_write: true,
667            stencil_test: None,
668            depth_test: Some(CompareFunc::Less),
669            blend: None,
670            stencil_op: Default::default(),
671            scissor_box: None,
672        }
673    }
674}
675
676/// A range of elements (usually it's triangles) to draw in a draw call.
677#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
678pub enum ElementRange {
679    /// All available elements. This is the default option.
680    #[default]
681    Full,
682    /// Specific range of elements. Useful if you have a large buffer that contains multiple smaller
683    /// elements at once.
684    Specific {
685        /// Offset (in elements) from the beginning of the buffer.
686        offset: usize,
687        /// Total count of elements to draw.
688        count: usize,
689    },
690}
691
692/// Element kind of geometry.
693#[derive(Copy, Clone, PartialEq, Eq, Debug)]
694pub enum ElementKind {
695    /// Triangles.
696    Triangle,
697    /// Lines.
698    Line,
699    /// Points.
700    Point,
701}
702
703impl ElementKind {
704    /// The number of indices that are required to represent the element.
705    pub fn index_per_element(self) -> usize {
706        match self {
707            ElementKind::Triangle => 3,
708            ElementKind::Line => 2,
709            ElementKind::Point => 1,
710        }
711    }
712}