Skip to main content

optic_render/
glraw.rs

1use optic_core::{Cull, PolyMode, RGBA, Size2D};
2
3/// Low-level, stateless OpenGL 4.6 wrappers.
4///
5/// Every method is a thin wrapper around a single `gl::*` call — no state tracking,
6/// no error handling. Use [`GPU`](crate::GPU) for stateful rendering.
7///
8/// # Example
9///
10/// ```ignore
11/// optic_render::GL::clear();
12/// optic_render::GL::set_clear(RGBA::grey(0.2));
13/// ```
14pub struct GL;
15
16impl GL {
17    /// Clears the colour and depth buffer of the currently bound framebuffer.
18    pub fn clear() {
19        unsafe { gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); }
20    }
21
22    /// Sets the clear colour for subsequent [`clear`](Self::clear) calls.
23    pub fn set_clear(color: RGBA) {
24        unsafe { gl::ClearColor(color.0, color.1, color.2, color.3); }
25    }
26
27    /// Sets the OpenGL viewport to span `(0, 0, size.w, size.h)`.
28    pub fn resize(size: Size2D) {
29        unsafe { gl::Viewport(0, 0, size.w as i32, size.h as i32); }
30    }
31
32    /// Sets polygon rasterisation mode (filled, wireframe, or points).
33    pub fn poly_mode(mode: PolyMode) {
34        unsafe {
35            match mode {
36                PolyMode::WireFrame => gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE),
37                PolyMode::Filled => gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL),
38                PolyMode::Points => {
39                    gl::PointSize(10.0);
40                    gl::PolygonMode(gl::FRONT_AND_BACK, gl::POINT);
41                }
42            }
43        }
44    }
45
46    /// Enables or disables multisample anti-aliasing.
47    pub fn enable_msaa(enable: bool) {
48        unsafe {
49            match enable {
50                true => gl::Enable(gl::MULTISAMPLE),
51                false => gl::Disable(gl::MULTISAMPLE),
52            }
53        }
54    }
55
56    /// Enables or disables depth testing.
57    pub fn enable_depth(enable: bool) {
58        unsafe {
59            match enable {
60                true => gl::Enable(gl::DEPTH_TEST),
61                false => gl::Disable(gl::DEPTH_TEST),
62            }
63        }
64    }
65
66    /// Enables or disables alpha blending (`SRC_ALPHA`, `ONE_MINUS_SRC_ALPHA`).
67    pub fn enable_alpha(enable: bool) {
68        unsafe {
69            match enable {
70                true => {
71                    gl::Enable(gl::BLEND);
72                    gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
73                }
74                false => gl::Disable(gl::BLEND),
75            }
76        }
77    }
78
79    /// Enables or disables back-face culling.
80    pub fn enable_cull(enable: bool) {
81        unsafe {
82            match enable {
83                true => {
84                    gl::Enable(gl::CULL_FACE);
85                    gl::CullFace(gl::BACK);
86                }
87                false => gl::Disable(gl::CULL_FACE),
88            }
89        }
90    }
91
92    /// Sets the front face winding order (clockwise or counter-clockwise).
93    pub fn set_cull_face(face: Cull) {
94        unsafe {
95            match face {
96                Cull::Clock => gl::FrontFace(gl::CW),
97                Cull::AntiClock => gl::FrontFace(gl::CCW),
98            }
99        }
100    }
101
102    /// Sets the point size (used with [`PolyMode::Points`]).
103    pub fn set_point_size(size: f32) {
104        unsafe { gl::PointSize(size); }
105    }
106
107    /// Sets the line width (used with [`PolyMode::WireFrame`]).
108    pub fn set_wire_width(width: f32) {
109        unsafe { gl::LineWidth(width); }
110    }
111
112    /// Binds a shader program (`glUseProgram`).
113    pub fn bind_shader(id: u32) {
114        unsafe { gl::UseProgram(id); }
115    }
116
117    /// Unbinds the current shader program (binds 0).
118    pub fn unbind_shader() {
119        unsafe { gl::UseProgram(0); }
120    }
121
122    /// Binds a 2D texture to the given texture unit slot.
123    pub fn bind_texture_at(tex_id: u32, slot: u32) {
124        unsafe {
125            gl::ActiveTexture(gl::TEXTURE0 + slot);
126            gl::BindTexture(gl::TEXTURE_2D, tex_id);
127        }
128    }
129
130    /// Unbinds the currently bound 2D texture (binds 0).
131    pub fn unbind_texture() {
132        unsafe { gl::BindTexture(gl::TEXTURE_2D, 0); }
133    }
134
135    /// Binds a vertex array object.
136    pub fn bind_vao(id: u32) {
137        unsafe { gl::BindVertexArray(id); }
138    }
139
140    /// Unbinds the current VAO (binds 0).
141    pub fn unbind_vao() {
142        unsafe { gl::BindVertexArray(0); }
143    }
144
145    /// Binds an array buffer (`GL_ARRAY_BUFFER`).
146    pub fn bind_buffer(id: u32) {
147        unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, id); }
148    }
149
150    /// Unbinds the current array buffer (binds 0).
151    pub fn unbind_buffer() {
152        unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, 0); }
153    }
154
155    /// Binds an element array buffer (`GL_ELEMENT_ARRAY_BUFFER`).
156    pub fn bind_ebo(id: u32) {
157        unsafe { gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, id); }
158    }
159
160    /// Unbinds the current element array buffer (binds 0).
161    pub fn unbind_ebo() {
162        unsafe { gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, 0); }
163    }
164
165    /// Binds a shader storage buffer (`GL_SHADER_STORAGE_BUFFER`).
166    pub fn bind_ssbo(id: u32) {
167        unsafe { gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, id); }
168    }
169
170    /// Unbinds the current SSBO (binds 0).
171    pub fn unbind_ssbo() {
172        unsafe { gl::BindBuffer(gl::SHADER_STORAGE_BUFFER, 0); }
173    }
174}