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}