1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! The CGL Graphics Module

#![allow(non_camel_case_types)]

use std::result;
use libc::{c_void, c_int, c_float};

mod framebuffer;
pub use framebuffer::*;

mod texture;
pub use texture::*;

mod shader;
pub use shader::*;

mod ssbo;
pub use ssbo::*;

mod mesh;
pub use mesh::*;

mod bloom;
pub use bloom::*;

mod tilemap;
pub use tilemap::*;

pub mod text;

pub mod widgets;

extern {
    fn CGL_gl_init() -> c_int;
    fn CGL_gl_shutdown() -> c_void;
    fn CGL_gl_clear(r: c_float, g: c_float, b: c_float, a: c_float) -> c_void;
    fn CGL_gl_render_screen_quad() -> c_void;
}


/// Initializes the CGL Graphics Module.
///
/// Note: This method should only be called after there exists a valid OpenGL context.
/// 
/// # Returns
///
/// Returns `Ok(())` if the initialization was successful, otherwise returns `Err(())`.
/// 
/// # Example
/// 
/// ```
/// cgl_rs::init().expect("Failed to initialize CGL");
/// let mut window = cgl_rs::Window::new("My Window", 800, 600).unwrap();
/// window.make_context_current();
/// cgl_rs::graphics::init().expect("Failed to initialize CGL Graphics Module");
/// // ...
/// cgl_rs::graphics::shutdown();
/// window.destroy();
/// cgl_rs::shutdown();
/// ```
pub fn init() -> result::Result<(), ()> {
    unsafe {
        let result = CGL_gl_init();
        if result == 0 {
            Err(())
        } else {
            Ok(())
        }   
    }
}

/// Shuts down the CGL Graphics Module.
/// 
/// This function should be called before cgl_rs::shutdown().
/// 
/// # Example
/// 
/// ```
/// cgl_rs::init().expect("Failed to initialize CGL");
/// let mut window = cgl_rs::Window::new("My Window", 800, 600).unwrap();
/// cgl_rs::graphics::init().expect("Failed to initialize CGL Graphics Module");
/// // ...
/// cgl_rs::graphics::shutdown();
/// window.destroy();
/// cgl_rs::shutdown();
pub fn shutdown() -> () {
    unsafe {
        CGL_gl_shutdown();
    }
}



/// Clears the screen with the specified color.
///
/// # Arguments
///
/// * `r` - The red component of the color, in the range [0.0, 1.0].
/// * `g` - The green component of the color, in the range [0.0, 1.0].
/// * `b` - The blue component of the color, in the range [0.0, 1.0].
/// * `a` - The alpha component of the color, in the range [0.0, 1.0].
///
/// # Example
///
/// ```
/// cgl_rs::init().expect("Failed to initialize CGL");
/// let mut window = cgl_rs::Window::new("My Window", 800, 600).unwrap();
/// cgl_rs::graphics::init().expect("Failed to initialize CGL Graphics Module");
/// cgl_rs::graphics::clear(0.0, 0.0, 0.0, 1.0); // Clears the screen to black
/// // ...
/// cgl_rs::graphics::shutdown();
/// window.destroy();
/// cgl_rs::shutdown();
/// ```
pub fn clear(r: f32, g: f32, b: f32, a: f32) -> () {
    unsafe {
        CGL_gl_clear(r, g, b, a);
    }
}

/// Renders a screen quad.
///
/// # Example
///
/// ```
/// cgl_rs::init().expect("Failed to initialize CGL");
/// let mut window = cgl_rs::Window::new("My Window", 800, 600).unwrap();
/// cgl_rs::graphics::init().expect("Failed to initialize CGL Graphics Module");
/// cgl_rs::graphics::render_screen_quad(); // Renders a screen quad
/// // ...
/// cgl_rs::graphics::shutdown();
/// window.destroy();
/// cgl_rs::shutdown();
/// ```
pub fn render_screen_quad() -> () {
    unsafe {
        CGL_gl_render_screen_quad();
    }
}