1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
use crate::runtime::state::ContextUpdate; use crate::runtime::Connection; /// Describes the viewport used by by a [GraphicsPipeline]. /// /// The viewport defines the affine transformation of `X` and `Y` from normalized device coordinates /// to window coordinates. /// /// Given a viewport with origin `(X_vp, Y_vp)`, width `width` and height `height`; let `X_nd` and /// `Y_nd` be normalized device coordinates, then the corresponding window coordinates `X_w` and /// `Y_w` are computed as: /// /// `X_w = (X_nd + 1) * 0.5 * width + X_vp` /// /// `Y_w = (X_nd + 1) * 0.5 * height + Y_vp` /// /// There are two ways to define a [Viewport]: /// /// 1. With explicit values: /// ``` /// # #[allow(non_snake_case)] let X_vp = 0; /// # #[allow(non_snake_case)] let Y_vp = 0; /// # let width = 100; /// # let height = 100; /// use web_glitz::pipeline::graphics::Viewport; /// /// let viewport = Viewport::Region((X_vp, Y_vp), width, height); /// ``` /// Where `X_vp`, `Y_vp`, `width` and `height` correspond to the values used in the description /// above. /// /// 2. With automatic values: /// ``` /// use web_glitz::pipeline::graphics::Viewport; /// /// let viewport = Viewport::Auto; /// ``` /// In this case, the origin will always be `(0, 0)`; determination of the `width` and `height` /// is deferred until draw time, where they taken to be the width and height of the /// [RenderTarget] that is being drawn to, such that the viewport will cover the [RenderTarget] /// exactly. Note that the width and height of the [RenderTarget] are determined by the attached /// images with the smallest width and height respectively. /// #[derive(Clone, PartialEq, Debug)] pub enum Viewport { Region((i32, i32), u32, u32), Auto, } impl Viewport { pub(crate) fn apply(&self, connection: &mut Connection, auto_dimensions: (u32, u32)) { let (gl, state) = unsafe { connection.unpack_mut() }; let (x, y, width, height) = match self { Viewport::Region((x, y), width, height) => (*x, *y, *width, *height), Viewport::Auto => { let (width, height) = auto_dimensions; (0, 0, width, height) } }; state .set_viewport(x, y, width as i32, height as i32) .apply(gl) .unwrap(); } }