use crate::gl;
use std::ffi::CStr;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum OpenGlApi {
Desktop,
ES,
}
#[derive(Clone, Debug, PartialEq)]
pub enum OpenGlVersion {
Available {
api: OpenGlApi,
major: u8,
minor: u8,
},
Unavailable {
version_string: String,
},
}
pub(crate) fn get_version() -> OpenGlVersion {
let version_str = unsafe { CStr::from_ptr(gl::GetString(gl::VERSION) as *const _) };
let version_str = version_str.to_string_lossy();
if let Some((es, major, minor)) = parse_version(&version_str) {
OpenGlVersion::Available {
api: if es {
OpenGlApi::ES
} else {
OpenGlApi::Desktop
},
major,
minor,
}
} else {
OpenGlVersion::Unavailable {
version_string: version_str.to_string(),
}
}
}
fn parse_version(version_str: &str) -> Option<(bool, u8, u8)> {
let mut es = false;
let version_str = if version_str.starts_with("OpenGL ES-") {
if version_str.len() < 16 {
return None;
}
es = true;
&version_str[13..]
} else {
&version_str
};
let mut split = version_str.split('.'); let major_str = &split.next()?; let major = u8::from_str_radix(major_str, 10).ok()?;
let rest_of_version = split.next()?; let end_of_version_num = rest_of_version
.find(|c: char| !c.is_digit(10))
.unwrap_or_else(|| rest_of_version.len()); let minor_str = &rest_of_version[0..end_of_version_num]; let minor = u8::from_str_radix(minor_str, 10).ok()?;
Some((es, major, minor))
}