1 //! Models versions of OpenGL Shader Language (GLSL) 2 3 use { OpenGL, PickShader, Shaders }; 4 use std::str::FromStr; 5 use std::fmt; 6 use std::error::Error; 7 8 /// For OpenGL version 3.3 and above, 9 /// the GLSL version is the same as the OpenGL version. 10 /// 11 /// Source: http://www.opengl.org/wiki/Core_Language_%28GLSL%29 12 #[allow(missing_docs)] 13 #[allow(non_camel_case_types)] 14 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)] 15 pub enum GLSL { 16 V1_10, 17 V1_20, 18 V1_30, 19 V1_40, 20 V1_50, 21 V3_30, 22 V4_00, 23 V4_10, 24 V4_20, 25 V4_30, 26 V4_40, 27 V4_50 28 } 29 30 impl GLSL { 31 /// Gets OpenGL version associated with GLSL. 32 #[allow(non_snake_case)] to_opengl(&self) -> OpenGL33 pub fn to_opengl(&self) -> OpenGL { 34 match *self { 35 GLSL::V1_10 => OpenGL::V2_0, 36 GLSL::V1_20 => OpenGL::V2_1, 37 GLSL::V1_30 => OpenGL::V3_0, 38 GLSL::V1_40 => OpenGL::V3_1, 39 GLSL::V1_50 => OpenGL::V3_2, 40 GLSL::V3_30 => OpenGL::V3_3, 41 GLSL::V4_00 => OpenGL::V4_0, 42 GLSL::V4_10 => OpenGL::V4_1, 43 GLSL::V4_20 => OpenGL::V4_2, 44 GLSL::V4_30 => OpenGL::V4_3, 45 GLSL::V4_40 => OpenGL::V4_4, 46 GLSL::V4_50 => OpenGL::V4_5 47 } 48 } 49 } 50 51 impl PickShader for GLSL { pick_shader<'a, S: ?Sized>(self, shaders: &Shaders<'a, Self, S>) -> Option<&'a S>52 fn pick_shader<'a, S: ?Sized>(self, shaders: &Shaders<'a, Self, S>) -> Option<&'a S> { 53 // OpenGL since 3.2 in core profile doesn't support GLSL lower than 1.50. 54 // Since there are no compatible shader in this case, it will return `None`. 55 let low = if self < GLSL::V1_50 { 56 GLSL::V1_10 57 } else { 58 GLSL::V1_50 59 }; 60 shaders.0.iter() 61 .skip_while(|&(v, _)| *v < low) 62 .take_while(|&(v, _)| *v <= self) 63 .last().map(|(_, &s)| s) 64 } 65 } 66 67 68 impl FromStr for GLSL { 69 type Err = ParseGLSLError; 70 from_str(s: &str) -> Result<Self, Self::Err>71 fn from_str(s: &str) -> Result<Self, Self::Err> { 72 match s { 73 "1.10" => Ok(GLSL::V1_10), 74 "1.20" => Ok(GLSL::V1_20), 75 "1.30" => Ok(GLSL::V1_30), 76 "1.40" => Ok(GLSL::V1_40), 77 "1.50" => Ok(GLSL::V1_50), 78 "3.30" => Ok(GLSL::V3_30), 79 "4.00" => Ok(GLSL::V4_00), 80 "4.10" => Ok(GLSL::V4_10), 81 "4.20" => Ok(GLSL::V4_20), 82 "4.30" => Ok(GLSL::V4_30), 83 "4.40" => Ok(GLSL::V4_40), 84 "4.50" => Ok(GLSL::V4_50), 85 error => Err(ParseGLSLError{input: error.into()}), 86 } 87 } 88 } 89 90 91 /// Represents an error while trying to get `GLSL` from `&str`. 92 #[derive(Debug)] 93 pub struct ParseGLSLError{ 94 input: String 95 } 96 97 impl fmt::Display for ParseGLSLError { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 99 write!(f, "`{}` is not a valid GLSL version", self.input) 100 } 101 } 102 103 impl Error for ParseGLSLError { description(&self) -> &str104 fn description(&self) -> &str { 105 "Invalid GLSL version" 106 } 107 } 108