Source code
Revision control
Copy as Markdown
Other Tools
use std::ffi::{CString, CStr};
use std::ptr;
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
mod bindings;
pub enum ShaderType {
Vertex,
Fragment,
}
pub enum Target {
OpenGl,
OpenGles20,
OpenGles30,
Metal,
}
pub struct Context {
ctx: *mut bindings::glslopt_ctx,
}
impl Context {
pub fn new(target: Target) -> Self {
let target = match target {
Target::OpenGl => bindings::glslopt_target_kGlslTargetOpenGL,
Target::OpenGles20 => bindings::glslopt_target_kGlslTargetOpenGLES20,
Target::OpenGles30 => bindings::glslopt_target_kGlslTargetOpenGLES30,
Target::Metal => bindings::glslopt_target_kGlslTargetMetal,
};
let ctx = unsafe { bindings::glslopt_initialize(target) };
Self {
ctx,
}
}
pub fn optimize(&self, shader_type: ShaderType, source: String) -> Shader {
let shader_type = match shader_type {
ShaderType::Vertex => bindings::glslopt_shader_type_kGlslOptShaderVertex,
ShaderType::Fragment => bindings::glslopt_shader_type_kGlslOptShaderFragment,
};
let source = CString::new(source).unwrap();
let shader = unsafe { bindings::glslopt_optimize(self.ctx, shader_type, source.as_ptr(), 0) };
assert_ne!(shader, ptr::null_mut());
Shader {
shader,
}
}
}
impl Drop for Context {
fn drop(&mut self) {
unsafe {
bindings::glslopt_cleanup(self.ctx);
}
}
}
pub struct Shader {
shader: *mut bindings::glslopt_shader,
}
impl Shader {
pub fn get_status(&self) -> bool {
unsafe { bindings::glslopt_get_status(self.shader) }
}
pub fn get_output(&self) -> Result<&str, ()> {
unsafe {
let cstr = bindings::glslopt_get_output(self.shader);
if cstr == ptr::null() {
Err(())
} else {
Ok(CStr::from_ptr(cstr).to_str().unwrap())
}
}
}
pub fn get_log(&self) -> &str {
unsafe {
let cstr = bindings::glslopt_get_log(self.shader);
if cstr == ptr::null() {
""
} else {
CStr::from_ptr(cstr).to_str().unwrap()
}
}
}
}
impl Drop for Shader {
fn drop(&mut self) {
unsafe {
bindings::glslopt_shader_delete(self.shader);
}
}
}