1 // Copyright 2017 The Gfx-rs Developers. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Fixed-function hardware state. 16 //! 17 //! Configures the primitive assembly (PA), rasterizer, and output merger (OM) blocks. 18 19 use std::default::Default; 20 use std::fmt; 21 22 use target; 23 24 /// The front face winding order of a set of vertices. 25 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 26 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 27 pub enum FrontFace { 28 /// Clockwise winding order. 29 Clockwise, 30 /// Counter-clockwise winding order. 31 CounterClockwise, 32 } 33 34 /// Width of a line. 35 /// Could be f32 if not for Hash deriving issues. 36 pub type LineWidth = i32; 37 /// Slope depth offset factor 38 /// Could be f32 if not for Hash deriving issues. 39 pub type OffsetSlope = i32; 40 /// Number of units to offset, where 41 /// the unit is the minimal difference in the depth value 42 /// dictated by the precision of the depth buffer. 43 pub type OffsetUnits = i32; 44 45 /// How to offset vertices in screen space, if at all. 46 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)] 47 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 48 pub struct Offset(pub OffsetSlope, pub OffsetUnits); 49 50 /// Which face, if any, to cull. 51 #[allow(missing_docs)] 52 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 53 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 54 pub enum CullFace { 55 Nothing, 56 Front, 57 Back, 58 } 59 60 /// How to rasterize a primitive. 61 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)] 62 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 63 pub enum RasterMethod { 64 /// Rasterize as a point. 65 Point, 66 /// Rasterize as a line with the given width. 67 Line(LineWidth), 68 /// Rasterize as a face. 69 Fill 70 } 71 72 /// Multi-sampling rasterization mode 73 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 74 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 75 pub struct MultiSample; 76 //sample_mask: u16, 77 //alpha_to_coverage: bool, 78 79 /// Primitive rasterization state. Note that GL allows different raster 80 /// method to be used for front and back, while this abstraction does not. 81 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)] 82 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 83 pub struct Rasterizer { 84 /// Which vertex winding is considered to be the front face for culling. 85 pub front_face: FrontFace, 86 /// Which face should be culled. 87 pub cull_face: CullFace, 88 /// How to rasterize this primitive. 89 pub method: RasterMethod, 90 /// Any polygon offset to apply. 91 pub offset: Option<Offset>, 92 /// Multi-sampling mode. 93 pub samples: Option<MultiSample>, 94 } 95 96 impl Rasterizer { 97 /// Create a new filling rasterizer. new_fill() -> Self98 pub fn new_fill() -> Self { 99 Rasterizer { 100 front_face: FrontFace::CounterClockwise, 101 cull_face: CullFace::Nothing, 102 method: RasterMethod::Fill, 103 offset: None, 104 samples: None, 105 } 106 } 107 108 /// Add back face culling. with_cull_back(self) -> Self109 pub fn with_cull_back(self) -> Self { 110 Rasterizer { 111 cull_face: CullFace::Back, 112 ..self 113 } 114 } 115 116 /// Add polygon offset. with_offset(self, slope: f32, units: OffsetUnits) -> Self117 pub fn with_offset(self, slope: f32, units: OffsetUnits) -> Self { 118 Rasterizer { 119 offset: Some(Offset(slope as OffsetSlope, units)), 120 ..self 121 } 122 } 123 } 124 125 /// A pixel-wise comparison function. 126 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 127 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 128 pub enum Comparison { 129 /// `false` 130 Never, 131 /// `x < y` 132 Less, 133 /// `x <= y` 134 LessEqual, 135 /// `x == y` 136 Equal, 137 /// `x >= y` 138 GreaterEqual, 139 /// `x > y` 140 Greater, 141 /// `x != y` 142 NotEqual, 143 /// `true` 144 Always, 145 } 146 147 /// Stencil mask operation. 148 #[allow(missing_docs)] 149 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 150 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 151 pub enum StencilOp { 152 /// Keep the current value in the stencil buffer (no change). 153 Keep, 154 /// Set the value in the stencil buffer to zero. 155 Zero, 156 /// Set the stencil buffer value to `value` from `StencilSide` 157 Replace, 158 /// Increment the stencil buffer value, clamping to its maximum value. 159 IncrementClamp, 160 /// Increment the stencil buffer value, wrapping around to 0 on overflow. 161 IncrementWrap, 162 /// Decrement the stencil buffer value, clamping to its minimum value. 163 DecrementClamp, 164 /// Decrement the stencil buffer value, wrapping around to the maximum value on overflow. 165 DecrementWrap, 166 /// Bitwise invert the current value in the stencil buffer. 167 Invert, 168 } 169 170 /// Complete stencil state for a given side of a face. 171 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 172 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 173 pub struct StencilSide { 174 /// Comparison function to use to determine if the stencil test passes. 175 pub fun: Comparison, 176 /// A mask that is ANDd with both the stencil buffer value and the reference value when they 177 /// are read before doing the stencil test. 178 pub mask_read: target::Stencil, 179 /// A mask that is ANDd with the stencil value before writing to the stencil buffer. 180 pub mask_write: target::Stencil, 181 /// What operation to do if the stencil test fails. 182 pub op_fail: StencilOp, 183 /// What operation to do if the stenil test passes but the depth test fails. 184 pub op_depth_fail: StencilOp, 185 /// What operation to do if both the depth and stencil test pass. 186 pub op_pass: StencilOp, 187 } 188 189 impl Default for StencilSide { default() -> Self190 fn default() -> Self { 191 StencilSide { 192 fun: Comparison::Always, 193 mask_read: target::Stencil::max_value(), 194 mask_write: target::Stencil::max_value(), 195 op_fail: StencilOp::Keep, 196 op_depth_fail: StencilOp::Keep, 197 op_pass: StencilOp::Keep, 198 } 199 } 200 } 201 202 /// Complete stencil state, specifying how to handle the front and back side of a face. 203 #[allow(missing_docs)] 204 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 205 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 206 pub struct Stencil { 207 pub front: StencilSide, 208 pub back: StencilSide, 209 } 210 211 impl Stencil { 212 /// Create a new stencil state with a given function. new(fun: Comparison, mask: target::Stencil, ops: (StencilOp, StencilOp, StencilOp)) -> Self213 pub fn new(fun: Comparison, mask: target::Stencil, 214 ops: (StencilOp, StencilOp, StencilOp)) 215 -> Self { 216 let side = StencilSide { 217 fun: fun, 218 mask_read: mask, 219 mask_write: mask, 220 op_fail: ops.0, 221 op_depth_fail: ops.1, 222 op_pass: ops.2, 223 }; 224 Stencil { 225 front: side, 226 back: side, 227 } 228 } 229 } 230 231 /// Depth test state. 232 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 233 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 234 pub struct Depth { 235 /// Comparison function to use. 236 pub fun: Comparison, 237 /// Specify whether to write to the depth buffer or not. 238 pub write: bool, 239 } 240 241 impl Default for Depth { default() -> Self242 fn default() -> Self { 243 Depth { 244 fun: Comparison::Always, 245 write: false, 246 } 247 } 248 } 249 250 #[allow(missing_docs)] 251 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 252 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 253 pub enum Equation { 254 /// Adds source and destination. 255 /// Source and destination are multiplied by blending parameters before addition. 256 Add, 257 /// Subtracts destination from source. 258 /// Source and destination are multiplied by blending parameters before subtraction. 259 Sub, 260 /// Subtracts source from destination. 261 /// Source and destination are multiplied by blending parameters before subtraction. 262 RevSub, 263 /// Component-wise minimum value of source and destination. 264 /// Blending parameters are ignored. 265 Min, 266 /// Component-wise maximum value of source and destination. 267 /// Blending parameters are ignored. 268 Max, 269 } 270 271 #[allow(missing_docs)] 272 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 273 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 274 pub enum BlendValue { 275 SourceColor, 276 SourceAlpha, 277 DestColor, 278 DestAlpha, 279 ConstColor, 280 ConstAlpha, 281 } 282 283 #[allow(missing_docs)] 284 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 285 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 286 pub enum Factor { 287 Zero, 288 One, 289 SourceAlphaSaturated, 290 ZeroPlus(BlendValue), 291 OneMinus(BlendValue), 292 } 293 294 #[allow(missing_docs)] 295 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 296 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 297 pub struct BlendChannel { 298 pub equation: Equation, 299 pub source: Factor, 300 pub destination: Factor, 301 } 302 303 impl Default for BlendChannel { default() -> Self304 fn default() -> Self { 305 BlendChannel { 306 equation: Equation::Add, 307 source: Factor::One, 308 destination: Factor::Zero, 309 } 310 } 311 } 312 313 #[allow(missing_docs)] 314 #[derive(Clone, Copy, Default, Eq, Hash, PartialEq, PartialOrd)] 315 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 316 pub struct Blend { 317 pub color: BlendChannel, 318 pub alpha: BlendChannel, 319 } 320 321 impl Blend { 322 /// Create a new blend state with a given equation. new(eq: Equation, src: Factor, dst: Factor) -> Self323 pub fn new(eq: Equation, src: Factor, dst: Factor) -> Self { 324 let chan = BlendChannel { 325 equation: eq, 326 source: src, 327 destination: dst, 328 }; 329 Blend { 330 color: chan, 331 alpha: chan, 332 } 333 } 334 } 335 336 impl fmt::Debug for Blend { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result337 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 338 write!(f, "Blend {{ color: {:?}, alpha: {:?}}}", 339 self.color, self.alpha) 340 } 341 } 342 343 bitflags!( 344 #[allow(missing_docs)] 345 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 346 pub struct ColorMask: u8 { 347 #[allow(missing_docs)] 348 const RED = 0x1; 349 #[allow(missing_docs)] 350 const GREEN = 0x2; 351 #[allow(missing_docs)] 352 const BLUE = 0x4; 353 #[allow(missing_docs)] 354 const ALPHA = 0x8; 355 } 356 ); 357 358 /// The state of an active color render target 359 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)] 360 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 361 pub struct Color { 362 /// Color mask to use. 363 pub mask: ColorMask, 364 /// Optional blending. 365 pub blend: Option<Blend>, 366 } 367 368 impl Default for Color { default() -> Self369 fn default() -> Self { 370 Color { 371 mask: ColorMask::all(), 372 blend: None, 373 } 374 } 375 } 376 377 /// The complete set of the rasterizer reference values. 378 /// Switching these doesn't roll the hardware context. 379 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] 380 #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] 381 pub struct RefValues { 382 /// Stencil front and back values. 383 pub stencil: (target::Stencil, target::Stencil), 384 /// Constant blend color. 385 pub blend: target::ColorValue, 386 } 387 388 impl Default for RefValues { default() -> Self389 fn default() -> Self { 390 RefValues { 391 stencil: (0, 0), 392 blend: [0f32; 4], 393 } 394 } 395 } 396