1pub mod gl {
6 pub use self::ffi::types::*;
7 pub use self::ffi::*;
8 use std::ffi::{CStr, CString};
9 use std::mem::size_of;
10 use std::os::raw::{c_char, c_int, c_void};
11 use std::ptr;
12 use std::rc::Rc;
13 use std::str;
14
15 #[derive(Copy, Clone, Debug, PartialEq)]
16 pub enum GlType {
17 Gl,
18 Gles,
19 }
20
21 pub enum Gl {
22 Gl(self::ffi_gl::Gl),
23 Gles(self::ffi_gles::Gles2),
24 }
25
26 pub enum TexImageSource<'a> {
27 Pixels(Option<&'a [u8]>),
28 BufferOffset(i64),
29 }
30
31 impl Gl {
32 pub fn get_type(&self) -> GlType {
33 match self {
34 Gl::Gl(..) => GlType::Gl,
35 Gl::Gles(..) => GlType::Gles,
36 }
37 }
38
39 pub fn gl_fns(gl: self::ffi_gl::Gl) -> Rc<Gl> {
40 Rc::new(Gl::Gl(gl))
41 }
42
43 pub fn gles_fns(gl: self::ffi_gles::Gles2) -> Rc<Gl> {
44 Rc::new(Gl::Gles(gl))
45 }
46
47 pub fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint> {
48 let mut ids = vec![0 as GLuint; n as usize];
49 match self {
50 Gl::Gl(gl) => unsafe { gl.GenFramebuffers(n, ids.as_mut_ptr()) },
51 Gl::Gles(gles) => unsafe { gles.GenFramebuffers(n, ids.as_mut_ptr()) },
52 }
53 ids
54 }
55
56 pub fn gen_textures(&self, n: GLsizei) -> Vec<GLuint> {
57 let mut ids = vec![0 as GLuint; n as usize];
58 match self {
59 Gl::Gl(gl) => unsafe { gl.GenTextures(n, ids.as_mut_ptr()) },
60 Gl::Gles(gles) => unsafe { gles.GenTextures(n, ids.as_mut_ptr()) },
61 }
62 ids
63 }
64
65 pub fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint> {
66 let mut ids = vec![0 as GLuint; n as usize];
67 match self {
68 Gl::Gl(gl) => unsafe { gl.GenRenderbuffers(n, ids.as_mut_ptr()) },
69 Gl::Gles(gles) => unsafe { gles.GenRenderbuffers(n, ids.as_mut_ptr()) },
70 }
71 ids
72 }
73
74 pub fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint> {
75 let mut ids = vec![0 as GLuint; n as usize];
76 match self {
77 Gl::Gl(gl) => unsafe { gl.GenBuffers(n, ids.as_mut_ptr()) },
78 Gl::Gles(gles) => unsafe { gles.GenBuffers(n, ids.as_mut_ptr()) },
79 }
80 ids
81 }
82
83 pub fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint> {
84 let mut ids = vec![0 as GLuint; n as usize];
85 match self {
86 Gl::Gl(gl) => unsafe { gl.GenVertexArrays(n, ids.as_mut_ptr()) },
87 Gl::Gles(gles) => unsafe { gles.GenVertexArrays(n, ids.as_mut_ptr()) },
88 }
89 ids
90 }
91
92 pub fn shader_source(&self, shader: GLuint, strings: &[&[u8]]) {
93 let pointers: Vec<*const u8> =
94 strings.iter().map(|string| (*string).as_ptr()).collect();
95 let lengths: Vec<GLint> = strings.iter().map(|string| string.len() as GLint).collect();
96 let len = pointers.len() as GLsizei;
97 let pointers = pointers.as_ptr() as *const *const GLchar;
98 match self {
99 Gl::Gl(gl) => unsafe { gl.ShaderSource(shader, len, pointers, lengths.as_ptr()) },
100 Gl::Gles(gles) => unsafe {
101 gles.ShaderSource(shader, len, pointers, lengths.as_ptr())
102 },
103 }
104 }
105
106 pub fn create_program(&self) -> GLuint {
107 match self {
108 Gl::Gl(gl) => unsafe { gl.CreateProgram() },
109 Gl::Gles(gles) => unsafe { gles.CreateProgram() },
110 }
111 }
112
113 pub fn tex_image_2d(
114 &self,
115 target: GLenum,
116 level: GLint,
117 internal_format: GLint,
118 width: GLsizei,
119 height: GLsizei,
120 border: GLint,
121 format: GLenum,
122 ty: GLenum,
123 source: TexImageSource,
124 ) {
125 let data = match source {
126 TexImageSource::Pixels(pixels) => {
127 pixels.map(|d| d.as_ptr()).unwrap_or(ptr::null()) as *const _
128 },
129 TexImageSource::BufferOffset(offset) => unsafe {
130 let mut buffer = [0];
131 self.get_integer_v(PIXEL_UNPACK_BUFFER_BINDING, &mut buffer);
132 assert!(buffer[0] != 0);
133 offset as *const _
134 }
135 };
136 match self {
137 Gl::Gl(gl) => unsafe {
138 gl.TexImage2D(
139 target,
140 level,
141 internal_format,
142 width,
143 height,
144 border,
145 format,
146 ty,
147 data,
148 )
149 },
150 Gl::Gles(gles) => unsafe {
151 gles.TexImage2D(
152 target,
153 level,
154 internal_format,
155 width,
156 height,
157 border,
158 format,
159 ty,
160 data,
161 )
162 },
163 }
164 }
165
166 pub fn tex_sub_image_2d(
167 &self,
168 target: GLenum,
169 level: GLint,
170 xoffset: GLint,
171 yoffset: GLint,
172 width: GLsizei,
173 height: GLsizei,
174 format: GLenum,
175 ty: GLenum,
176 data: &[u8],
177 ) {
178 let data = data.as_ptr() as *const c_void;
179 match self {
180 Gl::Gl(gl) => unsafe {
181 gl.TexSubImage2D(
182 target, level, xoffset, yoffset, width, height, format, ty, data,
183 )
184 },
185 Gl::Gles(gles) => unsafe {
186 gles.TexSubImage2D(
187 target, level, xoffset, yoffset, width, height, format, ty, data,
188 )
189 },
190 }
191 }
192
193 pub fn copy_tex_image_2d(
194 &self,
195 target: GLenum,
196 level: GLint,
197 internal_format: GLenum,
198 x: GLint,
199 y: GLint,
200 width: GLsizei,
201 height: GLsizei,
202 border: GLint,
203 ) {
204 match self {
205 Gl::Gl(gl) => unsafe {
206 gl.CopyTexImage2D(target, level, internal_format, x, y, width, height, border)
207 },
208 Gl::Gles(gles) => unsafe {
209 gles.CopyTexImage2D(target, level, internal_format, x, y, width, height, border)
210 },
211 }
212 }
213
214 pub fn copy_tex_sub_image_2d(
215 &self,
216 target: GLenum,
217 level: GLint,
218 xoffset: GLint,
219 yoffset: GLint,
220 x: GLint,
221 y: GLint,
222 width: GLsizei,
223 height: GLsizei,
224 ) {
225 match self {
226 Gl::Gl(gl) => unsafe {
227 gl.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height)
228 },
229 Gl::Gles(gles) => unsafe {
230 gles.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height)
231 },
232 }
233 }
234
235 pub fn compressed_tex_image_2d(
236 &self,
237 target: GLenum,
238 level: GLint,
239 internal_format: GLenum,
240 width: GLsizei,
241 height: GLsizei,
242 border: GLint,
243 data: &[u8],
244 ) {
245 let len = data.len() as GLsizei;
246 let data = data.as_ptr() as *const c_void;
247 match self {
248 Gl::Gl(gl) => unsafe {
249 gl.CompressedTexImage2D(
250 target,
251 level,
252 internal_format,
253 width,
254 height,
255 border,
256 len,
257 data,
258 )
259 },
260 Gl::Gles(gles) => unsafe {
261 gles.CompressedTexImage2D(
262 target,
263 level,
264 internal_format,
265 width,
266 height,
267 border,
268 len,
269 data,
270 )
271 },
272 }
273 }
274
275 pub fn compressed_tex_sub_image_2d(
276 &self,
277 target: GLenum,
278 level: GLint,
279 xoffset: GLint,
280 yoffset: GLint,
281 width: GLsizei,
282 height: GLsizei,
283 format: GLenum,
284 data: &[u8],
285 ) {
286 let len = data.len() as GLsizei;
287 let data = data.as_ptr() as *const c_void;
288 match self {
289 Gl::Gl(gl) => unsafe {
290 gl.CompressedTexSubImage2D(
291 target, level, xoffset, yoffset, width, height, format, len, data,
292 )
293 },
294 Gl::Gles(gles) => unsafe {
295 gles.CompressedTexSubImage2D(
296 target, level, xoffset, yoffset, width, height, format, len, data,
297 )
298 },
299 }
300 }
301
302 pub fn tex_storage_2d(
303 &self,
304 target: GLenum,
305 levels: GLsizei,
306 internal_format: GLenum,
307 width: GLsizei,
308 height: GLsizei,
309 ) {
310 match self {
311 Gl::Gl(gl) => unsafe {
312 gl.TexStorage2D(target, levels, internal_format, width, height)
313 },
314 Gl::Gles(gles) => unsafe {
315 gles.TexStorage2D(target, levels, internal_format, width, height)
316 },
317 }
318 }
319
320 pub fn tex_storage_3d(
321 &self,
322 target: GLenum,
323 levels: GLsizei,
324 internal_format: GLenum,
325 width: GLsizei,
326 height: GLsizei,
327 depth: GLsizei,
328 ) {
329 match self {
330 Gl::Gl(gl) => unsafe {
331 gl.TexStorage3D(target, levels, internal_format, width, height, depth)
332 },
333 Gl::Gles(gles) => unsafe {
334 gles.TexStorage3D(target, levels, internal_format, width, height, depth)
335 },
336 }
337 }
338
339 pub fn generate_mipmap(&self, target: GLenum) {
340 match self {
341 Gl::Gl(gl) => unsafe { gl.GenerateMipmap(target) },
342 Gl::Gles(gles) => unsafe { gles.GenerateMipmap(target) },
343 }
344 }
345
346 pub fn active_texture(&self, texture: GLenum) {
347 match self {
348 Gl::Gl(gl) => unsafe { gl.ActiveTexture(texture) },
349 Gl::Gles(gles) => unsafe { gles.ActiveTexture(texture) },
350 }
351 }
352
353 pub fn attach_shader(&self, program: GLuint, shader: GLuint) {
354 match self {
355 Gl::Gl(gl) => unsafe { gl.AttachShader(program, shader) },
356 Gl::Gles(gles) => unsafe { gles.AttachShader(program, shader) },
357 }
358 }
359
360 pub fn create_shader(&self, shader_type: GLenum) -> GLuint {
361 match self {
362 Gl::Gl(gl) => unsafe { gl.CreateShader(shader_type) },
363 Gl::Gles(gles) => unsafe { gles.CreateShader(shader_type) },
364 }
365 }
366
367 pub fn delete_shader(&self, shader: GLuint) {
368 match self {
369 Gl::Gl(gl) => unsafe { gl.DeleteShader(shader) },
370 Gl::Gles(gles) => unsafe { gles.DeleteShader(shader) },
371 }
372 }
373
374 pub fn detach_shader(&self, program: GLuint, shader: GLuint) {
375 match self {
376 Gl::Gl(gl) => unsafe { gl.DetachShader(program, shader) },
377 Gl::Gles(gles) => unsafe { gles.DetachShader(program, shader) },
378 }
379 }
380
381 pub fn bind_buffer(&self, target: GLenum, buffer: GLuint) {
382 match self {
383 Gl::Gl(gl) => unsafe { gl.BindBuffer(target, buffer) },
384 Gl::Gles(gles) => unsafe { gles.BindBuffer(target, buffer) },
385 }
386 }
387
388 pub fn delete_buffers(&self, buffers: &[GLuint]) {
389 let len = buffers.len() as GLsizei;
390 let buffers = buffers.as_ptr();
391 match self {
392 Gl::Gl(gl) => unsafe { gl.DeleteBuffers(len, buffers) },
393 Gl::Gles(gles) => unsafe { gles.DeleteBuffers(len, buffers) },
394 }
395 }
396
397 pub fn copy_buffer_sub_data(
398 &self,
399 read_target: u32,
400 write_target: u32,
401 read_offset: isize,
402 write_offset: isize,
403 size: isize,
404 ) {
405 match self {
406 Gl::Gl(gl) => unsafe { gl.CopyBufferSubData(read_target, write_target, read_offset, write_offset, size) },
407 Gl::Gles(gles) => unsafe { gles.CopyBufferSubData(read_target, write_target, read_offset, write_offset, size) },
408 }
409 }
410
411 pub fn map_buffer_range(
412 &self,
413 target: GLenum,
414 offset: GLintptr,
415 length: GLsizeiptr,
416 access: GLbitfield,
417 ) -> *mut c_void {
418 match self {
419 Gl::Gl(gl) => unsafe { gl.MapBufferRange(target, offset, length, access) },
420 Gl::Gles(gles) => unsafe { gles.MapBufferRange(target, offset, length, access) },
421 }
422 }
423
424 pub fn unmap_buffer(&self, target: GLenum) {
425 match self {
426 Gl::Gl(gl) => unsafe { gl.UnmapBuffer(target); },
427 Gl::Gles(gles) => unsafe { gles.UnmapBuffer(target); },
428 }
429 }
430
431 pub fn link_program(&self, program: GLuint) {
432 match self {
433 Gl::Gl(gl) => unsafe { gl.LinkProgram(program) },
434 Gl::Gles(gles) => unsafe { gles.LinkProgram(program) },
435 }
436 }
437
438 pub fn validate_program(&self, program: GLuint) {
439 match self {
440 Gl::Gl(gl) => unsafe { gl.ValidateProgram(program) },
441 Gl::Gles(gles) => unsafe { gles.ValidateProgram(program) },
442 }
443 }
444
445 pub fn delete_program(&self, program: GLuint) {
446 match self {
447 Gl::Gl(gl) => unsafe { gl.DeleteProgram(program) },
448 Gl::Gles(gles) => unsafe { gles.DeleteProgram(program) },
449 }
450 }
451
452 pub fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]) {
453 let len = vertex_arrays.len() as GLsizei;
454 match self {
455 Gl::Gl(gl) => unsafe { gl.DeleteVertexArrays(len, vertex_arrays.as_ptr()) },
456 Gl::Gles(gles) => unsafe { gles.DeleteVertexArrays(len, vertex_arrays.as_ptr()) },
457 }
458 }
459
460 pub fn bind_vertex_array(&self, vao: GLuint) {
461 match self {
462 Gl::Gl(gl) => unsafe { gl.BindVertexArray(vao) },
463 Gl::Gles(gles) => unsafe { gles.BindVertexArray(vao) },
464 }
465 }
466
467 pub fn enable_vertex_attrib_array(&self, index: GLuint) {
468 match self {
469 Gl::Gl(gl) => unsafe { gl.EnableVertexAttribArray(index) },
470 Gl::Gles(gles) => unsafe { gles.EnableVertexAttribArray(index) },
471 }
472 }
473
474 pub fn disable_vertex_attrib_array(&self, index: GLuint) {
475 match self {
476 Gl::Gl(gl) => unsafe { gl.DisableVertexAttribArray(index) },
477 Gl::Gles(gles) => unsafe { gles.DisableVertexAttribArray(index) },
478 }
479 }
480
481 pub fn vertex_attrib_4f(
482 &self,
483 index: GLuint,
484 x: GLfloat,
485 y: GLfloat,
486 z: GLfloat,
487 w: GLfloat,
488 ) {
489 match self {
490 Gl::Gl(gl) => unsafe { gl.VertexAttrib4f(index, x, y, z, w) },
491 Gl::Gles(gles) => unsafe { gles.VertexAttrib4f(index, x, y, z, w) },
492 }
493 }
494
495 pub fn vertex_attrib_4i(
496 &self,
497 index: GLuint,
498 x: GLint,
499 y: GLint,
500 z: GLint,
501 w: GLint,
502 ) {
503 match self {
504 Gl::Gl(gl) => unsafe { gl.VertexAttribI4i(index, x, y, z, w) },
505 Gl::Gles(gles) => unsafe { gles.VertexAttribI4i(index, x, y, z, w) },
506 }
507 }
508
509 pub fn vertex_attrib_4ui(
510 &self,
511 index: GLuint,
512 x: GLuint,
513 y: GLuint,
514 z: GLuint,
515 w: GLuint,
516 ) {
517 match self {
518 Gl::Gl(gl) => unsafe { gl.VertexAttribI4ui(index, x, y, z, w) },
519 Gl::Gles(gles) => unsafe { gles.VertexAttribI4ui(index, x, y, z, w) },
520 }
521 }
522
523 pub fn vertex_attrib_pointer_f32(
524 &self,
525 index: GLuint,
526 size: GLint,
527 normalized: bool,
528 stride: GLsizei,
529 offset: GLuint,
530 ) {
531 self.vertex_attrib_pointer(index, size, ffi::FLOAT, normalized, stride, offset)
532 }
533
534 pub fn vertex_attrib_pointer(
535 &self,
536 index: GLuint,
537 size: GLint,
538 type_: GLenum,
539 normalized: bool,
540 stride: GLsizei,
541 offset: GLuint,
542 ) {
543 let normalized = normalized as GLboolean;
544 let offset = offset as *const GLvoid;
545 match self {
546 Gl::Gl(gl) => unsafe {
547 gl.VertexAttribPointer(index, size, type_, normalized, stride, offset)
548 },
549 Gl::Gles(gles) => unsafe {
550 gles.VertexAttribPointer(index, size, type_, normalized, stride, offset)
551 },
552 }
553 }
554
555 pub fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) {
556 match self {
557 Gl::Gl(gl) => unsafe { gl.VertexAttribDivisor(index, divisor) },
558 Gl::Gles(gles) => unsafe { gles.VertexAttribDivisor(index, divisor) },
559 }
560 }
561
562 pub fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) {
563 let c_string = CString::new(name).unwrap();
564 match self {
565 Gl::Gl(gl) => unsafe { gl.BindAttribLocation(program, index, c_string.as_ptr()) },
566 Gl::Gles(gles) => unsafe {
567 gles.BindAttribLocation(program, index, c_string.as_ptr())
568 },
569 }
570 }
571
572 pub unsafe fn get_uniform_iv(
573 &self,
574 program: GLuint,
575 location: GLint,
576 result: &mut [GLint],
577 ) {
578 match self {
579 Gl::Gl(gl) => gl.GetUniformiv(program, location, result.as_mut_ptr()),
580 Gl::Gles(gles) => gles.GetUniformiv(program, location, result.as_mut_ptr()),
581 }
582 }
583
584 pub unsafe fn get_uniform_uiv(
585 &self,
586 program: GLuint,
587 location: GLint,
588 result: &mut [GLuint],
589 ) {
590 match self {
591 Gl::Gl(gl) => gl.GetUniformuiv(program, location, result.as_mut_ptr()),
592 Gl::Gles(gles) => gles.GetUniformuiv(program, location, result.as_mut_ptr()),
593 }
594 }
595
596 pub unsafe fn get_uniform_fv(
597 &self,
598 program: GLuint,
599 location: GLint,
600 result: &mut [GLfloat],
601 ) {
602 match self {
603 Gl::Gl(gl) => gl.GetUniformfv(program, location, result.as_mut_ptr()),
604 Gl::Gles(gles) => gles.GetUniformfv(program, location, result.as_mut_ptr()),
605 }
606 }
607
608 pub fn hint(&self, param_name: GLenum, param_val: GLenum) {
609 match self {
610 Gl::Gl(gl) => unsafe { gl.Hint(param_name, param_val) },
611 Gl::Gles(gles) => unsafe { gles.Hint(param_name, param_val) },
612 }
613 }
614
615 pub fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) {
616 match self {
617 Gl::Gl(gl) => unsafe { gl.BlendColor(r, g, b, a) },
618 Gl::Gles(gles) => unsafe { gles.BlendColor(r, g, b, a) },
619 }
620 }
621
622 pub fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) {
623 match self {
624 Gl::Gl(gl) => unsafe { gl.BlendFunc(sfactor, dfactor) },
625 Gl::Gles(gles) => unsafe { gles.BlendFunc(sfactor, dfactor) },
626 }
627 }
628
629 pub fn blend_func_separate(
630 &self,
631 src_rgb: GLenum,
632 dest_rgb: GLenum,
633 src_alpha: GLenum,
634 dest_alpha: GLenum,
635 ) {
636 match self {
637 Gl::Gl(gl) => unsafe {
638 gl.BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha)
639 },
640 Gl::Gles(gles) => unsafe {
641 gles.BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha)
642 },
643 }
644 }
645
646 pub fn blend_equation(&self, mode: GLenum) {
647 match self {
648 Gl::Gl(gl) => unsafe { gl.BlendEquation(mode) },
649 Gl::Gles(gles) => unsafe { gles.BlendEquation(mode) },
650 }
651 }
652
653 pub fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) {
654 match self {
655 Gl::Gl(gl) => unsafe { gl.BlendEquationSeparate(mode_rgb, mode_alpha) },
656 Gl::Gles(gles) => unsafe { gles.BlendEquationSeparate(mode_rgb, mode_alpha) },
657 }
658 }
659
660 pub fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) {
661 let (r, g, b, a) = (
662 r as GLboolean,
663 g as GLboolean,
664 b as GLboolean,
665 a as GLboolean,
666 );
667 match self {
668 Gl::Gl(gl) => unsafe { gl.ColorMask(r, g, b, a) },
669 Gl::Gles(gles) => unsafe { gles.ColorMask(r, g, b, a) },
670 }
671 }
672
673 pub fn cull_face(&self, mode: GLenum) {
674 match self {
675 Gl::Gl(gl) => unsafe { gl.CullFace(mode) },
676 Gl::Gles(gles) => unsafe { gles.CullFace(mode) },
677 }
678 }
679
680 pub fn front_face(&self, mode: GLenum) {
681 match self {
682 Gl::Gl(gl) => unsafe { gl.FrontFace(mode) },
683 Gl::Gles(gles) => unsafe { gles.FrontFace(mode) },
684 }
685 }
686
687 pub fn depth_func(&self, func: GLenum) {
688 match self {
689 Gl::Gl(gl) => unsafe { gl.DepthFunc(func) },
690 Gl::Gles(gles) => unsafe { gles.DepthFunc(func) },
691 }
692 }
693
694 pub fn depth_mask(&self, flag: bool) {
695 match self {
696 Gl::Gl(gl) => unsafe { gl.DepthMask(flag as GLboolean) },
697 Gl::Gles(gles) => unsafe { gles.DepthMask(flag as GLboolean) },
698 }
699 }
700
701 pub fn depth_range(&self, near: f64, far: f64) {
702 match self {
703 Gl::Gl(gl) => unsafe { gl.DepthRange(near, far) },
704 Gl::Gles(gles) => unsafe { gles.DepthRangef(near as f32, far as f32) },
705 }
706 }
707
708 pub fn line_width(&self, width: GLfloat) {
709 match self {
710 Gl::Gl(gl) => unsafe { gl.LineWidth(width) },
711 Gl::Gles(gles) => unsafe { gles.LineWidth(width) },
712 }
713 }
714
715 pub fn polygon_offset(&self, factor: GLfloat, units: GLfloat) {
716 match self {
717 Gl::Gl(gl) => unsafe { gl.PolygonOffset(factor, units) },
718 Gl::Gles(gles) => unsafe { gles.PolygonOffset(factor, units) },
719 }
720 }
721
722 pub fn sample_coverage(&self, value: GLclampf, invert: bool) {
723 match self {
724 Gl::Gl(gl) => unsafe { gl.SampleCoverage(value, invert as GLboolean) },
725 Gl::Gles(gles) => unsafe { gles.SampleCoverage(value, invert as GLboolean) },
726 }
727 }
728
729 pub fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) {
730 match self {
731 Gl::Gl(gl) => unsafe { gl.ClearColor(r, g, b, a) },
732 Gl::Gles(gles) => unsafe { gles.ClearColor(r, g, b, a) },
733 }
734 }
735
736 pub fn clear_depth(&self, depth: f64) {
737 match self {
738 Gl::Gl(gl) => unsafe { gl.ClearDepth(depth) },
739 Gl::Gles(gles) => unsafe { gles.ClearDepthf(depth as f32) },
740 }
741 }
742
743 pub fn clear_stencil(&self, s: GLint) {
744 match self {
745 Gl::Gl(gl) => unsafe { gl.ClearStencil(s) },
746 Gl::Gles(gles) => unsafe { gles.ClearStencil(s) },
747 }
748 }
749
750 pub fn clear(&self, buffer_mask: GLbitfield) {
751 match self {
752 Gl::Gl(gl) => unsafe { gl.Clear(buffer_mask) },
753 Gl::Gles(gles) => unsafe { gles.Clear(buffer_mask) },
754 }
755 }
756
757 pub fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
758 match self {
759 Gl::Gl(gl) => unsafe { gl.Scissor(x, y, width, height) },
760 Gl::Gles(gles) => unsafe { gles.Scissor(x, y, width, height) },
761 }
762 }
763
764 pub fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
765 match self {
766 Gl::Gl(gl) => unsafe { gl.StencilOp(sfail, dpfail, dppass) },
767 Gl::Gles(gles) => unsafe { gles.StencilOp(sfail, dpfail, dppass) },
768 }
769 }
770
771 pub fn stencil_op_separate(
772 &self,
773 face: GLenum,
774 sfail: GLenum,
775 dpfail: GLenum,
776 dppass: GLenum,
777 ) {
778 match self {
779 Gl::Gl(gl) => unsafe { gl.StencilOpSeparate(face, sfail, dpfail, dppass) },
780 Gl::Gles(gles) => unsafe { gles.StencilOpSeparate(face, sfail, dpfail, dppass) },
781 }
782 }
783
784 pub fn stencil_mask(&self, mask: GLuint) {
785 match self {
786 Gl::Gl(gl) => unsafe { gl.StencilMask(mask) },
787 Gl::Gles(gles) => unsafe { gles.StencilMask(mask) },
788 }
789 }
790
791 pub fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) {
792 match self {
793 Gl::Gl(gl) => unsafe { gl.StencilMaskSeparate(face, mask) },
794 Gl::Gles(gles) => unsafe { gles.StencilMaskSeparate(face, mask) },
795 }
796 }
797
798 pub fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) {
799 match self {
800 Gl::Gl(gl) => unsafe { gl.StencilFunc(func, ref_, mask) },
801 Gl::Gles(gles) => unsafe { gles.StencilFunc(func, ref_, mask) },
802 }
803 }
804
805 pub fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) {
806 match self {
807 Gl::Gl(gl) => unsafe { gl.StencilFuncSeparate(face, func, ref_, mask) },
808 Gl::Gles(gles) => unsafe { gles.StencilFuncSeparate(face, func, ref_, mask) },
809 }
810 }
811
812 pub fn is_enabled(&self, cap: GLenum) -> bool {
813 TRUE == match self {
814 Gl::Gl(gl) => unsafe { gl.IsEnabled(cap) },
815 Gl::Gles(gles) => unsafe { gles.IsEnabled(cap) },
816 }
817 }
818
819 pub fn enable(&self, cap: GLenum) {
820 match self {
821 Gl::Gl(gl) => unsafe { gl.Enable(cap) },
822 Gl::Gles(gles) => unsafe { gles.Enable(cap) },
823 }
824 }
825
826 pub fn disable(&self, cap: GLenum) {
827 match self {
828 Gl::Gl(gl) => unsafe { gl.Disable(cap) },
829 Gl::Gles(gles) => unsafe { gles.Disable(cap) },
830 }
831 }
832
833 pub fn finish(&self) {
834 match self {
835 Gl::Gl(gl) => unsafe { gl.Finish() },
836 Gl::Gles(gles) => unsafe { gles.Finish() },
837 }
838 }
839
840 pub fn flush(&self) {
841 match self {
842 Gl::Gl(gl) => unsafe { gl.Flush() },
843 Gl::Gles(gles) => unsafe { gles.Flush() },
844 }
845 }
846
847 pub fn get_string(&self, which: GLenum) -> String {
848 let llstr = match self {
849 Gl::Gl(gl) => unsafe { gl.GetString(which) },
850 Gl::Gles(gles) => unsafe { gles.GetString(which) },
851 };
852 if !llstr.is_null() {
853 unsafe {
854 str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes())
855 .to_string()
856 }
857 } else {
858 "".to_string()
859 }
860 }
861
862 pub fn get_string_i(&self, which: GLenum, index: GLuint) -> String {
863 let llstr = match self {
864 Gl::Gl(gl) => unsafe { gl.GetStringi(which, index) },
865 Gl::Gles(gles) => unsafe { gles.GetStringi(which, index) },
866 };
867 if !llstr.is_null() {
868 unsafe {
869 str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes())
870 .to_string()
871 }
872 } else {
873 "".to_string()
874 }
875 }
876
877 pub unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]) {
878 assert!(!result.is_empty());
879 match self {
880 Gl::Gl(gl) => gl.GetShaderiv(shader, pname, result.as_mut_ptr()),
881 Gl::Gles(gles) => gles.GetShaderiv(shader, pname, result.as_mut_ptr()),
882 }
883 }
884
885 pub fn get_shader_precision_format(
886 &self,
887 shader_type: GLuint,
888 precision_type: GLuint,
889 ) -> (GLint, GLint, GLint) {
890 match self {
891 Gl::Gl(..) => {
892 match precision_type {
895 ffi::LOW_FLOAT | ffi::MEDIUM_FLOAT | ffi::HIGH_FLOAT => {
896 (127, 127, 23)
900 }
901 ffi::LOW_INT | ffi::MEDIUM_INT | ffi::HIGH_INT => {
902 (24, 24, 0)
906 }
907 _ => (0, 0, 0),
908 }
909 }
910 Gl::Gles(gles) => {
911 let (mut range, mut precision) = match precision_type {
912 ffi::LOW_INT | ffi::MEDIUM_INT | ffi::HIGH_INT => ([31, 30], 0),
914
915 ffi::LOW_FLOAT | ffi::MEDIUM_FLOAT | ffi::HIGH_FLOAT => ([127, 127], 23),
917
918 _ => unreachable!("invalid precision"),
919 };
920 unsafe {
924 gles.GetShaderPrecisionFormat(
925 shader_type,
926 precision_type,
927 range.as_mut_ptr(),
928 &mut precision,
929 );
930 let _ = gles.GetError();
931 }
932 (range[0], range[1], precision)
933 }
934 }
935 }
936
937 pub fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
938 match self {
939 Gl::Gl(gl) => unsafe { gl.Viewport(x, y, width, height) },
940 Gl::Gles(gles) => unsafe { gles.Viewport(x, y, width, height) },
941 }
942 }
943
944 pub fn get_framebuffer_attachment_parameter_iv(
945 &self,
946 target: GLenum,
947 attachment: GLenum,
948 pname: GLenum,
949 ) -> GLint {
950 let mut result = 0;
951 match self {
952 Gl::Gl(gl) => unsafe {
953 gl.GetFramebufferAttachmentParameteriv(target, attachment, pname, &mut result)
954 },
955 Gl::Gles(gles) => unsafe {
956 gles.GetFramebufferAttachmentParameteriv(target, attachment, pname, &mut result)
957 },
958 }
959 result
960 }
961
962 pub fn get_internal_format_iv(
963 &self,
964 target: GLenum,
965 internalformat: GLenum,
966 pname: GLenum,
967 result: &mut [GLint],
968 ) {
969 match self {
970 Gl::Gl(gl) => unsafe {
971 gl.GetInternalformativ(target, internalformat, pname, result.len() as _, result.as_mut_ptr())
972 },
973 Gl::Gles(gles) => unsafe {
974 gles.GetInternalformativ(target, internalformat, pname, result.len() as _, result.as_mut_ptr())
975 },
976 }
977 }
978
979 pub fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
980 let mut result = 0;
981 match self {
982 Gl::Gl(gl) => unsafe { gl.GetRenderbufferParameteriv(target, pname, &mut result) },
983 Gl::Gles(gles) => unsafe {
984 gles.GetRenderbufferParameteriv(target, pname, &mut result)
985 },
986 }
987 result
988 }
989
990 pub fn delete_renderbuffers(&self, buffers: &[GLuint]) {
991 match self {
992 Gl::Gl(gl) => unsafe {
993 gl.DeleteRenderbuffers(buffers.len() as GLsizei, buffers.as_ptr())
994 },
995 Gl::Gles(gles) => unsafe {
996 gles.DeleteRenderbuffers(buffers.len() as GLsizei, buffers.as_ptr())
997 },
998 }
999 }
1000
1001 pub fn delete_textures(&self, textures: &[GLuint]) {
1002 match self {
1003 Gl::Gl(gl) => unsafe {
1004 gl.DeleteTextures(textures.len() as GLsizei, textures.as_ptr())
1005 },
1006 Gl::Gles(gles) => unsafe {
1007 gles.DeleteTextures(textures.len() as GLsizei, textures.as_ptr())
1008 },
1009 }
1010 }
1011
1012 pub fn delete_framebuffers(&self, framebuffers: &[GLuint]) {
1013 match self {
1014 Gl::Gl(gl) => unsafe {
1015 gl.DeleteFramebuffers(framebuffers.len() as GLsizei, framebuffers.as_ptr())
1016 },
1017 Gl::Gles(gles) => unsafe {
1018 gles.DeleteFramebuffers(framebuffers.len() as GLsizei, framebuffers.as_ptr())
1019 },
1020 }
1021 }
1022
1023 pub fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) {
1024 match self {
1025 Gl::Gl(gl) => unsafe { gl.BindRenderbuffer(target, renderbuffer) },
1026 Gl::Gles(gles) => unsafe { gles.BindRenderbuffer(target, renderbuffer) },
1027 }
1028 }
1029
1030 pub fn is_renderbuffer(&self, renderbuffer: GLuint) -> bool {
1031 TRUE == match self {
1032 Gl::Gl(gl) => unsafe { gl.IsRenderbuffer(renderbuffer) },
1033 Gl::Gles(gles) => unsafe { gles.IsRenderbuffer(renderbuffer) },
1034 }
1035 }
1036
1037 pub fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) {
1038 match self {
1039 Gl::Gl(gl) => unsafe { gl.BindFramebuffer(target, framebuffer) },
1040 Gl::Gles(gles) => unsafe { gles.BindFramebuffer(target, framebuffer) },
1041 }
1042 }
1043
1044 pub fn is_framebuffer(&self, framebuffer: GLuint) -> bool {
1045 TRUE == match self {
1046 Gl::Gl(gl) => unsafe { gl.IsFramebuffer(framebuffer) },
1047 Gl::Gles(gles) => unsafe { gles.IsFramebuffer(framebuffer) },
1048 }
1049 }
1050
1051 pub fn bind_texture(&self, target: GLenum, texture: GLuint) {
1052 match self {
1053 Gl::Gl(gl) => unsafe { gl.BindTexture(target, texture) },
1054 Gl::Gles(gles) => unsafe { gles.BindTexture(target, texture) },
1055 }
1056 }
1057
1058 pub fn is_texture(&self, texture: GLuint) -> bool {
1059 TRUE == match self {
1060 Gl::Gl(gl) => unsafe { gl.IsTexture(texture) },
1061 Gl::Gles(gles) => unsafe { gles.IsTexture(texture) },
1062 }
1063 }
1064
1065 pub fn is_shader(&self, shader: GLuint) -> bool {
1066 TRUE == match self {
1067 Gl::Gl(gl) => unsafe { gl.IsShader(shader) },
1068 Gl::Gles(gles) => unsafe { gles.IsShader(shader) },
1069 }
1070 }
1071
1072 pub unsafe fn buffer_data(
1073 &self,
1074 target: GLenum,
1075 size: GLsizeiptr,
1076 data: *const GLvoid,
1077 usage: GLenum,
1078 ) {
1079 match self {
1080 Gl::Gl(gl) => gl.BufferData(target, size, data, usage),
1081 Gl::Gles(gles) => gles.BufferData(target, size, data, usage),
1082 }
1083 }
1084
1085 pub unsafe fn buffer_sub_data(
1086 &self,
1087 target: GLenum,
1088 offset: isize,
1089 size: GLsizeiptr,
1090 data: *const GLvoid,
1091 ) {
1092 match self {
1093 Gl::Gl(gl) => gl.BufferSubData(target, offset, size, data),
1094 Gl::Gles(gles) => gles.BufferSubData(target, offset, size, data),
1095 }
1096 }
1097
1098 pub fn read_buffer(&self, buffer: GLenum) {
1099 match self {
1100 Gl::Gl(gl) => unsafe { gl.ReadBuffer(buffer) },
1101 Gl::Gles(gles) => unsafe { gles.ReadBuffer(buffer) },
1102 }
1103 }
1104
1105 pub fn draw_buffers(&self, bufs: &[GLenum]) {
1106 let len = bufs.len() as GLsizei;
1107 match self {
1108 Gl::Gl(gl) => unsafe { gl.DrawBuffers(len, bufs.as_ptr()) },
1109 Gl::Gles(gles) => unsafe { gles.DrawBuffers(len, bufs.as_ptr()) },
1110 }
1111 }
1112
1113 pub fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) {
1114 match self {
1115 Gl::Gl(gl) => unsafe { gl.DrawArrays(mode, first, count) },
1116 Gl::Gles(gles) => unsafe { gles.DrawArrays(mode, first, count) },
1117 }
1118 }
1119
1120 pub fn draw_arrays_instanced(
1121 &self,
1122 mode: GLenum,
1123 first: GLint,
1124 count: GLsizei,
1125 primcount: GLsizei,
1126 ) {
1127 match self {
1128 Gl::Gl(gl) => unsafe { gl.DrawArraysInstanced(mode, first, count, primcount) },
1129 Gl::Gles(gles) => unsafe {
1130 gles.DrawArraysInstanced(mode, first, count, primcount)
1131 },
1132 }
1133 }
1134
1135 pub fn draw_elements(
1136 &self,
1137 mode: GLenum,
1138 count: GLsizei,
1139 element_type: GLenum,
1140 indices_offset: GLuint,
1141 ) {
1142 match self {
1143 Gl::Gl(gl) => unsafe {
1144 gl.DrawElements(mode, count, element_type, indices_offset as *const c_void)
1145 },
1146 Gl::Gles(gles) => unsafe {
1147 gles.DrawElements(mode, count, element_type, indices_offset as *const c_void)
1148 },
1149 }
1150 }
1151
1152 pub fn draw_elements_instanced(
1153 &self,
1154 mode: GLenum,
1155 count: GLsizei,
1156 element_type: GLenum,
1157 indices_offset: GLuint,
1158 primcount: GLsizei,
1159 ) {
1160 match self {
1161 Gl::Gl(gl) => unsafe {
1162 gl.DrawElementsInstanced(
1163 mode,
1164 count,
1165 element_type,
1166 indices_offset as *const c_void,
1167 primcount,
1168 )
1169 },
1170 Gl::Gles(gles) => unsafe {
1171 gles.DrawElementsInstanced(
1172 mode,
1173 count,
1174 element_type,
1175 indices_offset as *const c_void,
1176 primcount,
1177 )
1178 },
1179 }
1180 }
1181
1182 pub fn framebuffer_renderbuffer(
1183 &self,
1184 target: GLenum,
1185 attachment: GLenum,
1186 renderbuffertarget: GLenum,
1187 renderbuffer: GLuint,
1188 ) {
1189 match self {
1190 Gl::Gl(gl) => unsafe {
1191 gl.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)
1192 },
1193 Gl::Gles(gles) => unsafe {
1194 gles.FramebufferRenderbuffer(
1195 target,
1196 attachment,
1197 renderbuffertarget,
1198 renderbuffer,
1199 )
1200 },
1201 }
1202 }
1203
1204 pub fn framebuffer_texture_2d(
1205 &self,
1206 target: GLenum,
1207 attachment: GLenum,
1208 textarget: GLenum,
1209 texture: GLuint,
1210 level: GLint,
1211 ) {
1212 match self {
1213 Gl::Gl(gl) => unsafe {
1214 gl.FramebufferTexture2D(target, attachment, textarget, texture, level)
1215 },
1216 Gl::Gles(gles) => unsafe {
1217 gles.FramebufferTexture2D(target, attachment, textarget, texture, level)
1218 },
1219 }
1220 }
1221
1222 pub fn framebuffer_texture_layer(
1223 &self,
1224 target: GLenum,
1225 attachment: GLenum,
1226 texture: GLuint,
1227 level: GLint,
1228 layer: GLint,
1229 ) {
1230 match self {
1231 Gl::Gl(gl) => unsafe {
1232 gl.FramebufferTextureLayer(
1233 target,
1234 attachment,
1235 texture,
1236 level,
1237 layer,
1238 )
1239 },
1240 Gl::Gles(gles) => unsafe {
1241 gles.FramebufferTextureLayer(
1242 target,
1243 attachment,
1244 texture,
1245 level,
1246 layer,
1247 )
1248 },
1249 }
1250 }
1251
1252 pub fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]) {
1253 match self {
1254 Gl::Gl(gl) => unsafe {
1255 gl.InvalidateFramebuffer(
1256 target,
1257 attachments.len() as GLsizei,
1258 attachments.as_ptr(),
1259 )
1260 },
1261 Gl::Gles(gles) => unsafe {
1262 gles.InvalidateFramebuffer(
1263 target,
1264 attachments.len() as GLsizei,
1265 attachments.as_ptr(),
1266 )
1267 },
1268 }
1269 }
1270
1271 pub fn invalidate_sub_framebuffer(
1272 &self,
1273 target: GLenum,
1274 attachments: &[GLenum],
1275 x: i32,
1276 y: i32,
1277 width: GLsizei,
1278 height: GLsizei,
1279 ) {
1280 match self {
1281 Gl::Gl(gl) => unsafe {
1282 gl.InvalidateSubFramebuffer(
1283 target,
1284 attachments.len() as GLsizei,
1285 attachments.as_ptr(),
1286 x,
1287 y,
1288 width,
1289 height,
1290 )
1291 },
1292 Gl::Gles(gles) => unsafe {
1293 gles.InvalidateSubFramebuffer(
1294 target,
1295 attachments.len() as GLsizei,
1296 attachments.as_ptr(),
1297 x,
1298 y,
1299 width,
1300 height,
1301 )
1302 },
1303 }
1304 }
1305
1306 pub fn renderbuffer_storage(
1307 &self,
1308 target: GLenum,
1309 internalformat: GLenum,
1310 width: GLsizei,
1311 height: GLsizei,
1312 ) {
1313 match self {
1314 Gl::Gl(gl) => unsafe {
1315 gl.RenderbufferStorage(target, internalformat, width, height)
1316 },
1317 Gl::Gles(gles) => unsafe {
1318 gles.RenderbufferStorage(target, internalformat, width, height)
1319 },
1320 }
1321 }
1322
1323 pub fn renderbuffer_storage_multisample(
1324 &self,
1325 target: GLenum,
1326 samples: GLsizei,
1327 internalformat: GLenum,
1328 width: GLsizei,
1329 height: GLsizei,
1330 ) {
1331 match self {
1332 Gl::Gl(gl) => unsafe {
1333 gl.RenderbufferStorageMultisample(target, samples, internalformat, width, height)
1334 },
1335 Gl::Gles(gles) => unsafe {
1336 gles.RenderbufferStorageMultisample(target, samples, internalformat, width, height)
1337 },
1338 }
1339 }
1340
1341 pub fn check_framebuffer_status(&self, target: GLenum) -> GLenum {
1342 match self {
1343 Gl::Gl(gl) => unsafe { gl.CheckFramebufferStatus(target) },
1344 Gl::Gles(gles) => unsafe { gles.CheckFramebufferStatus(target) },
1345 }
1346 }
1347
1348 pub fn get_error(&self) -> GLenum {
1349 match self {
1350 Gl::Gl(gl) => unsafe { gl.GetError() },
1351 Gl::Gles(gles) => unsafe { gles.GetError() },
1352 }
1353 }
1354
1355 pub fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) {
1356 match self {
1357 Gl::Gl(gl) => unsafe { gl.TexParameteri(target, pname, param) },
1358 Gl::Gles(gles) => unsafe { gles.TexParameteri(target, pname, param) },
1359 }
1360 }
1361
1362 pub fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) {
1363 match self {
1364 Gl::Gl(gl) => unsafe { gl.TexParameterf(target, pname, param) },
1365 Gl::Gles(gles) => unsafe { gles.TexParameterf(target, pname, param) },
1366 }
1367 }
1368
1369 pub fn get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
1370 let mut result = 0;
1371 match self {
1372 Gl::Gl(gl) => unsafe { gl.GetTexParameteriv(target, pname, &mut result) },
1373 Gl::Gles(gles) => unsafe { gles.GetTexParameteriv(target, pname, &mut result) },
1374 };
1375 result
1376 }
1377
1378 pub fn get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat {
1379 let mut result = 0.;
1380 match self {
1381 Gl::Gl(gl) => unsafe { gl.GetTexParameterfv(target, pname, &mut result) },
1382 Gl::Gles(gles) => unsafe { gles.GetTexParameterfv(target, pname, &mut result) },
1383 };
1384 result
1385 }
1386
1387 pub fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1388 let mut buf_size = [0];
1389 unsafe {
1390 self.get_program_iv(program, ffi::ACTIVE_ATTRIBUTE_MAX_LENGTH, &mut buf_size);
1391 }
1392 let mut name = vec![0u8; buf_size[0] as usize];
1393 let mut length = 0 as GLsizei;
1394 let mut size = 0 as i32;
1395 let mut type_ = 0 as u32;
1396 match self {
1397 Gl::Gl(gl) => unsafe {
1398 gl.GetActiveAttrib(
1399 program,
1400 index,
1401 buf_size[0],
1402 &mut length,
1403 &mut size,
1404 &mut type_,
1405 name.as_mut_ptr() as *mut GLchar,
1406 );
1407 },
1408 Gl::Gles(gles) => unsafe {
1409 gles.GetActiveAttrib(
1410 program,
1411 index,
1412 buf_size[0],
1413 &mut length,
1414 &mut size,
1415 &mut type_,
1416 name.as_mut_ptr() as *mut GLchar,
1417 );
1418 },
1419 }
1420 name.truncate(if length > 0 { length as usize } else { 0 });
1421 (size, type_, String::from_utf8(name).unwrap())
1422 }
1423
1424 pub fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1425 let mut buf_size = [0];
1426 unsafe {
1427 self.get_program_iv(program, ffi::ACTIVE_UNIFORM_MAX_LENGTH, &mut buf_size);
1428 }
1429 let mut name = vec![0 as u8; buf_size[0] as usize];
1430 let mut length: GLsizei = 0;
1431 let mut size: i32 = 0;
1432 let mut type_: u32 = 0;
1433
1434 match self {
1435 Gl::Gl(gl) => unsafe {
1436 gl.GetActiveUniform(
1437 program,
1438 index,
1439 buf_size[0],
1440 &mut length,
1441 &mut size,
1442 &mut type_,
1443 name.as_mut_ptr() as *mut GLchar,
1444 );
1445 },
1446 Gl::Gles(gles) => unsafe {
1447 gles.GetActiveUniform(
1448 program,
1449 index,
1450 buf_size[0],
1451 &mut length,
1452 &mut size,
1453 &mut type_,
1454 name.as_mut_ptr() as *mut GLchar,
1455 );
1456 },
1457 }
1458
1459 name.truncate(if length > 0 { length as usize } else { 0 });
1460
1461 (size, type_, String::from_utf8(name).unwrap())
1462 }
1463
1464 pub fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int {
1465 let name = CString::new(name).unwrap();
1466 match self {
1467 Gl::Gl(gl) => unsafe { gl.GetAttribLocation(program, name.as_ptr()) },
1468 Gl::Gles(gles) => unsafe { gles.GetAttribLocation(program, name.as_ptr()) },
1469 }
1470 }
1471
1472 pub fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int {
1473 let name = CString::new(name).unwrap();
1474 match self {
1475 Gl::Gl(gl) => unsafe { gl.GetFragDataLocation(program, name.as_ptr()) },
1476 Gl::Gles(gles) => unsafe { gles.GetFragDataLocation(program, name.as_ptr()) },
1477 }
1478 }
1479
1480 pub fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int {
1481 let name = CString::new(name).unwrap();
1482 match self {
1483 Gl::Gl(gl) => unsafe { gl.GetUniformLocation(program, name.as_ptr()) },
1484 Gl::Gles(gles) => unsafe { gles.GetUniformLocation(program, name.as_ptr()) },
1485 }
1486 }
1487
1488 pub fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint {
1489 let name = CString::new(name).unwrap();
1490 match self {
1491 Gl::Gl(gl) => unsafe { gl.GetUniformBlockIndex(program, name.as_ptr()) },
1492 Gl::Gles(gles) => unsafe { gles.GetUniformBlockIndex(program, name.as_ptr()) },
1493 }
1494 }
1495
1496 pub fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint> {
1497 let count = names.len() as GLsizei;
1498 let c_names = names
1499 .iter()
1500 .map(|&name| std::ffi::CString::new(name).unwrap())
1501 .collect::<Vec<_>>();
1502 let c_name_ptrs = c_names
1503 .iter()
1504 .map(|name| name.as_ptr())
1505 .collect::<Vec<_>>();
1506
1507 let mut indices = vec![0 as GLuint; names.len()];
1508 match self {
1509 Gl::Gl(gl) => unsafe {
1510 gl.GetUniformIndices(
1511 program,
1512 count,
1513 c_name_ptrs.as_ptr(),
1514 indices.as_mut_ptr(),
1515 )
1516 },
1517 Gl::Gles(gles) => unsafe {
1518 gles.GetUniformIndices(
1519 program,
1520 count,
1521 c_name_ptrs.as_ptr(),
1522 indices.as_mut_ptr(),
1523 )
1524 },
1525 }
1526 indices
1527 }
1528
1529 pub fn get_active_uniforms_iv(
1530 &self,
1531 program: GLuint,
1532 uniforms: &[GLuint],
1533 pname: GLenum,
1534 ) -> Vec<GLint> {
1535 let mut results = vec![0 as GLint; uniforms.len()];
1536 match self {
1537 Gl::Gl(gl) => unsafe {
1538 gl.GetActiveUniformsiv(
1539 program,
1540 uniforms.len() as GLsizei,
1541 uniforms.as_ptr(),
1542 pname,
1543 results.as_mut_ptr(),
1544 )
1545 },
1546 Gl::Gles(gles) => unsafe {
1547 gles.GetActiveUniformsiv(
1548 program,
1549 uniforms.len() as GLsizei,
1550 uniforms.as_ptr(),
1551 pname,
1552 results.as_mut_ptr(),
1553 )
1554 },
1555 }
1556 results
1557 }
1558
1559 pub fn get_active_uniform_block_iv(
1560 &self,
1561 program: GLuint,
1562 index: GLuint,
1563 pname: GLenum,
1564 ) -> Vec<GLint> {
1565 let buf_size = match pname {
1566 ffi::UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES => {
1567 self.get_active_uniform_block_iv(
1568 program,
1569 index,
1570 ffi::UNIFORM_BLOCK_ACTIVE_UNIFORMS,
1571 )[0] as usize
1572 },
1573 _ => 1,
1574 };
1575 let mut results = vec![0 as i32; buf_size];
1576 match self {
1577 Gl::Gl(gl) => unsafe {
1578 gl.GetActiveUniformBlockiv(
1579 program,
1580 index,
1581 pname,
1582 results.as_mut_ptr(),
1583 )
1584 },
1585 Gl::Gles(gles) => unsafe {
1586 gles.GetActiveUniformBlockiv(
1587 program,
1588 index,
1589 pname,
1590 results.as_mut_ptr(),
1591 )
1592 },
1593 }
1594 results
1595 }
1596
1597 pub fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String {
1598 let buf_size = self.get_active_uniform_block_iv(program, index, ffi::UNIFORM_BLOCK_NAME_LENGTH)[0];
1599 let mut name = vec![0 as u8; buf_size as usize];
1600 let mut length: GLsizei = 0;
1601
1602 match self {
1603 Gl::Gl(gl) => unsafe {
1604 gl.GetActiveUniformBlockName(
1605 program,
1606 index,
1607 buf_size,
1608 &mut length,
1609 name.as_mut_ptr() as *mut GLchar,
1610 );
1611 },
1612 Gl::Gles(gles) => unsafe {
1613 gles.GetActiveUniformBlockName(
1614 program,
1615 index,
1616 buf_size,
1617 &mut length,
1618 name.as_mut_ptr() as *mut GLchar,
1619 );
1620 },
1621 }
1622
1623 name.truncate(if length > 0 { length as usize } else { 0 });
1624 String::from_utf8(name).unwrap()
1625 }
1626
1627 pub fn uniform_block_binding(
1628 &self,
1629 program: GLuint,
1630 uniform_block_index: GLuint,
1631 uniform_block_binding: GLuint,
1632 ) {
1633 match self {
1634 Gl::Gl(gl) => unsafe {
1635 gl.UniformBlockBinding(
1636 program,
1637 uniform_block_index,
1638 uniform_block_binding,
1639 )
1640 },
1641 Gl::Gles(gles) => unsafe {
1642 gles.UniformBlockBinding(
1643 program,
1644 uniform_block_index,
1645 uniform_block_binding,
1646 )
1647 },
1648 }
1649 }
1650
1651 pub fn bind_buffer_base(&self, program: GLenum, index: GLuint, buffer: GLuint) {
1652 match self {
1653 Gl::Gl(gl) => unsafe { gl.BindBufferBase(program, index, buffer) },
1654 Gl::Gles(gles) => unsafe { gles.BindBufferBase(program, index, buffer) },
1655 }
1656 }
1657
1658 pub fn bind_buffer_range(
1659 &self,
1660 program: GLenum,
1661 index: GLuint,
1662 buffer: GLuint,
1663 offset: GLintptr,
1664 size: GLsizeiptr,
1665 ) {
1666 assert!(offset >= 0);
1667 assert!(size >= 0);
1668 match self {
1669 Gl::Gl(gl) => unsafe { gl.BindBufferRange(program, index, buffer, offset, size) },
1670 Gl::Gles(gles) => unsafe { gles.BindBufferRange(program, index, buffer, offset, size) },
1671 }
1672 }
1673
1674 pub fn get_program_info_log(&self, program: GLuint) -> String {
1675 let mut max_len = [0];
1676 unsafe {
1677 self.get_program_iv(program, ffi::INFO_LOG_LENGTH, &mut max_len);
1678 }
1679 if max_len[0] == 0 {
1680 return String::new();
1681 }
1682 let mut result = vec![0u8; max_len[0] as usize];
1683 let mut result_len = 0 as GLsizei;
1684 let max_len = max_len[0] as GLsizei;
1685 match self {
1686 Gl::Gl(gl) => unsafe {
1687 gl.GetProgramInfoLog(
1688 program,
1689 max_len,
1690 &mut result_len,
1691 result.as_mut_ptr() as *mut GLchar,
1692 )
1693 },
1694 Gl::Gles(gles) => unsafe {
1695 gles.GetProgramInfoLog(
1696 program,
1697 max_len,
1698 &mut result_len,
1699 result.as_mut_ptr() as *mut GLchar,
1700 )
1701 },
1702 }
1703 result.truncate(if result_len > 0 {
1704 result_len as usize
1705 } else {
1706 0
1707 });
1708 String::from_utf8(result).unwrap()
1709 }
1710
1711 pub unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]) {
1712 assert!(!result.is_empty());
1713 match self {
1714 Gl::Gl(gl) => gl.GetProgramiv(program, pname, result.as_mut_ptr()),
1715 Gl::Gles(gles) => gles.GetProgramiv(program, pname, result.as_mut_ptr()),
1716 }
1717 }
1718
1719 pub unsafe fn get_vertex_attrib_fv(
1720 &self,
1721 index: GLuint,
1722 pname: GLenum,
1723 result: &mut [GLfloat],
1724 ) {
1725 assert!(!result.is_empty());
1726 match self {
1727 Gl::Gl(gl) => gl.GetVertexAttribfv(index, pname, result.as_mut_ptr()),
1728 Gl::Gles(gles) => gles.GetVertexAttribfv(index, pname, result.as_mut_ptr()),
1729 }
1730 }
1731
1732 pub fn get_shader_info_log(&self, shader: GLuint) -> String {
1733 let mut max_len = [0];
1734 unsafe {
1735 self.get_shader_iv(shader, ffi::INFO_LOG_LENGTH, &mut max_len);
1736 }
1737 if max_len[0] == 0 {
1738 return String::new();
1739 }
1740 let mut result = vec![0u8; max_len[0] as usize];
1741 let mut result_len = 0 as GLsizei;
1742 let max_len = max_len[0] as GLsizei;
1743 match self {
1744 Gl::Gl(gl) => unsafe {
1745 gl.GetShaderInfoLog(
1746 shader,
1747 max_len,
1748 &mut result_len,
1749 result.as_mut_ptr() as *mut GLchar,
1750 )
1751 },
1752 Gl::Gles(gles) => unsafe {
1753 gles.GetShaderInfoLog(
1754 shader,
1755 max_len,
1756 &mut result_len,
1757 result.as_mut_ptr() as *mut GLchar,
1758 )
1759 },
1760 }
1761 result.truncate(if result_len > 0 {
1762 result_len as usize
1763 } else {
1764 0
1765 });
1766 String::from_utf8(result).unwrap()
1767 }
1768
1769 pub unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]) {
1770 assert!(!result.is_empty());
1771 match self {
1772 Gl::Gl(gl) => gl.GetIntegerv(name, result.as_mut_ptr()),
1773 Gl::Gles(gles) => gles.GetIntegerv(name, result.as_mut_ptr()),
1774 }
1775 }
1776
1777 pub unsafe fn get_integer64_v(&self, name: GLenum, result: &mut [GLint64]) {
1778 assert!(!result.is_empty());
1779 match self {
1780 Gl::Gl(gl) => gl.GetInteger64v(name, result.as_mut_ptr()),
1781 Gl::Gles(gles) => gles.GetInteger64v(name, result.as_mut_ptr()),
1782 }
1783 }
1784
1785 pub unsafe fn get_integeri_v(&self, name: GLenum, index: GLuint, result: &mut [GLint]) {
1786 assert!(!result.is_empty());
1787 match self {
1788 Gl::Gl(gl) => gl.GetIntegeri_v(name, index, result.as_mut_ptr()),
1789 Gl::Gles(gles) => gles.GetIntegeri_v(name, index, result.as_mut_ptr()),
1790 }
1791 }
1792
1793 pub unsafe fn get_integer64i_v(&self, name: GLenum, index: GLuint, result: &mut [GLint64]) {
1794 assert!(!result.is_empty());
1795 match self {
1796 Gl::Gl(gl) => gl.GetInteger64i_v(name, index, result.as_mut_ptr()),
1797 Gl::Gles(gles) => gles.GetInteger64i_v(name, index, result.as_mut_ptr()),
1798 }
1799 }
1800
1801 pub unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]) {
1802 assert!(!result.is_empty());
1803 match self {
1804 Gl::Gl(gl) => gl.GetBooleanv(name, result.as_mut_ptr()),
1805 Gl::Gles(gles) => gles.GetBooleanv(name, result.as_mut_ptr()),
1806 }
1807 }
1808
1809 pub unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]) {
1810 assert!(!result.is_empty());
1811 match self {
1812 Gl::Gl(gl) => gl.GetFloatv(name, result.as_mut_ptr()),
1813 Gl::Gles(gles) => gles.GetFloatv(name, result.as_mut_ptr()),
1814 }
1815 }
1816
1817 pub fn compile_shader(&self, shader: GLuint) {
1818 match self {
1819 Gl::Gl(gl) => unsafe { gl.CompileShader(shader) },
1820 Gl::Gles(gles) => unsafe { gles.CompileShader(shader) },
1821 }
1822 }
1823
1824 pub fn pixel_store_i(&self, name: GLenum, param: GLint) {
1825 match self {
1826 Gl::Gl(gl) => unsafe { gl.PixelStorei(name, param) },
1827 Gl::Gles(gles) => unsafe { gles.PixelStorei(name, param) },
1828 }
1829 }
1830
1831 pub fn read_pixels_into_buffer(
1832 &self,
1833 x: GLint,
1834 y: GLint,
1835 width: GLsizei,
1836 height: GLsizei,
1837 format: GLenum,
1838 pixel_type: GLenum,
1839 buffer: &mut [u8],
1840 ) {
1841 assert_eq!(
1843 calculate_length(width, height, format, pixel_type),
1844 buffer.len()
1845 );
1846
1847 self.pixel_store_i(ffi::PACK_ALIGNMENT, 1);
1849
1850 match self {
1851 Gl::Gl(gl) => unsafe {
1852 gl.ReadPixels(
1853 x,
1854 y,
1855 width,
1856 height,
1857 format,
1858 pixel_type,
1859 buffer.as_mut_ptr() as *mut _,
1860 )
1861 },
1862 Gl::Gles(gles) => unsafe {
1863 gles.ReadPixels(
1864 x,
1865 y,
1866 width,
1867 height,
1868 format,
1869 pixel_type,
1870 buffer.as_mut_ptr() as *mut _,
1871 )
1872 },
1873 }
1874 }
1875
1876 pub unsafe fn read_pixels_into_pixel_pack_buffer(
1882 &self,
1883 x: GLint,
1884 y: GLint,
1885 width: GLsizei,
1886 height: GLsizei,
1887 format: GLenum,
1888 pixel_type: GLenum,
1889 buffer_byte_offset: usize,
1890 ) {
1891 match self {
1892 Gl::Gl(gl) =>
1893 gl.ReadPixels(
1894 x,
1895 y,
1896 width,
1897 height,
1898 format,
1899 pixel_type,
1900 buffer_byte_offset as *mut _,
1901 ),
1902 Gl::Gles(gles) =>
1903 gles.ReadPixels(
1904 x,
1905 y,
1906 width,
1907 height,
1908 format,
1909 pixel_type,
1910 buffer_byte_offset as *mut _,
1911 ),
1912 }
1913 }
1914
1915 pub fn read_pixels(
1916 &self,
1917 x: GLint,
1918 y: GLint,
1919 width: GLsizei,
1920 height: GLsizei,
1921 format: GLenum,
1922 pixel_type: GLenum,
1923 ) -> Vec<u8> {
1924 let len = calculate_length(width, height, format, pixel_type);
1925 let mut pixels: Vec<u8> = Vec::new();
1926 pixels.reserve(len);
1927 unsafe {
1928 pixels.set_len(len);
1929 }
1930 self.read_pixels_into_buffer(x, y, width, height, format, pixel_type, &mut pixels[..]);
1931 pixels
1932 }
1933
1934 pub fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
1935 match self {
1936 Gl::Gl(gl) => unsafe { gl.FenceSync(condition, flags) as GLsync },
1937 Gl::Gles(gles) => unsafe { gles.FenceSync(condition, flags) as GLsync },
1938 }
1939 }
1940
1941 pub fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum {
1942 match self {
1943 Gl::Gl(gl) => unsafe { gl.ClientWaitSync(sync as *const _, flags, timeout) },
1944 Gl::Gles(gles) => unsafe { gles.ClientWaitSync(sync as *const _, flags, timeout) },
1945 }
1946 }
1947
1948 pub fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) {
1949 match self {
1950 Gl::Gl(gl) => unsafe { gl.WaitSync(sync as *const _, flags, timeout) },
1951 Gl::Gles(gles) => unsafe { gles.WaitSync(sync as *const _, flags, timeout) },
1952 };
1953 }
1954
1955 pub fn get_sync_iv(&self, sync: GLsync, pname: GLenum) -> Vec<GLint> {
1956 let mut result = vec![0 as GLint];
1957 match self {
1958 Gl::Gl(gl) => unsafe { gl.GetSynciv(sync as *const _, pname, result.len() as _, ptr::null_mut(), result.as_mut_ptr()); },
1959 Gl::Gles(gles) => unsafe { gles.GetSynciv(sync as *const _, pname, result.len() as _, ptr::null_mut(), result.as_mut_ptr()); },
1960 };
1961 result
1962 }
1963
1964 pub fn is_sync(&self, sync: GLsync) -> bool {
1965 TRUE == match self {
1966 Gl::Gl(gl) => unsafe { gl.IsSync(sync as *const _) as GLboolean },
1967 Gl::Gles(gles) => unsafe { gles.IsSync(sync as *const _) as GLboolean },
1968 }
1969 }
1970
1971 pub fn delete_sync(&self, sync: GLsync) {
1972 match self {
1973 Gl::Gl(gl) => unsafe { gl.DeleteSync(sync as *const _) },
1974 Gl::Gles(gles) => unsafe { gles.DeleteSync(sync as *const _) },
1975 }
1976 }
1977
1978 pub fn uniform_1f(&self, location: GLint, v0: GLfloat) {
1979 match self {
1980 Gl::Gl(gl) => unsafe { gl.Uniform1f(location, v0) },
1981 Gl::Gles(gles) => unsafe { gles.Uniform1f(location, v0) },
1982 }
1983 }
1984
1985 pub fn uniform_1fv(&self, location: GLint, values: &[f32]) {
1986 let len = values.len() as GLsizei;
1987 match self {
1988 Gl::Gl(gl) => unsafe { gl.Uniform1fv(location, len, values.as_ptr()) },
1989 Gl::Gles(gles) => unsafe { gles.Uniform1fv(location, len, values.as_ptr()) },
1990 }
1991 }
1992
1993 pub fn uniform_1i(&self, location: GLint, v0: GLint) {
1994 match self {
1995 Gl::Gl(gl) => unsafe { gl.Uniform1i(location, v0) },
1996 Gl::Gles(gles) => unsafe { gles.Uniform1i(location, v0) },
1997 }
1998 }
1999
2000 pub fn uniform_1iv(&self, location: GLint, values: &[i32]) {
2001 let len = values.len() as GLsizei;
2002 match self {
2003 Gl::Gl(gl) => unsafe { gl.Uniform1iv(location, len, values.as_ptr()) },
2004 Gl::Gles(gles) => unsafe { gles.Uniform1iv(location, len, values.as_ptr()) },
2005 }
2006 }
2007
2008 pub fn uniform_1ui(&self, location: GLint, v0: GLuint) {
2009 match self {
2010 Gl::Gl(gl) => unsafe { gl.Uniform1ui(location, v0) },
2011 Gl::Gles(gles) => unsafe { gles.Uniform1ui(location, v0) },
2012 }
2013 }
2014
2015 pub fn uniform_1uiv(&self, location: GLint, values: &[u32]) {
2016 let len = values.len() as GLsizei;
2017 match self {
2018 Gl::Gl(gl) => unsafe { gl.Uniform1uiv(location, len, values.as_ptr()) },
2019 Gl::Gles(gles) => unsafe { gles.Uniform1uiv(location, len, values.as_ptr()) },
2020 }
2021 }
2022
2023 pub fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) {
2024 match self {
2025 Gl::Gl(gl) => unsafe { gl.Uniform2f(location, v0, v1) },
2026 Gl::Gles(gles) => unsafe { gles.Uniform2f(location, v0, v1) },
2027 }
2028 }
2029
2030 pub fn uniform_2fv(&self, location: GLint, values: &[f32]) {
2031 let len = values.len() as GLsizei / 2;
2032 match self {
2033 Gl::Gl(gl) => unsafe { gl.Uniform2fv(location, len, values.as_ptr()) },
2034 Gl::Gles(gles) => unsafe { gles.Uniform2fv(location, len, values.as_ptr()) },
2035 }
2036 }
2037
2038 pub fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) {
2039 match self {
2040 Gl::Gl(gl) => unsafe { gl.Uniform2i(location, v0, v1) },
2041 Gl::Gles(gles) => unsafe { gles.Uniform2i(location, v0, v1) },
2042 }
2043 }
2044
2045 pub fn uniform_2iv(&self, location: GLint, values: &[i32]) {
2046 let len = values.len() as GLsizei / 2;
2047 match self {
2048 Gl::Gl(gl) => unsafe { gl.Uniform2iv(location, len, values.as_ptr()) },
2049 Gl::Gles(gles) => unsafe { gles.Uniform2iv(location, len, values.as_ptr()) },
2050 }
2051 }
2052
2053 pub fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) {
2054 match self {
2055 Gl::Gl(gl) => unsafe { gl.Uniform2ui(location, v0, v1) },
2056 Gl::Gles(gles) => unsafe { gles.Uniform2ui(location, v0, v1) },
2057 }
2058 }
2059
2060 pub fn uniform_2uiv(&self, location: GLint, values: &[u32]) {
2061 let len = values.len() as GLsizei / 2;
2062 match self {
2063 Gl::Gl(gl) => unsafe { gl.Uniform2uiv(location, len, values.as_ptr()) },
2064 Gl::Gles(gles) => unsafe { gles.Uniform2uiv(location, len, values.as_ptr()) },
2065 }
2066 }
2067
2068 pub fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) {
2069 match self {
2070 Gl::Gl(gl) => unsafe { gl.Uniform3f(location, v0, v1, v2) },
2071 Gl::Gles(gles) => unsafe { gles.Uniform3f(location, v0, v1, v2) },
2072 }
2073 }
2074
2075 pub fn uniform_3fv(&self, location: GLint, values: &[f32]) {
2076 let len = values.len() as GLsizei / 3;
2077 match self {
2078 Gl::Gl(gl) => unsafe { gl.Uniform3fv(location, len, values.as_ptr()) },
2079 Gl::Gles(gles) => unsafe { gles.Uniform3fv(location, len, values.as_ptr()) },
2080 }
2081 }
2082
2083 pub fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) {
2084 match self {
2085 Gl::Gl(gl) => unsafe { gl.Uniform3i(location, v0, v1, v2) },
2086 Gl::Gles(gles) => unsafe { gles.Uniform3i(location, v0, v1, v2) },
2087 }
2088 }
2089
2090 pub fn uniform_3iv(&self, location: GLint, values: &[i32]) {
2091 let len = values.len() as GLsizei / 3;
2092 match self {
2093 Gl::Gl(gl) => unsafe { gl.Uniform3iv(location, len, values.as_ptr()) },
2094 Gl::Gles(gles) => unsafe { gles.Uniform3iv(location, len, values.as_ptr()) },
2095 }
2096 }
2097
2098 pub fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) {
2099 match self {
2100 Gl::Gl(gl) => unsafe { gl.Uniform3ui(location, v0, v1, v2) },
2101 Gl::Gles(gles) => unsafe { gles.Uniform3ui(location, v0, v1, v2) },
2102 }
2103 }
2104
2105 pub fn uniform_3uiv(&self, location: GLint, values: &[u32]) {
2106 let len = values.len() as GLsizei / 3;
2107 match self {
2108 Gl::Gl(gl) => unsafe { gl.Uniform3uiv(location, len, values.as_ptr()) },
2109 Gl::Gles(gles) => unsafe { gles.Uniform3uiv(location, len, values.as_ptr()) },
2110 }
2111 }
2112
2113 pub fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
2114 match self {
2115 Gl::Gl(gl) => unsafe { gl.Uniform4f(location, x, y, z, w) },
2116 Gl::Gles(gles) => unsafe { gles.Uniform4f(location, x, y, z, w) },
2117 }
2118 }
2119
2120 pub fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) {
2121 match self {
2122 Gl::Gl(gl) => unsafe { gl.Uniform4i(location, x, y, z, w) },
2123 Gl::Gles(gles) => unsafe { gles.Uniform4i(location, x, y, z, w) },
2124 }
2125 }
2126
2127 pub fn uniform_4iv(&self, location: GLint, values: &[i32]) {
2128 let len = values.len() as GLsizei / 4;
2129 match self {
2130 Gl::Gl(gl) => unsafe { gl.Uniform4iv(location, len, values.as_ptr()) },
2131 Gl::Gles(gles) => unsafe { gles.Uniform4iv(location, len, values.as_ptr()) },
2132 }
2133 }
2134
2135 pub fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) {
2136 match self {
2137 Gl::Gl(gl) => unsafe { gl.Uniform4ui(location, x, y, z, w) },
2138 Gl::Gles(gles) => unsafe { gles.Uniform4ui(location, x, y, z, w) },
2139 }
2140 }
2141
2142 pub fn uniform_4uiv(&self, location: GLint, values: &[u32]) {
2143 let len = values.len() as GLsizei / 4;
2144 match self {
2145 Gl::Gl(gl) => unsafe { gl.Uniform4uiv(location, len, values.as_ptr()) },
2146 Gl::Gles(gles) => unsafe { gles.Uniform4uiv(location, len, values.as_ptr()) },
2147 }
2148 }
2149
2150 pub fn uniform_4fv(&self, location: GLint, values: &[f32]) {
2151 let len = values.len() as GLsizei / 4;
2152 match self {
2153 Gl::Gl(gl) => unsafe { gl.Uniform4fv(location, len, values.as_ptr()) },
2154 Gl::Gles(gles) => unsafe { gles.Uniform4fv(location, len, values.as_ptr()) },
2155 }
2156 }
2157
2158 pub fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2159 let len = values.len() as GLsizei / 4;
2160 let transpose = transpose as GLboolean;
2161 match self {
2162 Gl::Gl(gl) => unsafe {
2163 gl.UniformMatrix2fv(location, len, transpose, values.as_ptr())
2164 },
2165 Gl::Gles(gles) => unsafe {
2166 gles.UniformMatrix2fv(location, len, transpose, values.as_ptr())
2167 },
2168 }
2169 }
2170
2171 pub fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2172 let len = values.len() as GLsizei / 9;
2173 let transpose = transpose as GLboolean;
2174 match self {
2175 Gl::Gl(gl) => unsafe {
2176 gl.UniformMatrix3fv(location, len, transpose, values.as_ptr())
2177 },
2178 Gl::Gles(gles) => unsafe {
2179 gles.UniformMatrix3fv(location, len, transpose, values.as_ptr())
2180 },
2181 }
2182 }
2183
2184 pub fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2185 let len = values.len() as GLsizei / 16;
2186 let transpose = transpose as GLboolean;
2187 match self {
2188 Gl::Gl(gl) => unsafe {
2189 gl.UniformMatrix4fv(location, len, transpose, values.as_ptr())
2190 },
2191 Gl::Gles(gles) => unsafe {
2192 gles.UniformMatrix4fv(location, len, transpose, values.as_ptr())
2193 },
2194 }
2195 }
2196
2197 pub fn uniform_matrix_3x2fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2198 let len = values.len() as GLsizei / (3 * 2);
2199 let transpose = transpose as GLboolean;
2200 match self {
2201 Gl::Gl(gl) => unsafe {
2202 gl.UniformMatrix3x2fv(location, len, transpose, values.as_ptr())
2203 },
2204 Gl::Gles(gles) => unsafe {
2205 gles.UniformMatrix3x2fv(location, len, transpose, values.as_ptr())
2206 },
2207 }
2208 }
2209
2210 pub fn uniform_matrix_4x2fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2211 let len = values.len() as GLsizei / (4 * 2);
2212 let transpose = transpose as GLboolean;
2213 match self {
2214 Gl::Gl(gl) => unsafe {
2215 gl.UniformMatrix4x2fv(location, len, transpose, values.as_ptr())
2216 },
2217 Gl::Gles(gles) => unsafe {
2218 gles.UniformMatrix4x2fv(location, len, transpose, values.as_ptr())
2219 },
2220 }
2221 }
2222
2223 pub fn uniform_matrix_2x3fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2224 let len = values.len() as GLsizei / (2 * 3);
2225 let transpose = transpose as GLboolean;
2226 match self {
2227 Gl::Gl(gl) => unsafe {
2228 gl.UniformMatrix2x3fv(location, len, transpose, values.as_ptr())
2229 },
2230 Gl::Gles(gles) => unsafe {
2231 gles.UniformMatrix2x3fv(location, len, transpose, values.as_ptr())
2232 },
2233 }
2234 }
2235
2236 pub fn uniform_matrix_4x3fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2237 let len = values.len() as GLsizei / (4 * 3);
2238 let transpose = transpose as GLboolean;
2239 match self {
2240 Gl::Gl(gl) => unsafe {
2241 gl.UniformMatrix4x3fv(location, len, transpose, values.as_ptr())
2242 },
2243 Gl::Gles(gles) => unsafe {
2244 gles.UniformMatrix4x3fv(location, len, transpose, values.as_ptr())
2245 },
2246 }
2247 }
2248
2249 pub fn uniform_matrix_2x4fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2250 let len = values.len() as GLsizei / (2 * 4);
2251 let transpose = transpose as GLboolean;
2252 match self {
2253 Gl::Gl(gl) => unsafe {
2254 gl.UniformMatrix2x4fv(location, len, transpose, values.as_ptr())
2255 },
2256 Gl::Gles(gles) => unsafe {
2257 gles.UniformMatrix2x4fv(location, len, transpose, values.as_ptr())
2258 },
2259 }
2260 }
2261
2262 pub fn uniform_matrix_3x4fv(&self, location: GLint, transpose: bool, values: &[f32]) {
2263 let len = values.len() as GLsizei / (3 * 4);
2264 let transpose = transpose as GLboolean;
2265 match self {
2266 Gl::Gl(gl) => unsafe {
2267 gl.UniformMatrix3x4fv(location, len, transpose, values.as_ptr())
2268 },
2269 Gl::Gles(gles) => unsafe {
2270 gles.UniformMatrix3x4fv(location, len, transpose, values.as_ptr())
2271 },
2272 }
2273 }
2274
2275
2276 pub fn use_program(&self, program: GLuint) {
2277 match self {
2278 Gl::Gl(gl) => unsafe { gl.UseProgram(program) },
2279 Gl::Gles(gles) => unsafe { gles.UseProgram(program) },
2280 }
2281 }
2282
2283 pub fn blit_framebuffer(
2284 &self,
2285 src_x0: GLint,
2286 src_y0: GLint,
2287 src_x1: GLint,
2288 src_y1: GLint,
2289 dst_x0: GLint,
2290 dst_y0: GLint,
2291 dst_x1: GLint,
2292 dst_y1: GLint,
2293 mask: GLbitfield,
2294 filter: GLenum,
2295 ) {
2296 match self {
2297 Gl::Gl(gl) => unsafe {
2298 gl.BlitFramebuffer(
2299 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
2300 )
2301 },
2302 Gl::Gles(gles) => unsafe {
2303 gles.BlitFramebuffer(
2304 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
2305 )
2306 },
2307 }
2308 }
2309
2310 pub fn gen_queries(&self, n: GLsizei) -> Vec<GLuint> {
2311 if let Gl::Gles(gles) = self {
2312 if !gles.GenQueriesEXT.is_loaded() {
2313 return Vec::new();
2314 }
2315 }
2316 let mut result = vec![0 as GLuint; n as usize];
2317 match self {
2318 Gl::Gl(gl) => unsafe { gl.GenQueries(n, result.as_mut_ptr()) },
2319 Gl::Gles(gles) => unsafe { gles.GenQueriesEXT(n, result.as_mut_ptr()) },
2320 };
2321 result
2322 }
2323
2324 pub fn begin_query(&self, target: GLenum, id: GLuint) {
2325 match self {
2326 Gl::Gl(gl) => unsafe { gl.BeginQuery(target, id) },
2327 Gl::Gles(gles) => {
2328 if gles.BeginQueryEXT.is_loaded() {
2329 unsafe { gles.BeginQueryEXT(target, id) }
2330 }
2331 },
2332 }
2333 }
2334
2335 pub fn end_query(&self, target: GLenum) {
2336 match self {
2337 Gl::Gl(gl) => unsafe { gl.EndQuery(target) },
2338 Gl::Gles(gles) => {
2339 if gles.EndQueryEXT.is_loaded() {
2340 unsafe { gles.EndQueryEXT(target) }
2341 }
2342 },
2343 }
2344 }
2345
2346 pub fn delete_queries(&self, ids: &[GLuint]) {
2347 match self {
2348 Gl::Gl(gl) => unsafe { gl.DeleteQueries(ids.len() as GLsizei, ids.as_ptr()) },
2349 Gl::Gles(gles) => {
2350 if gles.DeleteQueriesEXT.is_loaded() {
2351 unsafe { gles.DeleteQueriesEXT(ids.len() as GLsizei, ids.as_ptr()) }
2352 }
2353 },
2354 }
2355 }
2356
2357 pub fn is_query(&self, id: GLuint) -> bool {
2358 TRUE == match self {
2359 Gl::Gl(gl) => unsafe { gl.IsQuery(id) },
2360 Gl::Gles(gles) => {
2361 match gles.IsQueryEXT.is_loaded() {
2362 true => unsafe { gles.IsQueryEXT(id) },
2363 false => FALSE,
2364 }
2365 },
2366 }
2367 }
2368
2369 pub fn get_query_iv(&self, target: GLenum, pname: GLenum) -> i32 {
2370 let mut result = 0;
2371 match self {
2372 Gl::Gl(gl) => unsafe { gl.GetQueryiv(target, pname, &mut result) },
2373 Gl::Gles(gles) => {
2374 if gles.GetQueryivEXT.is_loaded() {
2375 unsafe { gles.GetQueryivEXT(target, pname, &mut result) }
2376 }
2377 },
2378 };
2379 result
2380 }
2381
2382 pub fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 {
2383 let mut result = 0;
2384 match self {
2385 Gl::Gl(gl) => unsafe { gl.GetQueryObjectiv(id, pname, &mut result) },
2386 Gl::Gles(gles) => {
2387 if gles.GetQueryObjectivEXT.is_loaded() {
2388 unsafe { gles.GetQueryObjectivEXT(id, pname, &mut result) }
2389 }
2390 },
2391 }
2392 result
2393 }
2394
2395 pub fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 {
2396 let mut result = 0;
2397 match self {
2398 Gl::Gl(gl) => unsafe { gl.GetQueryObjectuiv(id, pname, &mut result) },
2399 Gl::Gles(gles) => {
2400 if gles.GetQueryObjectuivEXT.is_loaded() {
2401 unsafe { gles.GetQueryObjectuivEXT(id, pname, &mut result) }
2402 }
2403 },
2404 }
2405 result
2406 }
2407
2408 pub fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 {
2409 let mut result = 0;
2410 match self {
2411 Gl::Gl(gl) => unsafe { gl.GetQueryObjecti64v(id, pname, &mut result) },
2412 Gl::Gles(gles) => {
2413 if gles.GetQueryObjecti64vEXT.is_loaded() {
2414 unsafe { gles.GetQueryObjecti64vEXT(id, pname, &mut result) }
2415 }
2416 },
2417 }
2418 result
2419 }
2420
2421 pub fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 {
2422 let mut result = 0;
2423 match self {
2424 Gl::Gl(gl) => unsafe { gl.GetQueryObjectui64v(id, pname, &mut result) },
2425 Gl::Gles(gles) => {
2426 if gles.GetQueryObjectui64vEXT.is_loaded() {
2427 unsafe { gles.GetQueryObjectui64vEXT(id, pname, &mut result) }
2428 }
2429 },
2430 }
2431 result
2432 }
2433
2434 pub fn gen_samplers(&self, n: GLsizei) -> Vec<GLuint> {
2435 let mut result = vec![0 as GLuint; n as usize];
2436 match self {
2437 Gl::Gl(gl) => unsafe { gl.GenSamplers(n, result.as_mut_ptr()) },
2438 Gl::Gles(gles) => unsafe { gles.GenSamplers(n, result.as_mut_ptr()) },
2439 };
2440 result
2441 }
2442
2443 pub fn delete_samplers(&self, samplers: &[GLuint]) {
2444 match self {
2445 Gl::Gl(gl) => unsafe { gl.DeleteSamplers(samplers.len() as GLsizei, samplers.as_ptr()) },
2446 Gl::Gles(gles) => unsafe { gles.DeleteSamplers(samplers.len() as GLsizei, samplers.as_ptr()) },
2447 }
2448 }
2449
2450 pub fn is_sampler(&self, sampler: GLuint) -> bool {
2451 TRUE == match self {
2452 Gl::Gl(gl) => unsafe { gl.IsSampler(sampler) },
2453 Gl::Gles(gles) => unsafe { gles.IsSampler(sampler) },
2454 }
2455 }
2456
2457 pub fn bind_sampler(&self, target: GLenum, sampler: GLuint) {
2458 match self {
2459 Gl::Gl(gl) => unsafe { gl.BindSampler(target, sampler) },
2460 Gl::Gles(gles) => unsafe { gles.BindSampler(target, sampler) },
2461 }
2462 }
2463
2464 pub fn get_sampler_parameter_iv(&self, sampler: GLuint, pname: GLenum) -> Vec<GLint> {
2465 let mut result = vec![0 as GLint];
2466 match self {
2467 Gl::Gl(gl) => unsafe { gl.GetSamplerParameteriv(sampler, pname, result.as_mut_ptr()) },
2468 Gl::Gles(gles) => unsafe { gles.GetSamplerParameteriv(sampler, pname, result.as_mut_ptr()) },
2469 }
2470 result
2471 }
2472
2473 pub fn get_sampler_parameter_fv(&self, sampler: GLuint, pname: GLenum) -> Vec<GLfloat> {
2474 let mut result = vec![0.0_f32 as GLfloat];
2475 match self {
2476 Gl::Gl(gl) => unsafe { gl.GetSamplerParameterfv(sampler, pname, result.as_mut_ptr()) },
2477 Gl::Gles(gles) => unsafe { gles.GetSamplerParameterfv(sampler, pname, result.as_mut_ptr()) },
2478 }
2479 result
2480 }
2481
2482 pub fn sampler_parameter_i(&self, sampler: GLuint, pname: GLenum, param: GLint) {
2483 match self {
2484 Gl::Gl(gl) => unsafe { gl.SamplerParameteri(sampler, pname, param) },
2485 Gl::Gles(gles) => unsafe { gles.SamplerParameteri(sampler, pname, param) },
2486 }
2487 }
2488
2489 pub fn sampler_parameter_f(&self, sampler: GLuint, pname: GLenum, param: GLfloat) {
2490 match self {
2491 Gl::Gl(gl) => unsafe { gl.SamplerParameterf(sampler, pname, param) },
2492 Gl::Gles(gles) => unsafe { gles.SamplerParameterf(sampler, pname, param) },
2493 }
2494 }
2495
2496 pub fn sampler_parameter_iv(&self, sampler: GLuint, pname: GLenum, params: &[GLint]) {
2497 assert!(!params.is_empty());
2498 match self {
2499 Gl::Gl(gl) => unsafe { gl.SamplerParameteriv(sampler, pname, params.as_ptr()) },
2500 Gl::Gles(gles) => unsafe { gles.SamplerParameteriv(sampler, pname, params.as_ptr()) },
2501 }
2502 }
2503
2504 pub fn sampler_parameter_fv(&self, sampler: GLuint, pname: GLenum, params: &[GLfloat]) {
2505 assert!(!params.is_empty());
2506 match self {
2507 Gl::Gl(gl) => unsafe { gl.SamplerParameterfv(sampler, pname, params.as_ptr()) },
2508 Gl::Gles(gles) => unsafe { gles.SamplerParameterfv(sampler, pname, params.as_ptr()) },
2509 }
2510 }
2511
2512 pub fn gen_transform_feedbacks(&self) -> u32 {
2513 let mut ids = vec![0 as GLuint];
2514 match self {
2515 Gl::Gl(gl) => unsafe { gl.GenTransformFeedbacks(ids.len() as _, ids.as_mut_ptr()) },
2516 Gl::Gles(gles) => unsafe { gles.GenTransformFeedbacks(ids.len() as _, ids.as_mut_ptr()) },
2517 }
2518 ids[0]
2519 }
2520
2521 pub fn delete_transform_feedbacks(&self, id: GLuint) {
2522 let ids = vec![id];
2523 match self {
2524 Gl::Gl(gl) => unsafe { gl.DeleteTransformFeedbacks(ids.len() as _, ids.as_ptr()) },
2525 Gl::Gles(gles) => unsafe { gles.DeleteTransformFeedbacks(ids.len() as _, ids.as_ptr()) },
2526 }
2527 }
2528
2529 pub fn is_transform_feedback(&self, id: GLuint) -> bool {
2530 TRUE == match self {
2531 Gl::Gl(gl) => unsafe { gl.IsTransformFeedback(id) },
2532 Gl::Gles(gles) => unsafe { gles.IsTransformFeedback(id) },
2533 }
2534 }
2535
2536 pub fn bind_transform_feedback(&self, target: GLenum, id: u32) {
2537 match self {
2538 Gl::Gl(gl) => unsafe { gl.BindTransformFeedback(target, id) },
2539 Gl::Gles(gles) => unsafe { gles.BindTransformFeedback(target, id) },
2540 }
2541 }
2542
2543 pub fn begin_transform_feedback(&self, mode: GLenum) {
2544 match self {
2545 Gl::Gl(gl) => unsafe { gl.BeginTransformFeedback(mode) },
2546 Gl::Gles(gles) => unsafe { gles.BeginTransformFeedback(mode) },
2547 }
2548 }
2549
2550 pub fn end_transform_feedback(&self) {
2551 match self {
2552 Gl::Gl(gl) => unsafe { gl.EndTransformFeedback() },
2553 Gl::Gles(gles) => unsafe { gles.EndTransformFeedback() },
2554 }
2555 }
2556
2557 pub fn pause_transform_feedback(&self) {
2558 match self {
2559 Gl::Gl(gl) => unsafe { gl.PauseTransformFeedback() },
2560 Gl::Gles(gles) => unsafe { gles.PauseTransformFeedback() },
2561 }
2562 }
2563
2564 pub fn resume_transform_feedback(&self) {
2565 match self {
2566 Gl::Gl(gl) => unsafe { gl.ResumeTransformFeedback() },
2567 Gl::Gles(gles) => unsafe { gles.ResumeTransformFeedback() },
2568 }
2569 }
2570
2571 pub fn get_transform_feedback_varying(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
2572 let mut length = 0;
2573 let buf_size = 128;
2574 let mut name = vec![0 as c_char; buf_size as usize];
2575 let mut size = 0;
2576 let mut ty = 0;
2577 match self {
2578 Gl::Gl(gl) => unsafe { gl.GetTransformFeedbackVarying(program, index, buf_size, &mut length, &mut size, &mut ty, name.as_mut_ptr()) },
2579 Gl::Gles(gles) => unsafe { gles.GetTransformFeedbackVarying(program, index, buf_size, &mut length, &mut size, &mut ty, name.as_mut_ptr()) },
2580 }
2581 let name: &[u8] = unsafe { std::slice::from_raw_parts(name.as_ptr() as _, length as usize) };
2582 let name = String::from_utf8(name.to_vec()).unwrap();
2583 (size, ty, name)
2584 }
2585
2586 pub fn transform_feedback_varyings(&self, program: GLuint, varyings: &[String], buffer_mode: GLenum) {
2587 let c_varyings = varyings
2588 .iter()
2589 .map(|varying| {
2590 std::ffi::CString::new("_u".to_owned() + varying.as_str()).unwrap()
2591 })
2592 .collect::<Vec<_>>();
2593 let pointers: Vec<*const c_char> =
2594 c_varyings.iter().map(|p| p.as_ptr()).collect();
2595 match self {
2596 Gl::Gl(gl) => unsafe { gl.TransformFeedbackVaryings(program, varyings.len() as _, pointers.as_ptr() as _, buffer_mode) },
2597 Gl::Gles(gles) => unsafe { gles.TransformFeedbackVaryings(program, varyings.len() as _, pointers.as_ptr() as _, buffer_mode) },
2598 }
2599 }
2600
2601 pub fn clear_buffer_iv(&self, buffer: GLenum, draw_buffer: GLint, value: &[GLint]) {
2602 match self {
2603 Gl::Gl(gl) => unsafe { gl.ClearBufferiv(buffer, draw_buffer, value.as_ptr()) },
2604 Gl::Gles(gles) => unsafe { gles.ClearBufferiv(buffer, draw_buffer, value.as_ptr()) },
2605 }
2606 }
2607
2608 pub fn clear_buffer_uiv(&self, buffer: GLenum, draw_buffer: GLint, value: &[GLuint]) {
2609 match self {
2610 Gl::Gl(gl) => unsafe { gl.ClearBufferuiv(buffer, draw_buffer, value.as_ptr()) },
2611 Gl::Gles(gles) => unsafe { gles.ClearBufferuiv(buffer, draw_buffer, value.as_ptr()) },
2612 }
2613 }
2614
2615 pub fn clear_buffer_fv(&self, buffer: GLenum, draw_buffer: GLint, value: &[GLfloat]) {
2616 match self {
2617 Gl::Gl(gl) => unsafe { gl.ClearBufferfv(buffer, draw_buffer, value.as_ptr()) },
2618 Gl::Gles(gles) => unsafe { gles.ClearBufferfv(buffer, draw_buffer, value.as_ptr()) },
2619 }
2620 }
2621
2622 pub fn clear_buffer_fi(
2623 &self,
2624 buffer: GLenum,
2625 draw_buffer: GLint,
2626 depth: GLfloat,
2627 stencil: GLint,
2628 ) {
2629 match self {
2630 Gl::Gl(gl) => unsafe { gl.ClearBufferfi(buffer, draw_buffer, depth, stencil) },
2631 Gl::Gles(gles) => unsafe { gles.ClearBufferfi(buffer, draw_buffer, depth, stencil) },
2632 }
2633 }
2634 }
2635
2636 fn calculate_length(
2637 width: GLsizei,
2638 height: GLsizei,
2639 format: GLenum,
2640 pixel_type: GLenum,
2641 ) -> usize {
2642 let colors = match format {
2643 ffi::RED => 1,
2644 ffi::RGB => 3,
2645 ffi::BGR => 3,
2646
2647 ffi::RGBA => 4,
2648 ffi::BGRA => 4,
2649
2650 ffi::ALPHA => 1,
2651 ffi::R16 => 1,
2652 ffi::LUMINANCE => 1,
2653 ffi::DEPTH_COMPONENT => 1,
2654 _ => panic!("unsupported format: {:?}", format),
2655 };
2656 let depth = match pixel_type {
2657 ffi::UNSIGNED_BYTE => 1,
2658 ffi::UNSIGNED_SHORT => 2,
2659 ffi::SHORT => 2,
2660 ffi::FLOAT => 4,
2661 _ => panic!("unsupported pixel_type: {:?}", pixel_type),
2662 };
2663
2664 (width * height * colors * depth) as usize
2665 }
2666
2667 pub fn buffer_data<T>(gl_: &Gl, target: GLenum, data: &[T], usage: GLenum) {
2668 unsafe {
2669 gl_.buffer_data(
2670 target,
2671 (data.len() * size_of::<T>()) as GLsizeiptr,
2672 data.as_ptr() as *const GLvoid,
2673 usage,
2674 )
2675 }
2676 }
2677
2678 pub fn buffer_sub_data<T>(gl_: &Gl, target: GLenum, offset: isize, data: &[T]) {
2679 unsafe {
2680 gl_.buffer_sub_data(
2681 target,
2682 offset,
2683 (data.len() * size_of::<T>()) as GLsizeiptr,
2684 data.as_ptr() as *const GLvoid,
2685 );
2686 }
2687 }
2688
2689 pub mod ffi {
2690 include!(concat!(env!("OUT_DIR"), "/gl_and_gles_bindings.rs"));
2691 }
2692
2693 pub mod ffi_gl {
2694 include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
2695 }
2696
2697 pub mod ffi_gles {
2698 include!(concat!(env!("OUT_DIR"), "/gles_bindings.rs"));
2699 }
2700}