1use gl;
2use gl::types::{GLint, GLfloat, GLsizeiptr};
3use std::ffi::CString;
4use std::mem;
5use std::os::raw::c_void;
6use std::ptr;
7
8pub fn init() {
9
10}
11
12pub fn create_shader(shader_type: u32) -> u32 {
13 unsafe {
14 gl::CreateShader(shader_type)
15 }
16}
17
18pub fn shader_source(shader: u32, source: &str) {
19 unsafe {
20 let cstr = CString::new(source.as_bytes()).unwrap();
21 gl::ShaderSource(shader, 1, &cstr.as_ptr(), ptr::null());
22 }
23}
24
25pub fn compile_shader(shader: u32) {
26 unsafe {
27 gl::CompileShader(shader);
28
29 let mut success = gl::FALSE as GLint;
30 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success);
31 if success != gl::TRUE as GLint {
32 let mut bytes: [i8; 512] = [0;512];
33 gl::GetShaderInfoLog(shader, 512, ptr::null_mut(), &mut bytes[0] as *mut i8);
34 let u8bytes = &*(&bytes[..] as *const [i8] as *const [u8]);
35 gl::DeleteShader(shader);
36 panic!("Failed to compile shader: {}", std::str::from_utf8(u8bytes).unwrap());
37 }
38 }
39}
40
41pub fn create_program() -> u32 {
42 unsafe {
43 gl::CreateProgram()
44 }
45}
46
47pub fn attach_shader(program: u32, shader: u32) {
48 unsafe {
49 gl::AttachShader(program, shader);
50 }
51}
52
53pub fn link_program(program: u32) {
54 unsafe {
55 gl::LinkProgram(program);
56
57 let mut success = gl::FALSE as GLint;
58 gl::GetProgramiv(program, gl::LINK_STATUS, &mut success);
59 if success != gl::TRUE as GLint {
60 let mut bytes: [i8; 512] = [0;512];
61 gl::GetProgramInfoLog(program, 512, ptr::null_mut(), &mut bytes[0] as *mut i8);
62 let u8bytes = &*(&bytes[..] as *const [i8] as *const [u8]);
63 gl::DeleteProgram(program);
64 panic!("Failed to link program: {}", std::str::from_utf8(u8bytes).unwrap());
65 }
66 }
67}
68
69pub fn use_program(program: u32) {
70 unsafe {
71 gl::UseProgram(program);
72 }
73}
74
75pub fn clear_color(r: f32, g: f32, b: f32, a: f32) {
76 unsafe {
77 gl::ClearColor(r, g, b, a);
78 }
79}
80
81pub fn get_active_uniform_count(program: u32) -> u32 {
82 let mut count: i32 = 0;
83 unsafe {
84 gl::GetProgramiv(program, gl::ACTIVE_UNIFORMS, &mut count);
85 }
86 return count as u32;
87}
88
89pub fn get_active_uniform(program: u32, index: u32) -> (String, i32, u32) {
90 unsafe {
91 let mut buf: [i8; 128] = [0;128];
92 let mut name_length: i32 = 0;
93 let mut size: i32 = 0;
94 let mut uniform_type: u32 = 0;
95 gl::GetActiveUniform(program, index, 128, &mut name_length, &mut size, &mut uniform_type, &mut buf[0] as *mut i8);
96 let mut bytes: Vec<u8> = Vec::with_capacity(name_length as usize);
97 for i in 0..name_length {
98 bytes.push(buf[i as usize] as u8);
99 }
100 let name = String::from_utf8(bytes).unwrap();
101 (name, size, uniform_type)
102 }
103}
104
105pub fn get_uniform_location(program: u32, name: &str) -> i32 {
106 unsafe {
107 gl::GetUniformLocation(
108 program,
109 CString::new(name).unwrap().as_ptr()
110 )
111 }
112}
113
114pub fn get_active_attribute_count(program: u32) -> u32 {
115 let mut count: i32 = 0;
116 unsafe {
117 gl::GetProgramiv(program, gl::ACTIVE_ATTRIBUTES, &mut count);
118 }
119 return count as u32;
120}
121
122pub fn get_active_attribute(program: u32, index: u32) -> (String, i32, u32) {
123 unsafe {
124 let mut buf: [i8; 128] = [0;128];
125 let mut name_length: i32 = 0;
126 let mut size: i32 = 0;
127 let mut uniform_type: u32 = 0;
128 gl::GetActiveAttrib(program, index, 128, &mut name_length, &mut size, &mut uniform_type, &mut buf[0] as *mut i8);
129 let mut bytes: Vec<u8> = Vec::with_capacity(name_length as usize);
130 for i in 0..name_length {
131 bytes.push(buf[i as usize] as u8);
132 }
133 let name = String::from_utf8(bytes).unwrap();
134 (name, size, uniform_type)
135 }
136}
137
138pub fn get_attribute_location(program: u32, name: &str) -> i32 {
139 unsafe {
140 gl::GetAttribLocation(
141 program,
142 CString::new(name).unwrap().as_ptr()
143 )
144 }
145}
146
147pub fn get_attribute_size_and_type(attr_type: u32, normalize: bool) -> (i32, u32) {
148 let t = if normalize { gl::UNSIGNED_BYTE } else { gl::FLOAT };
149 match attr_type {
150 gl::FLOAT => (1, t),
151 gl::FLOAT_VEC2 => (2, t),
152 gl::FLOAT_VEC3 => (3, t),
153 gl::FLOAT_VEC4 => (4, t),
154 gl::FLOAT_MAT2 => (4, t),
155 gl::FLOAT_MAT3 => (9, t),
156 gl::FLOAT_MAT4 => (16, t),
157 _ => (1, t),
158 }
159}
160
161pub fn size_of_type(gl_type: u32) -> i32 {
162 match gl_type {
163 gl::BYTE => 1,
164 gl::UNSIGNED_BYTE => 1,
165 gl::SHORT => 2,
166 gl::UNSIGNED_SHORT => 2,
167 gl::FLOAT => 4,
168 _ => 1,
169 }
170}
171
172pub fn create_vertex_array() -> u32 {
173 unsafe {
174 let mut vao = 0;
175 gl::GenVertexArrays(1, &mut vao);
176 vao
177 }
178}
179
180pub fn bind_vertex_array(array: u32) {
181 unsafe {
182 gl::BindVertexArray(array);
183 }
184}
185
186pub fn create_buffer() -> u32 {
187 unsafe {
188 let mut vbo = 0;
189 gl::GenBuffers(1, &mut vbo);
190 vbo
191 }
192}
193
194pub fn bind_array_buffer(buffer: u32) {
195 unsafe {
196 gl::BindBuffer(gl::ARRAY_BUFFER, buffer);
197 }
198}
199
200pub fn bind_element_array_buffer(buffer: u32) {
201 unsafe {
202 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, buffer);
203 }
204}
205
206pub fn draw_arrays_triangles(count: i32) {
207 unsafe {
208 gl::DrawArrays(gl::TRIANGLES, 0, count);
209 }
210}
211
212pub fn draw_elements_triangles(count: i32) {
213 unsafe {
214 gl::DrawElements(gl::TRIANGLES, count, gl::UNSIGNED_SHORT, ptr::null());
215 }
216}
217
218pub fn buffer_array_data(data: &[f32]) {
219 let float_size = mem::size_of::<GLfloat>();
220 unsafe {
221 gl::BufferData(
222 gl::ARRAY_BUFFER,
223 (data.len() * float_size) as GLsizeiptr,
224 &data[0] as *const f32 as *const c_void,
225 gl::STATIC_DRAW
226 );
227 }
228}
229
230pub fn vertex_attrib_pointer(location: u32, size: i32, gl_type: u32, normalized: bool, stride: i32, offset: i32) {
231 unsafe {
232 let normalized_value = if normalized { gl::TRUE } else { gl::FALSE };
233 gl::VertexAttribPointer(location, size, gl_type, normalized_value, stride, ptr::null());
234 }
235}
236
237pub fn enable_vertex_attrib_array(location: u32) {
238 unsafe {
239 gl::EnableVertexAttribArray(location);
240 }
241}
242
243pub fn uniform_1f(location: u32, f: f32) {
244 unsafe {
245 gl::Uniform1f(location as i32, f);
246 }
247}
248
249pub fn uniform_2f(location: u32, x: f32, y: f32) {
250 unsafe {
251 gl::Uniform2f(location as i32, x, y);
252 }
253}
254
255pub fn uniform_3f(location: u32, x: f32, y: f32, z: f32) {
256 unsafe {
257 gl::Uniform3f(location as i32, x, y, z);
258 }
259}
260
261pub fn uniform_4f(location: u32, x: f32, y: f32, z: f32, w: f32) {
262 unsafe {
263 gl::Uniform4f(location as i32, x, y, z, w);
264 }
265}
266
267pub fn uniform_1i(location: u32, i: i32) {
268 unsafe {
269 gl::Uniform1i(location as i32, i);
270 }
271}
272
273pub fn uniform_2i(location: u32, x: i32, y: i32) {
274 unsafe {
275 gl::Uniform2i(location as i32, x, y);
276 }
277}
278
279pub fn uniform_3i(location: u32, x: i32, y: i32, z: i32) {
280 unsafe {
281 gl::Uniform3i(location as i32, x, y, z);
282 }
283}
284
285pub fn uniform_4i(location: u32, x: i32, y: i32, z: i32, w: i32) {
286 unsafe {
287 gl::Uniform4i(location as i32, x, y, z, w);
288 }
289}
290
291pub fn create_texture() -> u32 {
292 unsafe {
293 let mut t = 0;
294 gl::GenTextures(1, &mut t);
295 t
296 }
297}
298
299pub fn active_texture(unit: u32) {
300 unsafe {
301 gl::ActiveTexture(gl::TEXTURE0 + unit);
302 }
303}
304
305pub fn bind_texture_2d(unit: u32) {
306 unsafe {
307 gl::BindTexture(gl::TEXTURE_2D, unit);
308 }
309}
310
311pub fn tex_parameter_2d(param: u32, value: u32) {
312 unsafe {
313 gl::TexParameteri(gl::TEXTURE_2D, param, value as i32);
314 }
315}
316
317pub fn tex_image_2d_from_bytes(internal_format: u32, width: i32, height: i32, format: u32, data: *const u8) {
318 unsafe {
319 gl::TexImage2D(gl::TEXTURE_2D, 0, internal_format as i32, width, height, 0, format, gl::UNSIGNED_BYTE, data as *const c_void);
320 }
321}
322
323pub use gl::TEXTURE_MIN_FILTER;
324pub use gl::TEXTURE_MAG_FILTER;
325pub use gl::TEXTURE_WRAP_S;
326pub use gl::TEXTURE_WRAP_T;
327
328pub use gl::NEAREST;
329pub use gl::LINEAR;
330pub use gl::CLAMP_TO_EDGE;
331pub use gl::REPEAT;
332
333pub use gl::R8UI;
334pub use gl::RGB;
335pub use gl::RGBA;
336pub use gl::RED_INTEGER;