shader_version/
glsl.rs

1//! Models versions of OpenGL Shader Language (GLSL)
2
3use { OpenGL, PickShader, Shaders };
4use std::str::FromStr;
5use std::fmt;
6use 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)]
15pub 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
30impl GLSL {
31    /// Gets OpenGL version associated with GLSL.
32    #[allow(non_snake_case)]
33    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
51impl PickShader for GLSL {
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
68impl FromStr for GLSL {
69    type Err = ParseGLSLError;
70
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)]
93pub struct ParseGLSLError{
94    input: String
95}
96
97impl fmt::Display for ParseGLSLError {
98    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99        write!(f, "`{}` is not a valid GLSL version", self.input)
100    }
101}
102
103impl Error for ParseGLSLError {
104    fn description(&self) -> &str {
105        "Invalid GLSL version"
106    }
107}