1use std::ffi::{CString, CStr};
2use std::ptr;
3
4#[allow(dead_code)]
5#[allow(non_camel_case_types)]
6#[allow(non_upper_case_globals)]
7mod bindings;
8
9pub enum ShaderType {
10 Vertex,
11 Fragment,
12}
13
14pub enum Target {
15 OpenGl,
16 OpenGles20,
17 OpenGles30,
18 Metal,
19}
20
21pub struct Context {
22 ctx: *mut bindings::glslopt_ctx,
23}
24
25impl Context {
26 pub fn new(target: Target) -> Self {
27 let target = match target {
28 Target::OpenGl => bindings::glslopt_target_kGlslTargetOpenGL,
29 Target::OpenGles20 => bindings::glslopt_target_kGlslTargetOpenGLES20,
30 Target::OpenGles30 => bindings::glslopt_target_kGlslTargetOpenGLES30,
31 Target::Metal => bindings::glslopt_target_kGlslTargetMetal,
32 };
33
34 let ctx = unsafe { bindings::glslopt_initialize(target) };
35
36 Self {
37 ctx,
38 }
39 }
40
41 pub fn optimize(&self, shader_type: ShaderType, source: String) -> Shader {
42 let shader_type = match shader_type {
43 ShaderType::Vertex => bindings::glslopt_shader_type_kGlslOptShaderVertex,
44 ShaderType::Fragment => bindings::glslopt_shader_type_kGlslOptShaderFragment,
45 };
46 let source = CString::new(source).unwrap();
47
48 let shader = unsafe { bindings::glslopt_optimize(self.ctx, shader_type, source.as_ptr(), 0) };
49 assert_ne!(shader, ptr::null_mut());
50 Shader {
51 shader,
52 }
53 }
54}
55
56impl Drop for Context {
57 fn drop(&mut self) {
58 unsafe {
59 bindings::glslopt_cleanup(self.ctx);
60 }
61 }
62}
63
64pub struct Shader {
65 shader: *mut bindings::glslopt_shader,
66}
67
68impl Shader {
69 pub fn get_status(&self) -> bool {
70 unsafe { bindings::glslopt_get_status(self.shader) }
71 }
72
73 pub fn get_output(&self) -> Result<&str, ()> {
74 unsafe {
75 let cstr = bindings::glslopt_get_output(self.shader);
76 if cstr == ptr::null() {
77 Err(())
78 } else {
79 Ok(CStr::from_ptr(cstr).to_str().unwrap())
80 }
81 }
82 }
83
84 pub fn get_log(&self) -> &str {
85 unsafe {
86 let cstr = bindings::glslopt_get_log(self.shader);
87 if cstr == ptr::null() {
88 ""
89 } else {
90 CStr::from_ptr(cstr).to_str().unwrap()
91 }
92 }
93 }
94}
95
96impl Drop for Shader {
97 fn drop(&mut self) {
98 unsafe {
99 bindings::glslopt_shader_delete(self.shader);
100 }
101 }
102}