1use super::*;
2use crate::{gl46 as native_gl, version::Version};
3use std::ffi::CStr;
4use std::ptr;
5use std::{collections::HashSet, ffi::CString, num::NonZeroU32};
6
7macro_rules! khr_fallback {
8 ($gl:ident . $is_loaded:ident, $gl2:ident . $khr:ident, $gl3:ident . $core:ident ($($arg:expr),* $(,)?) $(,)?) => {
9 if $gl.$is_loaded() {
10 $gl3.$core($($arg),*)
11 } else {
12 $gl2.$khr($($arg),*)
13 }
14 };
15}
16
17#[derive(Default)]
18struct Constants {
19 max_label_length: i32,
20}
21
22struct DebugCallbackRawPtr {
29 callback: *mut std::os::raw::c_void,
30}
31
32unsafe impl Send for DebugCallbackRawPtr {}
33unsafe impl Sync for DebugCallbackRawPtr {}
34
35impl Drop for DebugCallbackRawPtr {
36 fn drop(&mut self) {
37 unsafe {
38 let thin_ptr = Box::from_raw(self.callback as *mut DebugCallback);
40 let callback = *thin_ptr;
41 drop(callback);
42 }
43 }
44}
45
46pub struct Context {
47 raw: native_gl::GlFns,
48 extensions: HashSet<String>,
49 constants: Constants,
50 version: Version,
51 debug_callback: Option<DebugCallbackRawPtr>,
52}
53
54impl Context {
55 pub unsafe fn from_loader_function_cstr<F>(mut loader_function: F) -> Self
56 where
57 F: FnMut(&CStr) -> *const std::os::raw::c_void,
58 {
59 let raw: native_gl::GlFns =
60 native_gl::GlFns::load_with(|p: *const std::os::raw::c_char| {
61 let c_str = std::ffi::CStr::from_ptr(p);
62 loader_function(c_str) as *mut std::os::raw::c_void
63 });
64
65 let raw_string = raw.GetString(VERSION);
67
68 if raw_string.is_null() {
69 panic!("Reading GL_VERSION failed. Make sure there is a valid GL context currently active.")
70 }
71
72 let raw_version = std::ffi::CStr::from_ptr(raw_string as *const native_gl::GLchar)
73 .to_str()
74 .unwrap()
75 .to_owned();
76 let version = Version::parse(&raw_version).unwrap();
77
78 let mut context = Self {
80 raw,
81 extensions: HashSet::new(),
82 constants: Constants::default(),
83 version,
84 debug_callback: None,
85 };
86
87 if (context.version >= Version::new(3, 0, None, String::from("")))
89 || (context.version >= Version::new_embedded(3, 0, String::from("")))
90 {
91 let num_extensions = context.get_parameter_i32(NUM_EXTENSIONS);
92 for i in 0..num_extensions {
93 let extension_name = context.get_parameter_indexed_string(EXTENSIONS, i as u32);
94 context.extensions.insert(extension_name);
95 }
96 } else {
97 context.extensions.extend(
99 context
100 .get_parameter_string(EXTENSIONS)
101 .split(' ')
102 .map(|s| s.to_string()),
103 );
104 };
105
106 context.constants.max_label_length = if context.supports_debug() {
109 context.get_parameter_i32(MAX_LABEL_LENGTH)
110 } else {
111 0
112 };
113
114 context
115 }
116
117 pub unsafe fn from_loader_function<F>(mut loader_function: F) -> Self
118 where
119 F: FnMut(&str) -> *const std::os::raw::c_void,
120 {
121 Self::from_loader_function_cstr(move |name| loader_function(name.to_str().unwrap()))
122 }
123
124 #[deprecated = "Use the NativeTexture constructor instead"]
129 pub unsafe fn create_texture_from_gl_name(gl_name: native_gl::GLuint) -> NativeTexture {
130 NativeTexture(non_zero_gl_name(gl_name))
131 }
132
133 #[deprecated = "Use the NativeFramebuffer constructor instead"]
138 pub unsafe fn create_framebuffer_from_gl_name(gl_name: native_gl::GLuint) -> NativeFramebuffer {
139 NativeFramebuffer(non_zero_gl_name(gl_name))
140 }
141
142 unsafe fn get_parameter_gl_name(&self, parameter: u32) -> Option<NonZeroU32> {
143 let value = self.get_parameter_i32(parameter) as u32;
144 if value == 0 {
145 None
146 } else {
147 Some(non_zero_gl_name(value))
148 }
149 }
150}
151
152impl std::fmt::Debug for Context {
153 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
154 write!(f, "Native_GL_Context")
155 }
156}
157
158fn non_zero_gl_name(value: native_gl::GLuint) -> NonZeroU32 {
159 NonZeroU32::new(value as u32).expect("expected non-zero GL name")
160}
161
162#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
163pub struct NativeShader(pub NonZeroU32);
164
165#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
166pub struct NativeProgram(pub NonZeroU32);
167
168#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
169pub struct NativeBuffer(pub NonZeroU32);
170
171#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
172pub struct NativeVertexArray(pub NonZeroU32);
173
174#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
175pub struct NativeTexture(pub NonZeroU32);
176
177#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
178pub struct NativeSampler(pub NonZeroU32);
179
180#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
181pub struct NativeFence(pub native_gl::GLsync);
182
183#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
184pub struct NativeFramebuffer(pub NonZeroU32);
185
186#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
187pub struct NativeRenderbuffer(pub NonZeroU32);
188
189#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
190pub struct NativeQuery(pub NonZeroU32);
191
192#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
193pub struct NativeUniformLocation(pub native_gl::GLuint);
194
195#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
196pub struct NativeTransformFeedback(pub NonZeroU32);
197
198impl crate::__private::Sealed for Context {}
199
200impl HasContext for Context {
201 type Shader = NativeShader;
202 type Program = NativeProgram;
203 type Buffer = NativeBuffer;
204 type VertexArray = NativeVertexArray;
205 type Texture = NativeTexture;
206 type Sampler = NativeSampler;
207 type Fence = NativeFence;
208 type Framebuffer = NativeFramebuffer;
209 type Renderbuffer = NativeRenderbuffer;
210 type Query = NativeQuery;
211 type UniformLocation = NativeUniformLocation;
212 type TransformFeedback = NativeTransformFeedback;
213
214 fn supported_extensions(&self) -> &HashSet<String> {
215 &self.extensions
216 }
217
218 fn supports_debug(&self) -> bool {
219 if self.extensions.contains("GL_KHR_debug") {
220 true
222 } else if self.version.is_embedded {
223 self.version.major == 3 && self.version.minor >= 2
225 } else {
226 self.version.major == 4 && self.version.minor >= 3
228 }
229 }
230
231 fn version(&self) -> &Version {
232 &self.version
233 }
234
235 unsafe fn create_framebuffer(&self) -> Result<Self::Framebuffer, String> {
236 let gl = &self.raw;
237 let mut name = 0;
238 gl.GenFramebuffers(1, &mut name);
239 NonZeroU32::new(name)
240 .map(NativeFramebuffer)
241 .ok_or_else(|| String::from("Unable to create Framebuffer object"))
242 }
243
244 unsafe fn create_named_framebuffer(&self) -> Result<Self::Framebuffer, String> {
245 let gl = &self.raw;
246 let mut name = 0;
247 gl.CreateFramebuffers(1, &mut name);
248 NonZeroU32::new(name)
249 .map(NativeFramebuffer)
250 .ok_or_else(|| String::from("Unable to create Framebuffer object"))
251 }
252
253 unsafe fn is_framebuffer(&self, framebuffer: Self::Framebuffer) -> bool {
254 let gl = &self.raw;
255 gl.IsFramebuffer(framebuffer.0.get()) != 0
256 }
257
258 unsafe fn create_query(&self) -> Result<Self::Query, String> {
259 let gl = &self.raw;
260 let mut name = 0;
261 if gl.GenQueries_is_loaded() {
262 gl.GenQueries(1, &mut name);
263 } else {
264 gl.GenQueriesEXT(1, &mut name);
265 }
266 NonZeroU32::new(name)
267 .map(NativeQuery)
268 .ok_or_else(|| String::from("Unable to create Query object"))
269 }
270
271 unsafe fn create_renderbuffer(&self) -> Result<Self::Renderbuffer, String> {
272 let gl = &self.raw;
273 let mut name = 0;
274 gl.GenRenderbuffers(1, &mut name);
275 NonZeroU32::new(name)
276 .map(NativeRenderbuffer)
277 .ok_or_else(|| String::from("Unable to create Renderbuffer object"))
278 }
279
280 unsafe fn is_renderbuffer(&self, renderbuffer: Self::Renderbuffer) -> bool {
281 let gl = &self.raw;
282 gl.IsRenderbuffer(renderbuffer.0.get()) != 0
283 }
284
285 unsafe fn create_sampler(&self) -> Result<Self::Sampler, String> {
286 let gl = &self.raw;
287 let mut name = 0;
288 gl.GenSamplers(1, &mut name);
289 NonZeroU32::new(name)
290 .map(NativeSampler)
291 .ok_or_else(|| String::from("Unable to create Sampler object"))
292 }
293
294 unsafe fn create_shader(&self, shader_type: u32) -> Result<Self::Shader, String> {
295 let gl = &self.raw;
296 NonZeroU32::new(gl.CreateShader(shader_type as u32))
297 .map(NativeShader)
298 .ok_or_else(|| String::from("Unable to create Shader object"))
299 }
300
301 unsafe fn is_shader(&self, shader: Self::Shader) -> bool {
302 let gl = &self.raw;
303 gl.IsShader(shader.0.get()) != 0
304 }
305
306 unsafe fn create_texture(&self) -> Result<Self::Texture, String> {
307 let gl = &self.raw;
308 let mut name = 0;
309 gl.GenTextures(1, &mut name);
310 NonZeroU32::new(name)
311 .map(NativeTexture)
312 .ok_or_else(|| String::from("Unable to create Texture object"))
313 }
314
315 unsafe fn create_named_texture(&self, target: u32) -> Result<Self::Texture, String> {
316 let gl = &self.raw;
317 let mut name = 0;
318 gl.CreateTextures(target, 1, &mut name);
319 NonZeroU32::new(name)
320 .map(NativeTexture)
321 .ok_or_else(|| String::from("Unable to create Texture object"))
322 }
323
324 unsafe fn is_texture(&self, texture: Self::Texture) -> bool {
325 let gl = &self.raw;
326 gl.IsTexture(texture.0.get()) != 0
327 }
328
329 unsafe fn delete_shader(&self, shader: Self::Shader) {
330 let gl = &self.raw;
331 gl.DeleteShader(shader.0.get());
332 }
333
334 unsafe fn shader_source(&self, shader: Self::Shader, source: &str) {
335 let gl = &self.raw;
336 gl.ShaderSource(
337 shader.0.get(),
338 1,
339 &(source.as_ptr() as *const native_gl::GLchar),
340 &(source.len() as native_gl::GLint),
341 );
342 }
343
344 unsafe fn compile_shader(&self, shader: Self::Shader) {
345 let gl = &self.raw;
346 gl.CompileShader(shader.0.get());
347 }
348
349 unsafe fn get_shader_completion_status(&self, shader: Self::Shader) -> bool {
350 let gl = &self.raw;
351 let mut status = 0;
352 gl.GetShaderiv(shader.0.get(), COMPLETION_STATUS, &mut status);
353 1 == status
354 }
355
356 unsafe fn get_shader_compile_status(&self, shader: Self::Shader) -> bool {
357 let gl = &self.raw;
358 let mut status = 0;
359 gl.GetShaderiv(shader.0.get(), COMPILE_STATUS, &mut status);
360 1 == status
361 }
362
363 unsafe fn get_shader_info_log(&self, shader: Self::Shader) -> String {
364 let gl = &self.raw;
365 let mut length = 0;
366 gl.GetShaderiv(shader.0.get(), INFO_LOG_LENGTH, &mut length);
367 if length > 0 {
368 let mut log = String::with_capacity(length as usize);
369 log.extend(std::iter::repeat('\0').take(length as usize));
370 gl.GetShaderInfoLog(
371 shader.0.get(),
372 length,
373 &mut length,
374 (&log[..]).as_ptr() as *mut native_gl::GLchar,
375 );
376 log.truncate(length as usize);
377 log
378 } else {
379 String::from("")
380 }
381 }
382
383 unsafe fn get_shader_precision_format(
384 &self,
385 shader_type: u32,
386 precision_type: u32,
387 ) -> Option<ShaderPrecisionFormat> {
388 let gl = &self.raw;
389
390 if gl.GetShaderPrecisionFormat_is_loaded() {
391 let mut range = [0, 0];
392 let mut precision = 0;
393 gl.GetShaderPrecisionFormat(
394 shader_type,
395 precision_type,
396 range.as_mut_ptr(),
397 &mut precision,
398 );
399 if range[1] != 0 {
402 return Some(ShaderPrecisionFormat {
403 range_min: range[0],
404 range_max: range[1],
405 precision,
406 });
407 }
408 }
409
410 None
411 }
412
413 unsafe fn get_tex_image(
414 &self,
415 target: u32,
416 level: i32,
417 format: u32,
418 ty: u32,
419 pixels: PixelPackData,
420 ) {
421 let gl = &self.raw;
422 gl.GetTexImage(
423 target,
424 level,
425 format,
426 ty,
427 match pixels {
428 PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void,
429 PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut std::ffi::c_void,
430 PixelPackData::Slice(None) => ptr::null_mut(),
431 },
432 );
433 }
434
435 unsafe fn create_program(&self) -> Result<Self::Program, String> {
436 let gl = &self.raw;
437 NonZeroU32::new(gl.CreateProgram())
438 .map(NativeProgram)
439 .ok_or_else(|| String::from("Unable to create Program object"))
440 }
441
442 unsafe fn is_program(&self, program: Self::Program) -> bool {
443 let gl = &self.raw;
444 gl.IsProgram(program.0.get()) != 0
445 }
446
447 unsafe fn delete_program(&self, program: Self::Program) {
448 let gl = &self.raw;
449 gl.DeleteProgram(program.0.get());
450 }
451
452 unsafe fn attach_shader(&self, program: Self::Program, shader: Self::Shader) {
453 let gl = &self.raw;
454 gl.AttachShader(program.0.get(), shader.0.get());
455 }
456
457 unsafe fn detach_shader(&self, program: Self::Program, shader: Self::Shader) {
458 let gl = &self.raw;
459 gl.DetachShader(program.0.get(), shader.0.get());
460 }
461
462 unsafe fn link_program(&self, program: Self::Program) {
463 let gl = &self.raw;
464 gl.LinkProgram(program.0.get());
465 }
466
467 unsafe fn validate_program(&self, program: Self::Program) {
468 let gl = &self.raw;
469 gl.ValidateProgram(program.0.get());
470 }
471
472 unsafe fn get_program_completion_status(&self, program: Self::Program) -> bool {
473 let gl = &self.raw;
474 let mut status = 0;
475 gl.GetProgramiv(program.0.get(), COMPLETION_STATUS, &mut status);
476 1 == status
477 }
478
479 unsafe fn get_program_link_status(&self, program: Self::Program) -> bool {
480 let gl = &self.raw;
481 let mut status = 0;
482 gl.GetProgramiv(program.0.get(), LINK_STATUS, &mut status);
483 1 == status
484 }
485
486 unsafe fn get_program_validate_status(&self, program: Self::Program) -> bool {
487 let gl = &self.raw;
488 let mut status = 0;
489 gl.GetProgramiv(program.0.get(), VALIDATE_STATUS, &mut status);
490 status == 1
491 }
492
493 unsafe fn get_program_parameter_i32(&self, program: Self::Program, parameter: u32) -> i32 {
494 let gl = &self.raw;
495 let mut value = 0;
496 gl.GetProgramiv(program.0.get(), parameter, &mut value);
497 value
498 }
499
500 unsafe fn get_program_info_log(&self, program: Self::Program) -> String {
501 let gl = &self.raw;
502 let mut length = 0;
503 gl.GetProgramiv(program.0.get(), INFO_LOG_LENGTH, &mut length);
504 if length > 0 {
505 let mut log = String::with_capacity(length as usize);
506 log.extend(std::iter::repeat('\0').take(length as usize));
507 gl.GetProgramInfoLog(
508 program.0.get(),
509 length,
510 &mut length,
511 (&log[..]).as_ptr() as *mut native_gl::GLchar,
512 );
513 log.truncate(length as usize);
514 log
515 } else {
516 String::from("")
517 }
518 }
519
520 unsafe fn get_program_resource_i32(
521 &self,
522 program: Self::Program,
523 interface: u32,
524 index: u32,
525 properties: &[u32],
526 ) -> Vec<i32> {
527 let gl = &self.raw;
528 let mut length = 0i32;
530 gl.GetProgramResourceiv(
531 program.0.get(),
532 interface,
533 index,
534 properties.len() as i32,
535 properties.as_ptr(),
536 0,
537 &mut length,
538 ptr::null_mut(),
539 );
540 let mut params = vec![0i32; length as usize];
542 gl.GetProgramResourceiv(
543 program.0.get(),
544 interface,
545 index,
546 properties.len() as i32,
547 properties.as_ptr(),
548 length,
549 &mut length,
550 params.as_mut_ptr(),
551 );
552 params
553 }
554
555 unsafe fn program_uniform_1_i32(
556 &self,
557 program: Self::Program,
558 location: Option<&Self::UniformLocation>,
559 x: i32,
560 ) {
561 let gl = &self.raw;
562 if let Some(loc) = location {
563 gl.ProgramUniform1i(program.0.get(), loc.0 as i32, x);
564 }
565 }
566
567 unsafe fn program_uniform_2_i32(
568 &self,
569 program: Self::Program,
570 location: Option<&Self::UniformLocation>,
571 x: i32,
572 y: i32,
573 ) {
574 let gl = &self.raw;
575 if let Some(loc) = location {
576 gl.ProgramUniform2i(program.0.get(), loc.0 as i32, x, y);
577 }
578 }
579
580 unsafe fn program_uniform_3_i32(
581 &self,
582 program: Self::Program,
583 location: Option<&Self::UniformLocation>,
584 x: i32,
585 y: i32,
586 z: i32,
587 ) {
588 let gl = &self.raw;
589 if let Some(loc) = location {
590 gl.ProgramUniform3i(program.0.get(), loc.0 as i32, x, y, z);
591 }
592 }
593
594 unsafe fn program_uniform_4_i32(
595 &self,
596 program: Self::Program,
597 location: Option<&Self::UniformLocation>,
598 x: i32,
599 y: i32,
600 z: i32,
601 w: i32,
602 ) {
603 let gl = &self.raw;
604 if let Some(loc) = location {
605 gl.ProgramUniform4i(program.0.get(), loc.0 as i32, x, y, z, w);
606 }
607 }
608
609 unsafe fn program_uniform_1_i32_slice(
610 &self,
611 program: Self::Program,
612 location: Option<&Self::UniformLocation>,
613 v: &[i32],
614 ) {
615 let gl = &self.raw;
616 if let Some(loc) = location {
617 gl.ProgramUniform1iv(program.0.get(), loc.0 as i32, v.len() as i32, v.as_ptr());
618 }
619 }
620
621 unsafe fn program_uniform_2_i32_slice(
622 &self,
623 program: Self::Program,
624 location: Option<&Self::UniformLocation>,
625 v: &[i32],
626 ) {
627 let gl = &self.raw;
628 if let Some(loc) = location {
629 gl.ProgramUniform2iv(
630 program.0.get(),
631 loc.0 as i32,
632 v.len() as i32 / 2,
633 v.as_ptr(),
634 );
635 }
636 }
637
638 unsafe fn program_uniform_3_i32_slice(
639 &self,
640 program: Self::Program,
641 location: Option<&Self::UniformLocation>,
642 v: &[i32],
643 ) {
644 let gl = &self.raw;
645 if let Some(loc) = location {
646 gl.ProgramUniform3iv(
647 program.0.get(),
648 loc.0 as i32,
649 v.len() as i32 / 3,
650 v.as_ptr(),
651 );
652 }
653 }
654
655 unsafe fn program_uniform_4_i32_slice(
656 &self,
657 program: Self::Program,
658 location: Option<&Self::UniformLocation>,
659 v: &[i32],
660 ) {
661 let gl = &self.raw;
662 if let Some(loc) = location {
663 gl.ProgramUniform4iv(
664 program.0.get(),
665 loc.0 as i32,
666 v.len() as i32 / 4,
667 v.as_ptr(),
668 );
669 }
670 }
671
672 unsafe fn program_uniform_1_u32(
673 &self,
674 program: Self::Program,
675 location: Option<&Self::UniformLocation>,
676 x: u32,
677 ) {
678 let gl = &self.raw;
679 if let Some(loc) = location {
680 gl.ProgramUniform1ui(program.0.get(), loc.0 as i32, x);
681 }
682 }
683
684 unsafe fn program_uniform_2_u32(
685 &self,
686 program: Self::Program,
687 location: Option<&Self::UniformLocation>,
688 x: u32,
689 y: u32,
690 ) {
691 let gl = &self.raw;
692 if let Some(loc) = location {
693 gl.ProgramUniform2ui(program.0.get(), loc.0 as i32, x, y);
694 }
695 }
696
697 unsafe fn program_uniform_3_u32(
698 &self,
699 program: Self::Program,
700 location: Option<&Self::UniformLocation>,
701 x: u32,
702 y: u32,
703 z: u32,
704 ) {
705 let gl = &self.raw;
706 if let Some(loc) = location {
707 gl.ProgramUniform3ui(program.0.get(), loc.0 as i32, x, y, z);
708 }
709 }
710
711 unsafe fn program_uniform_4_u32(
712 &self,
713 program: Self::Program,
714 location: Option<&Self::UniformLocation>,
715 x: u32,
716 y: u32,
717 z: u32,
718 w: u32,
719 ) {
720 let gl = &self.raw;
721 if let Some(loc) = location {
722 gl.ProgramUniform4ui(program.0.get(), loc.0 as i32, x, y, z, w);
723 }
724 }
725
726 unsafe fn program_uniform_1_u32_slice(
727 &self,
728 program: Self::Program,
729 location: Option<&Self::UniformLocation>,
730 v: &[u32],
731 ) {
732 let gl = &self.raw;
733 if let Some(loc) = location {
734 gl.ProgramUniform1uiv(program.0.get(), loc.0 as i32, v.len() as i32, v.as_ptr());
735 }
736 }
737
738 unsafe fn program_uniform_2_u32_slice(
739 &self,
740 program: Self::Program,
741 location: Option<&Self::UniformLocation>,
742 v: &[u32],
743 ) {
744 let gl = &self.raw;
745 if let Some(loc) = location {
746 gl.ProgramUniform2uiv(
747 program.0.get(),
748 loc.0 as i32,
749 v.len() as i32 / 2,
750 v.as_ptr(),
751 );
752 }
753 }
754
755 unsafe fn program_uniform_3_u32_slice(
756 &self,
757 program: Self::Program,
758 location: Option<&Self::UniformLocation>,
759 v: &[u32],
760 ) {
761 let gl = &self.raw;
762 if let Some(loc) = location {
763 gl.ProgramUniform3uiv(
764 program.0.get(),
765 loc.0 as i32,
766 v.len() as i32 / 3,
767 v.as_ptr(),
768 );
769 }
770 }
771
772 unsafe fn program_uniform_4_u32_slice(
773 &self,
774 program: Self::Program,
775 location: Option<&Self::UniformLocation>,
776 v: &[u32],
777 ) {
778 let gl = &self.raw;
779 if let Some(loc) = location {
780 gl.ProgramUniform4uiv(
781 program.0.get(),
782 loc.0 as i32,
783 v.len() as i32 / 4,
784 v.as_ptr(),
785 );
786 }
787 }
788
789 unsafe fn program_uniform_1_f32(
790 &self,
791 program: Self::Program,
792 location: Option<&Self::UniformLocation>,
793 x: f32,
794 ) {
795 let gl = &self.raw;
796 if let Some(loc) = location {
797 gl.ProgramUniform1f(program.0.get(), loc.0 as i32, x);
798 }
799 }
800
801 unsafe fn program_uniform_2_f32(
802 &self,
803 program: Self::Program,
804 location: Option<&Self::UniformLocation>,
805 x: f32,
806 y: f32,
807 ) {
808 let gl = &self.raw;
809 if let Some(loc) = location {
810 gl.ProgramUniform2f(program.0.get(), loc.0 as i32, x, y);
811 }
812 }
813
814 unsafe fn program_uniform_3_f32(
815 &self,
816 program: Self::Program,
817 location: Option<&Self::UniformLocation>,
818 x: f32,
819 y: f32,
820 z: f32,
821 ) {
822 let gl = &self.raw;
823 if let Some(loc) = location {
824 gl.ProgramUniform3f(program.0.get(), loc.0 as i32, x, y, z);
825 }
826 }
827
828 unsafe fn program_uniform_4_f32(
829 &self,
830 program: Self::Program,
831 location: Option<&Self::UniformLocation>,
832 x: f32,
833 y: f32,
834 z: f32,
835 w: f32,
836 ) {
837 let gl = &self.raw;
838 if let Some(loc) = location {
839 gl.ProgramUniform4f(program.0.get(), loc.0 as i32, x, y, z, w);
840 }
841 }
842
843 unsafe fn program_uniform_1_f32_slice(
844 &self,
845 program: Self::Program,
846 location: Option<&Self::UniformLocation>,
847 v: &[f32],
848 ) {
849 let gl = &self.raw;
850 if let Some(loc) = location {
851 gl.ProgramUniform1fv(program.0.get(), loc.0 as i32, v.len() as i32, v.as_ptr());
852 }
853 }
854
855 unsafe fn program_uniform_2_f32_slice(
856 &self,
857 program: Self::Program,
858 location: Option<&Self::UniformLocation>,
859 v: &[f32],
860 ) {
861 let gl = &self.raw;
862 if let Some(loc) = location {
863 gl.ProgramUniform2fv(
864 program.0.get(),
865 loc.0 as i32,
866 v.len() as i32 / 2,
867 v.as_ptr(),
868 );
869 }
870 }
871
872 unsafe fn program_uniform_3_f32_slice(
873 &self,
874 program: Self::Program,
875 location: Option<&Self::UniformLocation>,
876 v: &[f32],
877 ) {
878 let gl = &self.raw;
879 if let Some(loc) = location {
880 gl.ProgramUniform3fv(
881 program.0.get(),
882 loc.0 as i32,
883 v.len() as i32 / 3,
884 v.as_ptr(),
885 );
886 }
887 }
888
889 unsafe fn program_uniform_4_f32_slice(
890 &self,
891 program: Self::Program,
892 location: Option<&Self::UniformLocation>,
893 v: &[f32],
894 ) {
895 let gl = &self.raw;
896 if let Some(loc) = location {
897 gl.ProgramUniform4fv(
898 program.0.get(),
899 loc.0 as i32,
900 v.len() as i32 / 4,
901 v.as_ptr(),
902 );
903 }
904 }
905
906 unsafe fn program_uniform_matrix_2_f32_slice(
907 &self,
908 program: Self::Program,
909 location: Option<&Self::UniformLocation>,
910 transpose: bool,
911 v: &[f32],
912 ) {
913 let gl = &self.raw;
914 if let Some(loc) = location {
915 gl.ProgramUniformMatrix2fv(
916 program.0.get(),
917 loc.0 as i32,
918 v.len() as i32 / 4,
919 transpose as u8,
920 v.as_ptr(),
921 );
922 }
923 }
924
925 unsafe fn program_uniform_matrix_2x3_f32_slice(
926 &self,
927 program: Self::Program,
928 location: Option<&Self::UniformLocation>,
929 transpose: bool,
930 v: &[f32],
931 ) {
932 let gl = &self.raw;
933 if let Some(loc) = location {
934 gl.ProgramUniformMatrix2x3fv(
935 program.0.get(),
936 loc.0 as i32,
937 v.len() as i32 / 6,
938 transpose as u8,
939 v.as_ptr(),
940 );
941 }
942 }
943
944 unsafe fn program_uniform_matrix_2x4_f32_slice(
945 &self,
946 program: Self::Program,
947 location: Option<&Self::UniformLocation>,
948 transpose: bool,
949 v: &[f32],
950 ) {
951 let gl = &self.raw;
952 if let Some(loc) = location {
953 gl.ProgramUniformMatrix2x4fv(
954 program.0.get(),
955 loc.0 as i32,
956 v.len() as i32 / 8,
957 transpose as u8,
958 v.as_ptr(),
959 );
960 }
961 }
962
963 unsafe fn program_uniform_matrix_3x2_f32_slice(
964 &self,
965 program: Self::Program,
966 location: Option<&Self::UniformLocation>,
967 transpose: bool,
968 v: &[f32],
969 ) {
970 let gl = &self.raw;
971 if let Some(loc) = location {
972 gl.ProgramUniformMatrix3x2fv(
973 program.0.get(),
974 loc.0 as i32,
975 v.len() as i32 / 6,
976 transpose as u8,
977 v.as_ptr(),
978 );
979 }
980 }
981
982 unsafe fn program_uniform_matrix_3_f32_slice(
983 &self,
984 program: Self::Program,
985 location: Option<&Self::UniformLocation>,
986 transpose: bool,
987 v: &[f32],
988 ) {
989 let gl = &self.raw;
990 if let Some(loc) = location {
991 gl.ProgramUniformMatrix3fv(
992 program.0.get(),
993 loc.0 as i32,
994 v.len() as i32 / 9,
995 transpose as u8,
996 v.as_ptr(),
997 );
998 }
999 }
1000
1001 unsafe fn program_uniform_matrix_3x4_f32_slice(
1002 &self,
1003 program: Self::Program,
1004 location: Option<&Self::UniformLocation>,
1005 transpose: bool,
1006 v: &[f32],
1007 ) {
1008 let gl = &self.raw;
1009 if let Some(loc) = location {
1010 gl.ProgramUniformMatrix3x4fv(
1011 program.0.get(),
1012 loc.0 as i32,
1013 v.len() as i32 / 12,
1014 transpose as u8,
1015 v.as_ptr(),
1016 );
1017 }
1018 }
1019
1020 unsafe fn program_uniform_matrix_4x2_f32_slice(
1021 &self,
1022 program: Self::Program,
1023 location: Option<&Self::UniformLocation>,
1024 transpose: bool,
1025 v: &[f32],
1026 ) {
1027 let gl = &self.raw;
1028 if let Some(loc) = location {
1029 gl.ProgramUniformMatrix4x2fv(
1030 program.0.get(),
1031 loc.0 as i32,
1032 v.len() as i32 / 8,
1033 transpose as u8,
1034 v.as_ptr(),
1035 );
1036 }
1037 }
1038
1039 unsafe fn program_uniform_matrix_4x3_f32_slice(
1040 &self,
1041 program: Self::Program,
1042 location: Option<&Self::UniformLocation>,
1043 transpose: bool,
1044 v: &[f32],
1045 ) {
1046 let gl = &self.raw;
1047 if let Some(loc) = location {
1048 gl.ProgramUniformMatrix4x3fv(
1049 program.0.get(),
1050 loc.0 as i32,
1051 v.len() as i32 / 12,
1052 transpose as u8,
1053 v.as_ptr(),
1054 );
1055 }
1056 }
1057
1058 unsafe fn program_uniform_matrix_4_f32_slice(
1059 &self,
1060 program: Self::Program,
1061 location: Option<&Self::UniformLocation>,
1062 transpose: bool,
1063 v: &[f32],
1064 ) {
1065 let gl = &self.raw;
1066 if let Some(loc) = location {
1067 gl.ProgramUniformMatrix4fv(
1068 program.0.get(),
1069 loc.0 as i32,
1070 v.len() as i32 / 16,
1071 transpose as u8,
1072 v.as_ptr(),
1073 );
1074 }
1075 }
1076
1077 unsafe fn program_binary_retrievable_hint(&self, program: Self::Program, value: bool) {
1078 let gl = &self.raw;
1079 gl.ProgramParameteri(
1080 program.0.get(),
1081 crate::PROGRAM_BINARY_RETRIEVABLE_HINT,
1082 value as i32,
1083 )
1084 }
1085
1086 unsafe fn get_program_binary(&self, program: Self::Program) -> Option<ProgramBinary> {
1087 let gl = &self.raw;
1088
1089 let mut len = 0;
1091 gl.GetProgramiv(program.0.get(), crate::PROGRAM_BINARY_LENGTH, &mut len);
1092
1093 let mut format = 0;
1094 let mut buffer = vec![0u8; len as usize];
1095
1096 gl.GetProgramBinary(
1097 program.0.get(),
1098 len,
1099 ptr::null_mut(),
1100 &mut format,
1101 buffer.as_mut_ptr() as *mut core::ffi::c_void,
1102 );
1103
1104 if gl.GetError() == crate::NO_ERROR {
1105 Some(ProgramBinary { buffer, format })
1106 } else {
1107 None
1108 }
1109 }
1110
1111 unsafe fn program_binary(&self, program: Self::Program, binary: &ProgramBinary) {
1112 let gl = &self.raw;
1113
1114 gl.ProgramBinary(
1115 program.0.get(),
1116 binary.format,
1117 binary.buffer.as_ptr() as *const core::ffi::c_void,
1118 binary.buffer.len() as native_gl::types::GLsizei,
1119 )
1120 }
1121
1122 unsafe fn get_active_uniforms(&self, program: Self::Program) -> u32 {
1123 let gl = &self.raw;
1124 let mut count = 0;
1125 gl.GetProgramiv(program.0.get(), ACTIVE_UNIFORMS, &mut count);
1126 count as u32
1127 }
1128
1129 unsafe fn get_active_uniforms_parameter(
1130 &self,
1131 program: Self::Program,
1132 uniforms: &[u32],
1133 pname: u32,
1134 ) -> Vec<i32> {
1135 let gl = &self.raw;
1136 let mut results = vec![0; uniforms.len()];
1137 gl.GetActiveUniformsiv(
1138 program.0.get(),
1139 uniforms.len() as _,
1140 uniforms.as_ptr(),
1141 pname,
1142 results.as_mut_ptr(),
1143 );
1144 results
1145 }
1146
1147 unsafe fn get_active_uniform(
1148 &self,
1149 program: Self::Program,
1150 index: u32,
1151 ) -> Option<ActiveUniform> {
1152 let gl = &self.raw;
1153 let mut uniform_max_size = 0;
1154 gl.GetProgramiv(
1155 program.0.get(),
1156 ACTIVE_UNIFORM_MAX_LENGTH,
1157 &mut uniform_max_size,
1158 );
1159
1160 let mut name = String::with_capacity(uniform_max_size as usize);
1161 name.extend(std::iter::repeat('\0').take(uniform_max_size as usize));
1162 let mut length = 0;
1163 let mut size = 0;
1164 let mut utype = 0;
1165 gl.GetActiveUniform(
1166 program.0.get(),
1167 index,
1168 uniform_max_size,
1169 &mut length,
1170 &mut size,
1171 &mut utype,
1172 name.as_ptr() as *mut native_gl::GLchar,
1173 );
1174 name.truncate(length as usize);
1175
1176 Some(ActiveUniform { size, utype, name })
1177 }
1178
1179 unsafe fn use_program(&self, program: Option<Self::Program>) {
1180 let gl = &self.raw;
1181 gl.UseProgram(program.map(|p| p.0.get()).unwrap_or(0));
1182 }
1183
1184 unsafe fn create_buffer(&self) -> Result<Self::Buffer, String> {
1185 let gl = &self.raw;
1186 let mut buffer = 0;
1187 gl.GenBuffers(1, &mut buffer);
1188 NonZeroU32::new(buffer)
1189 .map(NativeBuffer)
1190 .ok_or_else(|| String::from("Unable to create Buffer object"))
1191 }
1192
1193 unsafe fn create_named_buffer(&self) -> Result<Self::Buffer, String> {
1194 let gl = &self.raw;
1195 let mut buffer = 0;
1196 gl.CreateBuffers(1, &mut buffer);
1197 NonZeroU32::new(buffer)
1198 .map(NativeBuffer)
1199 .ok_or_else(|| String::from("Unable to create Buffer object"))
1200 }
1201
1202 unsafe fn is_buffer(&self, buffer: Self::Buffer) -> bool {
1203 let gl = &self.raw;
1204 gl.IsBuffer(buffer.0.get()) != 0
1205 }
1206
1207 unsafe fn bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>) {
1208 let gl = &self.raw;
1209 gl.BindBuffer(target, buffer.map(|b| b.0.get()).unwrap_or(0));
1210 }
1211
1212 unsafe fn bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>) {
1213 let gl = &self.raw;
1214 gl.BindBufferBase(target, index, buffer.map(|b| b.0.get()).unwrap_or(0));
1215 }
1216
1217 unsafe fn bind_buffer_range(
1218 &self,
1219 target: u32,
1220 index: u32,
1221 buffer: Option<Self::Buffer>,
1222 offset: i32,
1223 size: i32,
1224 ) {
1225 let gl = &self.raw;
1226 gl.BindBufferRange(
1227 target,
1228 index,
1229 buffer.map(|b| b.0.get()).unwrap_or(0),
1230 offset as isize,
1231 size as isize,
1232 );
1233 }
1234
1235 unsafe fn bind_vertex_buffer(
1236 &self,
1237 binding_index: u32,
1238 buffer: Option<Buffer>,
1239 offset: i32,
1240 stride: i32,
1241 ) {
1242 let gl = &self.raw;
1243 gl.BindVertexBuffer(
1244 binding_index,
1245 buffer.map(|b| b.0.get()).unwrap_or(0),
1246 offset as isize,
1247 stride,
1248 );
1249 }
1250
1251 unsafe fn bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>) {
1252 let gl = &self.raw;
1253 gl.BindFramebuffer(target, framebuffer.map(|fb| fb.0.get()).unwrap_or(0));
1254 }
1255
1256 unsafe fn bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>) {
1257 let gl = &self.raw;
1258 gl.BindRenderbuffer(target, renderbuffer.map(|rb| rb.0.get()).unwrap_or(0));
1259 }
1260
1261 unsafe fn blit_framebuffer(
1262 &self,
1263 src_x0: i32,
1264 src_y0: i32,
1265 src_x1: i32,
1266 src_y1: i32,
1267 dst_x0: i32,
1268 dst_y0: i32,
1269 dst_x1: i32,
1270 dst_y1: i32,
1271 mask: u32,
1272 filter: u32,
1273 ) {
1274 let gl = &self.raw;
1275 gl.BlitFramebuffer(
1276 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
1277 );
1278 }
1279
1280 unsafe fn blit_named_framebuffer(
1281 &self,
1282 read_buffer: Option<Self::Framebuffer>,
1283 draw_buffer: Option<Self::Framebuffer>,
1284 src_x0: i32,
1285 src_y0: i32,
1286 src_x1: i32,
1287 src_y1: i32,
1288 dst_x0: i32,
1289 dst_y0: i32,
1290 dst_x1: i32,
1291 dst_y1: i32,
1292 mask: u32,
1293 filter: u32,
1294 ) {
1295 let gl = &self.raw;
1296 gl.BlitNamedFramebuffer(
1297 read_buffer.map(|f| f.0.get()).unwrap_or(0),
1298 draw_buffer.map(|f| f.0.get()).unwrap_or(0),
1299 src_x0,
1300 src_y0,
1301 src_x1,
1302 src_y1,
1303 dst_x0,
1304 dst_y0,
1305 dst_x1,
1306 dst_y1,
1307 mask,
1308 filter,
1309 );
1310 }
1311
1312 unsafe fn create_vertex_array(&self) -> Result<Self::VertexArray, String> {
1313 let gl = &self.raw;
1314 let mut vertex_array = 0;
1315 if gl.GenVertexArrays_is_loaded() {
1316 gl.GenVertexArrays(1, &mut vertex_array);
1317 } else {
1318 #[cfg(not(target_vendor = "apple"))]
1319 gl.GenVertexArraysOES(1, &mut vertex_array);
1320 #[cfg(target_vendor = "apple")]
1321 gl.GenVertexArraysAPPLE(1, &mut vertex_array);
1322 }
1323 NonZeroU32::new(vertex_array)
1324 .map(NativeVertexArray)
1325 .ok_or_else(|| String::from("Unable to create VertexArray object"))
1326 }
1327
1328 unsafe fn create_named_vertex_array(&self) -> Result<Self::VertexArray, String> {
1329 let gl = &self.raw;
1330 let mut vertex_array = 0;
1331 gl.CreateVertexArrays(1, &mut vertex_array);
1332 NonZeroU32::new(vertex_array)
1333 .map(NativeVertexArray)
1334 .ok_or_else(|| String::from("Unable to create VertexArray object"))
1335 }
1336
1337 unsafe fn delete_vertex_array(&self, vertex_array: Self::VertexArray) {
1338 let gl = &self.raw;
1339 if gl.DeleteVertexArrays_is_loaded() {
1340 gl.DeleteVertexArrays(1, &vertex_array.0.get());
1341 } else {
1342 #[cfg(not(target_vendor = "apple"))]
1343 gl.DeleteVertexArraysOES(1, &vertex_array.0.get());
1344 #[cfg(target_vendor = "apple")]
1345 gl.DeleteVertexArraysAPPLE(1, &vertex_array.0.get());
1346 }
1347 }
1348
1349 unsafe fn bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>) {
1350 let gl = &self.raw;
1351 if gl.BindVertexArray_is_loaded() {
1352 gl.BindVertexArray(vertex_array.map(|va| va.0.get()).unwrap_or(0));
1353 } else {
1354 #[cfg(not(target_vendor = "apple"))]
1355 gl.BindVertexArrayOES(vertex_array.map(|va| va.0.get()).unwrap_or(0));
1356 #[cfg(target_vendor = "apple")]
1357 gl.BindVertexArrayAPPLE(vertex_array.map(|va| va.0.get()).unwrap_or(0));
1358 }
1359 }
1360
1361 unsafe fn clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
1362 let gl = &self.raw;
1363 gl.ClearColor(red, green, blue, alpha);
1364 }
1365
1366 unsafe fn supports_f64_precision(&self) -> bool {
1367 !self.version.is_embedded
1368 }
1369
1370 unsafe fn clear_depth_f64(&self, depth: f64) {
1371 let gl = &self.raw;
1372 gl.ClearDepth(depth);
1373 }
1374
1375 unsafe fn clear_depth_f32(&self, depth: f32) {
1376 let gl = &self.raw;
1377 gl.ClearDepthf(depth);
1378 }
1379
1380 unsafe fn clear_depth(&self, depth: f64) {
1381 if self.supports_f64_precision() {
1382 self.clear_depth_f64(depth);
1383 } else {
1384 self.clear_depth_f32(depth as f32);
1385 }
1386 }
1387
1388 unsafe fn clear_stencil(&self, stencil: i32) {
1389 let gl = &self.raw;
1390 gl.ClearStencil(stencil);
1391 }
1392
1393 unsafe fn clear(&self, mask: u32) {
1394 let gl = &self.raw;
1395 gl.Clear(mask);
1396 }
1397
1398 unsafe fn patch_parameter_i32(&self, parameter: u32, value: i32) {
1399 let gl = &self.raw;
1400 gl.PatchParameteri(parameter, value);
1401 }
1402
1403 unsafe fn pixel_store_i32(&self, parameter: u32, value: i32) {
1404 let gl = &self.raw;
1405 gl.PixelStorei(parameter, value);
1406 }
1407
1408 unsafe fn pixel_store_bool(&self, parameter: u32, value: bool) {
1409 let gl = &self.raw;
1410 gl.PixelStorei(parameter, value as i32);
1411 }
1412
1413 unsafe fn get_frag_data_location(&self, program: Self::Program, name: &str) -> i32 {
1414 let gl = &self.raw;
1415 let name = CString::new(name).unwrap();
1416 gl.GetFragDataLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar)
1417 }
1418
1419 unsafe fn bind_frag_data_location(
1420 &self,
1421 program: Self::Program,
1422 color_number: u32,
1423 name: &str,
1424 ) {
1425 let gl = &self.raw;
1426 let name = CString::new(name).unwrap();
1427 gl.BindFragDataLocation(
1428 program.0.get(),
1429 color_number,
1430 name.as_ptr() as *const native_gl::GLchar,
1431 );
1432 }
1433
1434 unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32) {
1435 let gl = &self.raw;
1436 gl.BufferData(target, size as isize, std::ptr::null(), usage);
1437 }
1438
1439 unsafe fn named_buffer_data_size(&self, buffer: Self::Buffer, size: i32, usage: u32) {
1440 let gl = &self.raw;
1441 gl.NamedBufferData(buffer.0.get(), size as isize, std::ptr::null(), usage);
1442 }
1443
1444 unsafe fn buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32) {
1445 let gl = &self.raw;
1446 gl.BufferData(
1447 target,
1448 data.len() as isize,
1449 data.as_ptr() as *const std::ffi::c_void,
1450 usage,
1451 );
1452 }
1453
1454 unsafe fn named_buffer_data_u8_slice(&self, buffer: Self::Buffer, data: &[u8], usage: u32) {
1455 let gl = &self.raw;
1456 gl.NamedBufferData(
1457 buffer.0.get(),
1458 data.len() as isize,
1459 data.as_ptr() as *const std::ffi::c_void,
1460 usage,
1461 );
1462 }
1463
1464 unsafe fn buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8]) {
1465 let gl = &self.raw;
1466 gl.BufferSubData(
1467 target,
1468 offset as isize,
1469 src_data.len() as isize,
1470 src_data.as_ptr() as *const std::ffi::c_void,
1471 );
1472 }
1473
1474 unsafe fn named_buffer_sub_data_u8_slice(
1475 &self,
1476 buffer: Self::Buffer,
1477 offset: i32,
1478 src_data: &[u8],
1479 ) {
1480 let gl = &self.raw;
1481 gl.NamedBufferSubData(
1482 buffer.0.get(),
1483 offset as isize,
1484 src_data.len() as isize,
1485 src_data.as_ptr() as *const std::ffi::c_void,
1486 );
1487 }
1488
1489 unsafe fn get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8]) {
1490 let gl = &self.raw;
1491 gl.GetBufferSubData(
1492 target,
1493 offset as isize,
1494 dst_data.len() as isize,
1495 dst_data.as_mut_ptr() as *mut std::ffi::c_void,
1496 );
1497 }
1498
1499 unsafe fn tex_buffer(&self, target: u32, internal_format: u32, buffer: Option<Self::Buffer>) {
1500 let gl = &self.raw;
1501 gl.TexBuffer(
1502 target,
1503 internal_format,
1504 buffer.map(|b| b.0.get()).unwrap_or(0),
1505 );
1506 }
1507
1508 unsafe fn buffer_storage(&self, target: u32, size: i32, data: Option<&[u8]>, flags: u32) {
1509 let gl = &self.raw;
1510 let size = size as isize;
1511 let data = data.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void;
1512 if gl.BufferStorage_is_loaded() {
1513 gl.BufferStorage(target, size, data, flags);
1514 } else {
1515 gl.BufferStorageEXT(target, size, data, flags);
1516 }
1517 }
1518 unsafe fn named_buffer_storage(
1519 &self,
1520 buffer: Self::Buffer,
1521 size: i32,
1522 data: Option<&[u8]>,
1523 flags: u32,
1524 ) {
1525 let gl = &self.raw;
1526 let data = data.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void;
1527 gl.NamedBufferStorage(buffer.0.get(), size as isize, data, flags);
1528 }
1529
1530 unsafe fn check_framebuffer_status(&self, target: u32) -> u32 {
1531 let gl = &self.raw;
1532 gl.CheckFramebufferStatus(target)
1533 }
1534
1535 unsafe fn check_named_framebuffer_status(
1536 &self,
1537 framebuffer: Option<Self::Framebuffer>,
1538 target: u32,
1539 ) -> u32 {
1540 let gl = &self.raw;
1541 gl.CheckNamedFramebufferStatus(framebuffer.map(|f| f.0.get()).unwrap_or(0), target)
1542 }
1543
1544 unsafe fn clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &[i32]) {
1545 let gl = &self.raw;
1546 gl.ClearBufferiv(target, draw_buffer as i32, values.as_ptr());
1547 }
1548
1549 unsafe fn clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &[u32]) {
1550 let gl = &self.raw;
1551 gl.ClearBufferuiv(target, draw_buffer as i32, values.as_ptr());
1552 }
1553
1554 unsafe fn clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &[f32]) {
1555 let gl = &self.raw;
1556 gl.ClearBufferfv(target, draw_buffer as i32, values.as_ptr());
1557 }
1558
1559 unsafe fn clear_buffer_depth_stencil(
1560 &self,
1561 target: u32,
1562 draw_buffer: u32,
1563 depth: f32,
1564 stencil: i32,
1565 ) {
1566 let gl = &self.raw;
1567 gl.ClearBufferfi(target, draw_buffer as i32, depth, stencil);
1568 }
1569
1570 unsafe fn clear_named_framebuffer_i32_slice(
1571 &self,
1572 framebuffer: Option<Self::Framebuffer>,
1573 target: u32,
1574 draw_buffer: u32,
1575 values: &[i32],
1576 ) {
1577 let gl = &self.raw;
1578 gl.ClearNamedFramebufferiv(
1579 framebuffer.map(|f| f.0.get()).unwrap_or(0),
1580 target,
1581 draw_buffer as i32,
1582 values.as_ptr(),
1583 );
1584 }
1585
1586 unsafe fn clear_named_framebuffer_u32_slice(
1587 &self,
1588 framebuffer: Option<Self::Framebuffer>,
1589 target: u32,
1590 draw_buffer: u32,
1591 values: &[u32],
1592 ) {
1593 let gl = &self.raw;
1594 gl.ClearNamedFramebufferuiv(
1595 framebuffer.map(|f| f.0.get()).unwrap_or(0),
1596 target,
1597 draw_buffer as i32,
1598 values.as_ptr(),
1599 );
1600 }
1601
1602 unsafe fn clear_named_framebuffer_f32_slice(
1603 &self,
1604 framebuffer: Option<Self::Framebuffer>,
1605 target: u32,
1606 draw_buffer: u32,
1607 values: &[f32],
1608 ) {
1609 let gl = &self.raw;
1610 gl.ClearNamedFramebufferfv(
1611 framebuffer.map(|f| f.0.get()).unwrap_or(0),
1612 target,
1613 draw_buffer as i32,
1614 values.as_ptr(),
1615 );
1616 }
1617
1618 unsafe fn clear_named_framebuffer_depth_stencil(
1619 &self,
1620 framebuffer: Option<Self::Framebuffer>,
1621 target: u32,
1622 draw_buffer: u32,
1623 depth: f32,
1624 stencil: i32,
1625 ) {
1626 let gl = &self.raw;
1627 gl.ClearNamedFramebufferfi(
1628 framebuffer.map(|f| f.0.get()).unwrap_or(0),
1629 target,
1630 draw_buffer as i32,
1631 depth,
1632 stencil,
1633 );
1634 }
1635
1636 unsafe fn client_wait_sync(&self, fence: Self::Fence, flags: u32, timeout: i32) -> u32 {
1637 let gl = &self.raw;
1638 gl.ClientWaitSync(fence.0, flags, timeout as u64)
1639 }
1640
1641 unsafe fn get_sync_parameter_i32(&self, fence: Self::Fence, parameter: u32) -> i32 {
1642 let gl = &self.raw;
1643 let mut v = 0;
1644 gl.GetSynciv(fence.0, parameter, 1, ptr::null_mut(), &mut v);
1645 v
1646 }
1647
1648 unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64) {
1649 let gl = &self.raw;
1650 gl.WaitSync(fence.0, flags, timeout)
1651 }
1652
1653 unsafe fn copy_buffer_sub_data(
1654 &self,
1655 src_target: u32,
1656 dst_target: u32,
1657 src_offset: i32,
1658 dst_offset: i32,
1659 size: i32,
1660 ) {
1661 let gl = &self.raw;
1662 gl.CopyBufferSubData(
1663 src_target,
1664 dst_target,
1665 src_offset as isize,
1666 dst_offset as isize,
1667 size as isize,
1668 );
1669 }
1670
1671 unsafe fn copy_image_sub_data(
1672 &self,
1673 src_name: Self::Texture,
1674 src_target: u32,
1675 src_level: i32,
1676 src_x: i32,
1677 src_y: i32,
1678 src_z: i32,
1679 dst_name: Self::Texture,
1680 dst_target: u32,
1681 dst_level: i32,
1682 dst_x: i32,
1683 dst_y: i32,
1684 dst_z: i32,
1685 src_width: i32,
1686 src_height: i32,
1687 src_depth: i32,
1688 ) {
1689 let gl = &self.raw;
1690 gl.CopyImageSubData(
1691 src_name.0.get(),
1692 src_target,
1693 src_level,
1694 src_x,
1695 src_y,
1696 src_z,
1697 dst_name.0.get(),
1698 dst_target,
1699 dst_level,
1700 dst_x,
1701 dst_y,
1702 dst_z,
1703 src_width,
1704 src_height,
1705 src_depth,
1706 );
1707 }
1708
1709 unsafe fn copy_tex_image_2d(
1710 &self,
1711 target: u32,
1712 level: i32,
1713 internal_format: u32,
1714 x: i32,
1715 y: i32,
1716 width: i32,
1717 height: i32,
1718 border: i32,
1719 ) {
1720 let gl = &self.raw;
1721 gl.CopyTexImage2D(target, level, internal_format, x, y, width, height, border);
1722 }
1723
1724 unsafe fn copy_tex_sub_image_2d(
1725 &self,
1726 target: u32,
1727 level: i32,
1728 x_offset: i32,
1729 y_offset: i32,
1730 x: i32,
1731 y: i32,
1732 width: i32,
1733 height: i32,
1734 ) {
1735 let gl = &self.raw;
1736 gl.CopyTexSubImage2D(target, level, x_offset, y_offset, x, y, width, height);
1737 }
1738
1739 unsafe fn copy_tex_sub_image_3d(
1740 &self,
1741 target: u32,
1742 level: i32,
1743 x_offset: i32,
1744 y_offset: i32,
1745 z_offset: i32,
1746 x: i32,
1747 y: i32,
1748 width: i32,
1749 height: i32,
1750 ) {
1751 let gl = &self.raw;
1752 gl.CopyTexSubImage3D(
1753 target, level, x_offset, y_offset, z_offset, x, y, width, height,
1754 );
1755 }
1756
1757 unsafe fn delete_buffer(&self, buffer: Self::Buffer) {
1758 let gl = &self.raw;
1759 gl.DeleteBuffers(1, &buffer.0.get());
1760 }
1761
1762 unsafe fn delete_framebuffer(&self, framebuffer: Self::Framebuffer) {
1763 let gl = &self.raw;
1764 gl.DeleteFramebuffers(1, &framebuffer.0.get());
1765 }
1766
1767 unsafe fn delete_query(&self, query: Self::Query) {
1768 let gl = &self.raw;
1769 if gl.DeleteQueries_is_loaded() {
1770 gl.DeleteQueries(1, &query.0.get());
1771 } else {
1772 gl.DeleteQueriesEXT(1, &query.0.get());
1773 }
1774 }
1775
1776 unsafe fn delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer) {
1777 let gl = &self.raw;
1778 gl.DeleteRenderbuffers(1, &renderbuffer.0.get());
1779 }
1780
1781 unsafe fn delete_sampler(&self, sampler: Self::Sampler) {
1782 let gl = &self.raw;
1783 gl.DeleteSamplers(1, &sampler.0.get());
1784 }
1785
1786 unsafe fn delete_sync(&self, fence: Self::Fence) {
1787 let gl = &self.raw;
1788 gl.DeleteSync(fence.0);
1789 }
1790
1791 unsafe fn delete_texture(&self, texture: Self::Texture) {
1792 let gl = &self.raw;
1793 gl.DeleteTextures(1, &texture.0.get());
1794 }
1795
1796 unsafe fn disable(&self, parameter: u32) {
1797 let gl = &self.raw;
1798 gl.Disable(parameter);
1799 }
1800
1801 unsafe fn disable_draw_buffer(&self, parameter: u32, draw_buffer: u32) {
1802 let gl = &self.raw;
1803 gl.Disablei(parameter, draw_buffer);
1804 }
1805
1806 unsafe fn disable_vertex_attrib_array(&self, index: u32) {
1807 let gl = &self.raw;
1808 gl.DisableVertexAttribArray(index);
1809 }
1810
1811 unsafe fn dispatch_compute(&self, groups_x: u32, groups_y: u32, groups_z: u32) {
1812 let gl = &self.raw;
1813 gl.DispatchCompute(groups_x, groups_y, groups_z);
1814 }
1815
1816 unsafe fn dispatch_compute_indirect(&self, offset: i32) {
1817 let gl = &self.raw;
1818 gl.DispatchComputeIndirect(offset as isize);
1819 }
1820
1821 unsafe fn draw_arrays(&self, mode: u32, first: i32, count: i32) {
1822 let gl = &self.raw;
1823 gl.DrawArrays(mode as u32, first, count);
1824 }
1825
1826 unsafe fn draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32) {
1827 let gl = &self.raw;
1828 gl.DrawArraysInstanced(mode as u32, first, count, instance_count);
1829 }
1830
1831 unsafe fn draw_arrays_instanced_base_instance(
1832 &self,
1833 mode: u32,
1834 first: i32,
1835 count: i32,
1836 instance_count: i32,
1837 base_instance: u32,
1838 ) {
1839 let gl = &self.raw;
1840 gl.DrawArraysInstancedBaseInstance(
1841 mode as u32,
1842 first,
1843 count,
1844 instance_count,
1845 base_instance,
1846 );
1847 }
1848
1849 unsafe fn draw_arrays_indirect_offset(&self, mode: u32, offset: i32) {
1850 let gl = &self.raw;
1851 gl.DrawArraysIndirect(mode, offset as *const std::ffi::c_void);
1852 }
1853
1854 unsafe fn draw_buffer(&self, draw_buffer: u32) {
1855 let gl = &self.raw;
1856 gl.DrawBuffer(draw_buffer);
1857 }
1858
1859 unsafe fn named_framebuffer_draw_buffer(
1860 &self,
1861 framebuffer: Option<Self::Framebuffer>,
1862 draw_buffer: u32,
1863 ) {
1864 let gl = &self.raw;
1865 gl.NamedFramebufferDrawBuffer(framebuffer.map(|f| f.0.get()).unwrap_or(0), draw_buffer);
1866 }
1867
1868 unsafe fn draw_buffers(&self, buffers: &[u32]) {
1869 let gl = &self.raw;
1870 gl.DrawBuffers(buffers.len() as i32, buffers.as_ptr());
1871 }
1872
1873 unsafe fn named_framebuffer_draw_buffers(
1874 &self,
1875 framebuffer: Option<Self::Framebuffer>,
1876 buffers: &[u32],
1877 ) {
1878 let gl = &self.raw;
1879 gl.NamedFramebufferDrawBuffers(
1880 framebuffer.map(|f| f.0.get()).unwrap_or(0),
1881 buffers.len() as i32,
1882 buffers.as_ptr(),
1883 );
1884 }
1885
1886 unsafe fn draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32) {
1887 let gl = &self.raw;
1888 gl.DrawElements(
1889 mode as u32,
1890 count,
1891 element_type as u32,
1892 offset as *const std::ffi::c_void,
1893 );
1894 }
1895
1896 unsafe fn draw_elements_base_vertex(
1897 &self,
1898 mode: u32,
1899 count: i32,
1900 element_type: u32,
1901 offset: i32,
1902 base_vertex: i32,
1903 ) {
1904 let gl = &self.raw;
1905 gl.DrawElementsBaseVertex(
1906 mode as u32,
1907 count,
1908 element_type as u32,
1909 offset as *const std::ffi::c_void,
1910 base_vertex,
1911 );
1912 }
1913
1914 unsafe fn draw_elements_instanced(
1915 &self,
1916 mode: u32,
1917 count: i32,
1918 element_type: u32,
1919 offset: i32,
1920 instance_count: i32,
1921 ) {
1922 let gl = &self.raw;
1923 gl.DrawElementsInstanced(
1924 mode as u32,
1925 count,
1926 element_type as u32,
1927 offset as *const std::ffi::c_void,
1928 instance_count,
1929 );
1930 }
1931
1932 unsafe fn draw_elements_instanced_base_vertex(
1933 &self,
1934 mode: u32,
1935 count: i32,
1936 element_type: u32,
1937 offset: i32,
1938 instance_count: i32,
1939 base_vertex: i32,
1940 ) {
1941 let gl = &self.raw;
1942 gl.DrawElementsInstancedBaseVertex(
1943 mode as u32,
1944 count,
1945 element_type as u32,
1946 offset as *const std::ffi::c_void,
1947 instance_count,
1948 base_vertex,
1949 );
1950 }
1951
1952 unsafe fn draw_elements_instanced_base_vertex_base_instance(
1953 &self,
1954 mode: u32,
1955 count: i32,
1956 element_type: u32,
1957 offset: i32,
1958 instance_count: i32,
1959 base_vertex: i32,
1960 base_instance: u32,
1961 ) {
1962 let gl = &self.raw;
1963 gl.DrawElementsInstancedBaseVertexBaseInstance(
1964 mode as u32,
1965 count,
1966 element_type as u32,
1967 offset as *const std::ffi::c_void,
1968 instance_count,
1969 base_vertex,
1970 base_instance,
1971 );
1972 }
1973
1974 unsafe fn draw_elements_indirect_offset(&self, mode: u32, element_type: u32, offset: i32) {
1975 let gl = &self.raw;
1976 gl.DrawElementsIndirect(mode, element_type, offset as *const std::ffi::c_void);
1977 }
1978
1979 unsafe fn enable(&self, parameter: u32) {
1980 let gl = &self.raw;
1981 gl.Enable(parameter);
1982 }
1983
1984 unsafe fn is_enabled(&self, parameter: u32) -> bool {
1985 let gl = &self.raw;
1986 gl.IsEnabled(parameter) != 0
1987 }
1988
1989 unsafe fn enable_draw_buffer(&self, parameter: u32, draw_buffer: u32) {
1990 let gl = &self.raw;
1991 gl.Enablei(parameter, draw_buffer);
1992 }
1993
1994 unsafe fn enable_vertex_array_attrib(&self, vao: Self::VertexArray, index: u32) {
1995 let gl = &self.raw;
1996 gl.EnableVertexArrayAttrib(vao.0.get(), index);
1997 }
1998
1999 unsafe fn enable_vertex_attrib_array(&self, index: u32) {
2000 let gl = &self.raw;
2001 gl.EnableVertexAttribArray(index);
2002 }
2003
2004 unsafe fn flush(&self) {
2005 let gl = &self.raw;
2006 gl.Flush();
2007 }
2008
2009 unsafe fn framebuffer_renderbuffer(
2010 &self,
2011 target: u32,
2012 attachment: u32,
2013 renderbuffer_target: u32,
2014 renderbuffer: Option<Self::Renderbuffer>,
2015 ) {
2016 let gl = &self.raw;
2017 gl.FramebufferRenderbuffer(
2018 target,
2019 attachment,
2020 renderbuffer_target,
2021 renderbuffer.map(|rb| rb.0.get()).unwrap_or(0),
2022 );
2023 }
2024
2025 unsafe fn framebuffer_texture(
2026 &self,
2027 target: u32,
2028 attachment: u32,
2029 texture: Option<Self::Texture>,
2030 level: i32,
2031 ) {
2032 let gl = &self.raw;
2033 gl.FramebufferTexture(
2034 target,
2035 attachment,
2036 texture.map(|t| t.0.get()).unwrap_or(0),
2037 level,
2038 );
2039 }
2040
2041 unsafe fn framebuffer_texture_2d(
2042 &self,
2043 target: u32,
2044 attachment: u32,
2045 texture_target: u32,
2046 texture: Option<Self::Texture>,
2047 level: i32,
2048 ) {
2049 let gl = &self.raw;
2050 gl.FramebufferTexture2D(
2051 target,
2052 attachment,
2053 texture_target,
2054 texture.map(|t| t.0.get()).unwrap_or(0),
2055 level,
2056 );
2057 }
2058
2059 unsafe fn framebuffer_texture_2d_multisample(
2060 &self,
2061 target: u32,
2062 attachment: u32,
2063 texture_target: u32,
2064 texture: Option<Self::Texture>,
2065 level: i32,
2066 samples: i32,
2067 ) {
2068 let gl = &self.raw;
2069 gl.FramebufferTexture2DMultisampleEXT(
2070 target,
2071 attachment,
2072 texture_target,
2073 texture.map(|t| t.0.get()).unwrap_or(0),
2074 level,
2075 samples,
2076 );
2077 }
2078
2079 unsafe fn framebuffer_texture_3d(
2080 &self,
2081 target: u32,
2082 attachment: u32,
2083 texture_target: u32,
2084 texture: Option<Self::Texture>,
2085 level: i32,
2086 layer: i32,
2087 ) {
2088 let gl = &self.raw;
2089 gl.FramebufferTexture3D(
2090 target,
2091 attachment,
2092 texture_target,
2093 texture.map(|t| t.0.get()).unwrap_or(0),
2094 level,
2095 layer,
2096 );
2097 }
2098
2099 unsafe fn framebuffer_texture_layer(
2100 &self,
2101 target: u32,
2102 attachment: u32,
2103 texture: Option<Self::Texture>,
2104 level: i32,
2105 layer: i32,
2106 ) {
2107 let gl = &self.raw;
2108 gl.FramebufferTextureLayer(
2109 target,
2110 attachment,
2111 texture.map(|t| t.0.get()).unwrap_or(0),
2112 level,
2113 layer,
2114 );
2115 }
2116
2117 unsafe fn named_framebuffer_renderbuffer(
2118 &self,
2119 framebuffer: Option<Self::Framebuffer>,
2120 attachment: u32,
2121 renderbuffer_target: u32,
2122 renderbuffer: Option<Self::Renderbuffer>,
2123 ) {
2124 let gl = &self.raw;
2125 gl.NamedFramebufferRenderbuffer(
2126 framebuffer.map(|f| f.0.get()).unwrap_or(0),
2127 attachment,
2128 renderbuffer_target,
2129 renderbuffer.map(|rb| rb.0.get()).unwrap_or(0),
2130 );
2131 }
2132
2133 unsafe fn named_framebuffer_texture(
2134 &self,
2135 framebuffer: Option<Self::Framebuffer>,
2136 attachment: u32,
2137 texture: Option<Self::Texture>,
2138 level: i32,
2139 ) {
2140 let gl = &self.raw;
2141 gl.NamedFramebufferTexture(
2142 framebuffer.map(|f| f.0.get()).unwrap_or(0),
2143 attachment,
2144 texture.map(|t| t.0.get()).unwrap_or(0),
2145 level,
2146 );
2147 }
2148
2149 unsafe fn named_framebuffer_texture_layer(
2150 &self,
2151 framebuffer: Option<Self::Framebuffer>,
2152 attachment: u32,
2153 texture: Option<Self::Texture>,
2154 level: i32,
2155 layer: i32,
2156 ) {
2157 let gl = &self.raw;
2158 gl.NamedFramebufferTextureLayer(
2159 framebuffer.map(|f| f.0.get()).unwrap_or(0),
2160 attachment,
2161 texture.map(|t| t.0.get()).unwrap_or(0),
2162 level,
2163 layer,
2164 );
2165 }
2166
2167 unsafe fn front_face(&self, value: u32) {
2168 let gl = &self.raw;
2169 gl.FrontFace(value as u32);
2170 }
2171
2172 unsafe fn get_error(&self) -> u32 {
2173 let gl = &self.raw;
2174 gl.GetError()
2175 }
2176
2177 unsafe fn get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
2178 let gl = &self.raw;
2179 let mut value = 0;
2180 gl.GetTexParameteriv(target, parameter, &mut value);
2181 value
2182 }
2183
2184 unsafe fn get_tex_parameter_f32(&self, target: u32, parameter: u32) -> f32 {
2185 let gl = &self.raw;
2186 let mut value = 0.;
2187 gl.GetTexParameterfv(target, parameter, &mut value);
2188 value
2189 }
2190
2191 unsafe fn get_texture_level_parameter_i32(
2192 &self,
2193 texture: Self::Texture,
2194 level: i32,
2195 parameter: u32,
2196 ) -> i32 {
2197 let gl = &self.raw;
2198 let mut value = 0;
2199 gl.GetTextureLevelParameteriv(texture.0.get(), level, parameter, &mut value);
2200 value
2201 }
2202
2203 unsafe fn get_texture_level_parameter_f32(
2204 &self,
2205 texture: Self::Texture,
2206 level: i32,
2207 parameter: u32,
2208 ) -> f32 {
2209 let gl = &self.raw;
2210 let mut value = 0.0;
2211 gl.GetTextureLevelParameterfv(texture.0.get(), level, parameter, &mut value);
2212 value
2213 }
2214
2215 unsafe fn get_tex_level_parameter_i32(&self, target: u32, level: i32, parameter: u32) -> i32 {
2216 let gl = &self.raw;
2217 let mut value = 0;
2218 gl.GetTexLevelParameteriv(target, level, parameter, &mut value);
2219 value
2220 }
2221
2222 unsafe fn get_tex_level_parameter_f32(&self, target: u32, level: i32, parameter: u32) -> f32 {
2223 let gl = &self.raw;
2224 let mut value = 0.0;
2225 gl.GetTexLevelParameterfv(target, level, parameter, &mut value);
2226 value
2227 }
2228
2229 unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
2230 let gl = &self.raw;
2231 let mut value = 0;
2232 gl.GetBufferParameteriv(target, parameter, &mut value);
2233 value
2234 }
2235
2236 unsafe fn get_parameter_bool(&self, parameter: u32) -> bool {
2237 let gl = &self.raw;
2238 let mut value = 0;
2239 gl.GetBooleanv(parameter, &mut value);
2240 value != FALSE
2241 }
2242
2243 unsafe fn get_parameter_bool_array<const N: usize>(&self, parameter: u32) -> [bool; N] {
2244 let gl = &self.raw;
2245 let mut value = [0; N];
2246 gl.GetBooleanv(parameter, &mut value[0]);
2247 value.map(|v| v != FALSE)
2248 }
2249
2250 unsafe fn get_parameter_i32(&self, parameter: u32) -> i32 {
2251 let gl = &self.raw;
2252 let mut value = 0;
2253 gl.GetIntegerv(parameter, &mut value);
2254 value
2255 }
2256
2257 unsafe fn get_parameter_i32_slice(&self, parameter: u32, out: &mut [i32]) {
2258 let gl = &self.raw;
2259 gl.GetIntegerv(parameter, &mut out[0]);
2260 }
2261
2262 unsafe fn get_parameter_i64(&self, parameter: u32) -> i64 {
2263 let gl = &self.raw;
2264 let mut value = 0;
2265 gl.GetInteger64v(parameter, &mut value);
2266 value
2267 }
2268
2269 unsafe fn get_parameter_i64_slice(&self, parameter: u32, out: &mut [i64]) {
2270 let gl = &self.raw;
2271 gl.GetInteger64v(parameter, &mut out[0]);
2272 }
2273
2274 unsafe fn get_parameter_indexed_i64(&self, parameter: u32, index: u32) -> i64 {
2275 let gl = &self.raw;
2276 let mut value = 0;
2277 gl.GetInteger64i_v(parameter, index, &mut value);
2278 value
2279 }
2280
2281 unsafe fn get_parameter_f32(&self, parameter: u32) -> f32 {
2282 let gl = &self.raw;
2283 let mut value: f32 = 0.0;
2284 gl.GetFloatv(parameter, &mut value);
2285 value
2286 }
2287
2288 unsafe fn get_parameter_f32_slice(&self, parameter: u32, out: &mut [f32]) {
2289 let gl = &self.raw;
2290 gl.GetFloatv(parameter, &mut out[0]);
2291 }
2292
2293 unsafe fn get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i32 {
2294 let gl = &self.raw;
2295 let mut value = 0;
2296 gl.GetIntegeri_v(parameter, index, &mut value);
2297 value
2298 }
2299
2300 unsafe fn get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String {
2301 let gl = &self.raw;
2302 let raw_ptr = gl.GetStringi(parameter, index);
2303 std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar)
2304 .to_str()
2305 .unwrap()
2306 .to_owned()
2307 }
2308
2309 unsafe fn get_parameter_string(&self, parameter: u32) -> String {
2310 let gl = &self.raw;
2311 let raw_ptr = gl.GetString(parameter);
2312 if raw_ptr.is_null() {
2313 panic!(
2314 "Get parameter string 0x{:X} failed. Maybe your GL context version is too outdated.",
2315 parameter
2316 )
2317 }
2318 std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar)
2319 .to_str()
2320 .unwrap()
2321 .to_owned()
2322 }
2323
2324 unsafe fn get_parameter_buffer(&self, parameter: u32) -> Option<Self::Buffer> {
2325 self.get_parameter_gl_name(parameter).map(NativeBuffer)
2326 }
2327
2328 unsafe fn get_parameter_framebuffer(&self, parameter: u32) -> Option<Self::Framebuffer> {
2329 self.get_parameter_gl_name(parameter).map(NativeFramebuffer)
2330 }
2331
2332 unsafe fn get_parameter_program(&self, parameter: u32) -> Option<Self::Program> {
2333 self.get_parameter_gl_name(parameter).map(NativeProgram)
2334 }
2335
2336 unsafe fn get_parameter_renderbuffer(&self, parameter: u32) -> Option<Self::Renderbuffer> {
2337 self.get_parameter_gl_name(parameter)
2338 .map(NativeRenderbuffer)
2339 }
2340
2341 unsafe fn get_parameter_sampler(&self, parameter: u32) -> Option<Self::Sampler> {
2342 self.get_parameter_gl_name(parameter).map(NativeSampler)
2343 }
2344
2345 unsafe fn get_parameter_texture(&self, parameter: u32) -> Option<Self::Texture> {
2346 self.get_parameter_gl_name(parameter).map(NativeTexture)
2347 }
2348
2349 unsafe fn get_parameter_transform_feedback(
2350 &self,
2351 parameter: u32,
2352 ) -> Option<Self::TransformFeedback> {
2353 self.get_parameter_gl_name(parameter)
2354 .map(NativeTransformFeedback)
2355 }
2356
2357 unsafe fn get_parameter_vertex_array(&self, parameter: u32) -> Option<Self::VertexArray> {
2358 self.get_parameter_gl_name(parameter).map(NativeVertexArray)
2359 }
2360
2361 unsafe fn get_renderbuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
2362 let gl = &self.raw;
2363 let mut value = 0;
2364 gl.GetRenderbufferParameteriv(target, parameter, &mut value);
2365 value
2366 }
2367
2368 unsafe fn get_framebuffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
2369 let gl = &self.raw;
2370 let mut value = 0;
2371 gl.GetFramebufferParameteriv(target, parameter, &mut value);
2372 value
2373 }
2374
2375 unsafe fn get_named_framebuffer_parameter_i32(
2376 &self,
2377 framebuffer: Option<Self::Framebuffer>,
2378 parameter: u32,
2379 ) -> i32 {
2380 let gl = &self.raw;
2381 let mut value = 0;
2382 gl.GetNamedFramebufferParameteriv(
2383 framebuffer.map(|f| f.0.get()).unwrap_or(0),
2384 parameter,
2385 &mut value,
2386 );
2387 value
2388 }
2389
2390 unsafe fn get_framebuffer_attachment_parameter_i32(
2391 &self,
2392 target: u32,
2393 attachment: u32,
2394 parameter: u32,
2395 ) -> i32 {
2396 let gl = &self.raw;
2397 let mut value = 0;
2398 gl.GetFramebufferAttachmentParameteriv(target, attachment, parameter, &mut value);
2399 value
2400 }
2401
2402 unsafe fn get_named_framebuffer_attachment_parameter_i32(
2403 &self,
2404 framebuffer: Option<Self::Framebuffer>,
2405 attachment: u32,
2406 parameter: u32,
2407 ) -> i32 {
2408 let gl = &self.raw;
2409 let mut value = 0;
2410 gl.GetNamedFramebufferAttachmentParameteriv(
2411 framebuffer.map(|f| f.0.get()).unwrap_or(0),
2412 attachment,
2413 parameter,
2414 &mut value,
2415 );
2416 value
2417 }
2418
2419 unsafe fn get_uniform_location(
2420 &self,
2421 program: Self::Program,
2422 name: &str,
2423 ) -> Option<Self::UniformLocation> {
2424 let gl = &self.raw;
2425 let name = CString::new(name).unwrap();
2426 let uniform_location =
2427 gl.GetUniformLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar);
2428 if uniform_location < 0 {
2429 None
2430 } else {
2431 Some(NativeUniformLocation(uniform_location as u32))
2432 }
2433 }
2434
2435 unsafe fn get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32> {
2436 let gl = &self.raw;
2437 let name = CString::new(name).unwrap();
2438 let attrib_location =
2439 gl.GetAttribLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar);
2440 if attrib_location < 0 {
2441 None
2442 } else {
2443 Some(attrib_location as u32)
2444 }
2445 }
2446
2447 unsafe fn bind_attrib_location(&self, program: Self::Program, index: u32, name: &str) {
2448 let gl = &self.raw;
2449 let name = CString::new(name).unwrap();
2450 gl.BindAttribLocation(
2451 program.0.get(),
2452 index,
2453 name.as_ptr() as *const native_gl::GLchar,
2454 );
2455 }
2456
2457 unsafe fn get_active_attributes(&self, program: Self::Program) -> u32 {
2458 let gl = &self.raw;
2459 let mut count = 0;
2460 gl.GetProgramiv(program.0.get(), ACTIVE_ATTRIBUTES, &mut count);
2461 count as u32
2462 }
2463
2464 unsafe fn get_active_attribute(
2465 &self,
2466 program: Self::Program,
2467 index: u32,
2468 ) -> Option<ActiveAttribute> {
2469 let gl = &self.raw;
2470 let mut attribute_max_size = 0;
2471 gl.GetProgramiv(
2472 program.0.get(),
2473 ACTIVE_ATTRIBUTE_MAX_LENGTH,
2474 &mut attribute_max_size,
2475 );
2476 let mut name = String::with_capacity(attribute_max_size as usize);
2477 name.extend(std::iter::repeat('\0').take(attribute_max_size as usize));
2478 let mut length = 0;
2479 let mut size = 0;
2480 let mut atype = 0;
2481 gl.GetActiveAttrib(
2482 program.0.get(),
2483 index,
2484 attribute_max_size,
2485 &mut length,
2486 &mut size,
2487 &mut atype,
2488 name.as_ptr() as *mut native_gl::GLchar,
2489 );
2490
2491 name.truncate(length as usize);
2492
2493 Some(ActiveAttribute { name, size, atype })
2494 }
2495
2496 unsafe fn get_sync_status(&self, fence: Self::Fence) -> u32 {
2497 let gl = &self.raw;
2498 let mut len = 0;
2499 let mut values = [UNSIGNALED as i32];
2500 gl.GetSynciv(
2501 fence.0,
2502 SYNC_STATUS,
2503 values.len() as i32,
2504 &mut len,
2505 values.as_mut_ptr(),
2506 );
2507 values[0] as u32
2508 }
2509
2510 unsafe fn is_sync(&self, fence: Self::Fence) -> bool {
2511 let gl = &self.raw;
2512 1 == gl.IsSync(fence.0)
2513 }
2514
2515 unsafe fn renderbuffer_storage(
2516 &self,
2517 target: u32,
2518 internal_format: u32,
2519 width: i32,
2520 height: i32,
2521 ) {
2522 let gl = &self.raw;
2523 gl.RenderbufferStorage(target, internal_format, width, height);
2524 }
2525
2526 unsafe fn renderbuffer_storage_multisample(
2527 &self,
2528 target: u32,
2529 samples: i32,
2530 internal_format: u32,
2531 width: i32,
2532 height: i32,
2533 ) {
2534 let gl = &self.raw;
2535 gl.RenderbufferStorageMultisample(target, samples, internal_format, width, height);
2536 }
2537
2538 unsafe fn sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32) {
2539 let gl = &self.raw;
2540 gl.SamplerParameterf(sampler.0.get(), name, value);
2541 }
2542
2543 unsafe fn sampler_parameter_f32_slice(&self, sampler: Self::Sampler, name: u32, value: &[f32]) {
2544 let gl = &self.raw;
2545 gl.SamplerParameterfv(sampler.0.get(), name, value.as_ptr());
2546 }
2547
2548 unsafe fn sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32) {
2549 let gl = &self.raw;
2550 gl.SamplerParameteri(sampler.0.get(), name, value);
2551 }
2552
2553 unsafe fn get_sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32) -> i32 {
2554 let gl = &self.raw;
2555 let mut value = 0;
2556 gl.GetSamplerParameteriv(sampler.0.get(), name, &mut value);
2557 value
2558 }
2559
2560 unsafe fn get_sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32) -> f32 {
2561 let gl = &self.raw;
2562 let mut value = 0.;
2563 gl.GetSamplerParameterfv(sampler.0.get(), name, &mut value);
2564 value
2565 }
2566
2567 unsafe fn get_sampler_parameter_f32_slice(
2568 &self,
2569 sampler: Self::Sampler,
2570 name: u32,
2571 out: &mut [f32],
2572 ) {
2573 let gl = &self.raw;
2574 gl.GetSamplerParameterfv(sampler.0.get(), name, out.as_mut_ptr());
2575 }
2576
2577 unsafe fn generate_mipmap(&self, target: u32) {
2578 let gl = &self.raw;
2579 gl.GenerateMipmap(target);
2580 }
2581
2582 unsafe fn generate_texture_mipmap(&self, texture: Self::Texture) {
2583 let gl = &self.raw;
2584 gl.GenerateTextureMipmap(texture.0.get());
2585 }
2586
2587 unsafe fn tex_image_1d(
2588 &self,
2589 target: u32,
2590 level: i32,
2591 internal_format: i32,
2592 width: i32,
2593 border: i32,
2594 format: u32,
2595 ty: u32,
2596 pixels: PixelUnpackData,
2597 ) {
2598 let gl = &self.raw;
2599 gl.TexImage1D(
2600 target,
2601 level,
2602 internal_format,
2603 width,
2604 border,
2605 format,
2606 ty,
2607 match pixels {
2608 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
2609 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
2610 PixelUnpackData::Slice(None) => ptr::null(),
2611 },
2612 );
2613 }
2614
2615 unsafe fn compressed_tex_image_1d(
2616 &self,
2617 target: u32,
2618 level: i32,
2619 internal_format: i32,
2620 width: i32,
2621 border: i32,
2622 image_size: i32,
2623 pixels: &[u8],
2624 ) {
2625 let gl = &self.raw;
2626 gl.CompressedTexImage1D(
2627 target,
2628 level,
2629 internal_format as u32,
2630 width,
2631 border,
2632 image_size,
2633 pixels.as_ptr() as *const std::ffi::c_void,
2634 );
2635 }
2636
2637 unsafe fn tex_image_2d(
2638 &self,
2639 target: u32,
2640 level: i32,
2641 internal_format: i32,
2642 width: i32,
2643 height: i32,
2644 border: i32,
2645 format: u32,
2646 ty: u32,
2647 pixels: PixelUnpackData,
2648 ) {
2649 let gl = &self.raw;
2650 gl.TexImage2D(
2651 target,
2652 level,
2653 internal_format,
2654 width,
2655 height,
2656 border,
2657 format,
2658 ty,
2659 match pixels {
2660 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
2661 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
2662 PixelUnpackData::Slice(None) => ptr::null(),
2663 },
2664 );
2665 }
2666
2667 unsafe fn tex_image_2d_multisample(
2668 &self,
2669 target: u32,
2670 samples: i32,
2671 internal_format: i32,
2672 width: i32,
2673 height: i32,
2674 fixed_sample_locations: bool,
2675 ) {
2676 let gl = &self.raw;
2677 gl.TexImage2DMultisample(
2678 target,
2679 samples,
2680 internal_format as u32,
2681 width,
2682 height,
2683 if fixed_sample_locations { 1 } else { 0 },
2684 );
2685 }
2686
2687 unsafe fn compressed_tex_image_2d(
2688 &self,
2689 target: u32,
2690 level: i32,
2691 internal_format: i32,
2692 width: i32,
2693 height: i32,
2694 border: i32,
2695 image_size: i32,
2696 pixels: &[u8],
2697 ) {
2698 let gl = &self.raw;
2699 gl.CompressedTexImage2D(
2700 target,
2701 level,
2702 internal_format as u32,
2703 width,
2704 height,
2705 border,
2706 image_size,
2707 pixels.as_ptr() as *const std::ffi::c_void,
2708 );
2709 }
2710
2711 unsafe fn tex_image_3d(
2712 &self,
2713 target: u32,
2714 level: i32,
2715 internal_format: i32,
2716 width: i32,
2717 height: i32,
2718 depth: i32,
2719 border: i32,
2720 format: u32,
2721 ty: u32,
2722 pixels: PixelUnpackData,
2723 ) {
2724 let gl = &self.raw;
2725 gl.TexImage3D(
2726 target,
2727 level,
2728 internal_format,
2729 width,
2730 height,
2731 depth,
2732 border,
2733 format,
2734 ty,
2735 match pixels {
2736 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
2737 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
2738 PixelUnpackData::Slice(None) => ptr::null(),
2739 },
2740 );
2741 }
2742
2743 unsafe fn compressed_tex_image_3d(
2744 &self,
2745 target: u32,
2746 level: i32,
2747 internal_format: i32,
2748 width: i32,
2749 height: i32,
2750 depth: i32,
2751 border: i32,
2752 image_size: i32,
2753 pixels: &[u8],
2754 ) {
2755 let gl = &self.raw;
2756 gl.CompressedTexImage3D(
2757 target,
2758 level,
2759 internal_format as u32,
2760 width,
2761 height,
2762 depth,
2763 border,
2764 image_size,
2765 pixels.as_ptr() as *const std::ffi::c_void,
2766 );
2767 }
2768
2769 unsafe fn tex_storage_1d(&self, target: u32, levels: i32, internal_format: u32, width: i32) {
2770 let gl = &self.raw;
2771 gl.TexStorage1D(target, levels, internal_format, width);
2772 }
2773
2774 unsafe fn tex_storage_2d(
2775 &self,
2776 target: u32,
2777 levels: i32,
2778 internal_format: u32,
2779 width: i32,
2780 height: i32,
2781 ) {
2782 let gl = &self.raw;
2783 gl.TexStorage2D(target, levels, internal_format, width, height);
2784 }
2785
2786 unsafe fn texture_storage_2d(
2787 &self,
2788 texture: Self::Texture,
2789 levels: i32,
2790 internal_format: u32,
2791 width: i32,
2792 height: i32,
2793 ) {
2794 let gl = &self.raw;
2795 gl.TextureStorage2D(texture.0.get(), levels, internal_format, width, height);
2796 }
2797
2798 unsafe fn tex_storage_2d_multisample(
2799 &self,
2800 target: u32,
2801 samples: i32,
2802 internal_format: u32,
2803 width: i32,
2804 height: i32,
2805 fixed_sample_locations: bool,
2806 ) {
2807 let gl = &self.raw;
2808 gl.TexStorage2DMultisample(
2809 target,
2810 samples,
2811 internal_format,
2812 width,
2813 height,
2814 if fixed_sample_locations { 1 } else { 0 },
2815 );
2816 }
2817
2818 unsafe fn tex_storage_3d(
2819 &self,
2820 target: u32,
2821 levels: i32,
2822 internal_format: u32,
2823 width: i32,
2824 height: i32,
2825 depth: i32,
2826 ) {
2827 let gl = &self.raw;
2828 gl.TexStorage3D(target, levels, internal_format, width, height, depth);
2829 }
2830
2831 unsafe fn texture_storage_3d(
2832 &self,
2833 texture: Self::Texture,
2834 levels: i32,
2835 internal_format: u32,
2836 width: i32,
2837 height: i32,
2838 depth: i32,
2839 ) {
2840 let gl = &self.raw;
2841 gl.TextureStorage3D(
2842 texture.0.get(),
2843 levels,
2844 internal_format,
2845 width,
2846 height,
2847 depth,
2848 );
2849 }
2850
2851 unsafe fn get_uniform_i32(
2852 &self,
2853 program: Self::Program,
2854 location: &Self::UniformLocation,
2855 v: &mut [i32],
2856 ) {
2857 let gl = &self.raw;
2858 gl.GetUniformiv(program.0.get(), location.0 as i32, v.as_mut_ptr())
2859 }
2860
2861 unsafe fn get_uniform_u32(
2862 &self,
2863 program: Self::Program,
2864 location: &Self::UniformLocation,
2865 v: &mut [u32],
2866 ) {
2867 let gl = &self.raw;
2868 gl.GetUniformuiv(program.0.get(), location.0 as i32, v.as_mut_ptr())
2869 }
2870
2871 unsafe fn get_uniform_f32(
2872 &self,
2873 program: Self::Program,
2874 location: &Self::UniformLocation,
2875 v: &mut [f32],
2876 ) {
2877 let gl = &self.raw;
2878 gl.GetUniformfv(program.0.get(), location.0 as i32, v.as_mut_ptr())
2879 }
2880
2881 unsafe fn uniform_1_i32(&self, location: Option<&Self::UniformLocation>, x: i32) {
2882 let gl = &self.raw;
2883 if let Some(loc) = location {
2884 gl.Uniform1i(loc.0 as i32, x);
2885 }
2886 }
2887
2888 unsafe fn uniform_2_i32(&self, location: Option<&Self::UniformLocation>, x: i32, y: i32) {
2889 let gl = &self.raw;
2890 if let Some(loc) = location {
2891 gl.Uniform2i(loc.0 as i32, x, y);
2892 }
2893 }
2894
2895 unsafe fn uniform_3_i32(
2896 &self,
2897 location: Option<&Self::UniformLocation>,
2898 x: i32,
2899 y: i32,
2900 z: i32,
2901 ) {
2902 let gl = &self.raw;
2903 if let Some(loc) = location {
2904 gl.Uniform3i(loc.0 as i32, x, y, z);
2905 }
2906 }
2907
2908 unsafe fn uniform_4_i32(
2909 &self,
2910 location: Option<&Self::UniformLocation>,
2911 x: i32,
2912 y: i32,
2913 z: i32,
2914 w: i32,
2915 ) {
2916 let gl = &self.raw;
2917 if let Some(loc) = location {
2918 gl.Uniform4i(loc.0 as i32, x, y, z, w);
2919 }
2920 }
2921
2922 unsafe fn uniform_1_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
2923 let gl = &self.raw;
2924 if let Some(loc) = location {
2925 gl.Uniform1iv(loc.0 as i32, v.len() as i32, v.as_ptr());
2926 }
2927 }
2928
2929 unsafe fn uniform_2_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
2930 let gl = &self.raw;
2931 if let Some(loc) = location {
2932 gl.Uniform2iv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
2933 }
2934 }
2935
2936 unsafe fn uniform_3_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
2937 let gl = &self.raw;
2938 if let Some(loc) = location {
2939 gl.Uniform3iv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
2940 }
2941 }
2942
2943 unsafe fn uniform_4_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
2944 let gl = &self.raw;
2945 if let Some(loc) = location {
2946 gl.Uniform4iv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
2947 }
2948 }
2949
2950 unsafe fn uniform_1_u32(&self, location: Option<&Self::UniformLocation>, x: u32) {
2951 let gl = &self.raw;
2952 if let Some(loc) = location {
2953 gl.Uniform1ui(loc.0 as i32, x);
2954 }
2955 }
2956
2957 unsafe fn uniform_2_u32(&self, location: Option<&Self::UniformLocation>, x: u32, y: u32) {
2958 let gl = &self.raw;
2959 if let Some(loc) = location {
2960 gl.Uniform2ui(loc.0 as i32, x, y);
2961 }
2962 }
2963
2964 unsafe fn uniform_3_u32(
2965 &self,
2966 location: Option<&Self::UniformLocation>,
2967 x: u32,
2968 y: u32,
2969 z: u32,
2970 ) {
2971 let gl = &self.raw;
2972 if let Some(loc) = location {
2973 gl.Uniform3ui(loc.0 as i32, x, y, z);
2974 }
2975 }
2976
2977 unsafe fn uniform_4_u32(
2978 &self,
2979 location: Option<&Self::UniformLocation>,
2980 x: u32,
2981 y: u32,
2982 z: u32,
2983 w: u32,
2984 ) {
2985 let gl = &self.raw;
2986 if let Some(loc) = location {
2987 gl.Uniform4ui(loc.0 as i32, x, y, z, w);
2988 }
2989 }
2990
2991 unsafe fn uniform_1_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
2992 let gl = &self.raw;
2993 if let Some(loc) = location {
2994 gl.Uniform1uiv(loc.0 as i32, v.len() as i32, v.as_ptr());
2995 }
2996 }
2997
2998 unsafe fn uniform_2_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
2999 let gl = &self.raw;
3000 if let Some(loc) = location {
3001 gl.Uniform2uiv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
3002 }
3003 }
3004
3005 unsafe fn uniform_3_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
3006 let gl = &self.raw;
3007 if let Some(loc) = location {
3008 gl.Uniform3uiv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
3009 }
3010 }
3011
3012 unsafe fn uniform_4_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
3013 let gl = &self.raw;
3014 if let Some(loc) = location {
3015 gl.Uniform4uiv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
3016 }
3017 }
3018
3019 unsafe fn uniform_1_f32(&self, location: Option<&Self::UniformLocation>, x: f32) {
3020 let gl = &self.raw;
3021 if let Some(loc) = location {
3022 gl.Uniform1f(loc.0 as i32, x);
3023 }
3024 }
3025
3026 unsafe fn uniform_2_f32(&self, location: Option<&Self::UniformLocation>, x: f32, y: f32) {
3027 let gl = &self.raw;
3028 if let Some(loc) = location {
3029 gl.Uniform2f(loc.0 as i32, x, y);
3030 }
3031 }
3032
3033 unsafe fn uniform_3_f32(
3034 &self,
3035 location: Option<&Self::UniformLocation>,
3036 x: f32,
3037 y: f32,
3038 z: f32,
3039 ) {
3040 let gl = &self.raw;
3041 if let Some(loc) = location {
3042 gl.Uniform3f(loc.0 as i32, x, y, z);
3043 }
3044 }
3045
3046 unsafe fn uniform_4_f32(
3047 &self,
3048 location: Option<&Self::UniformLocation>,
3049 x: f32,
3050 y: f32,
3051 z: f32,
3052 w: f32,
3053 ) {
3054 let gl = &self.raw;
3055 if let Some(loc) = location {
3056 gl.Uniform4f(loc.0 as i32, x, y, z, w);
3057 }
3058 }
3059
3060 unsafe fn uniform_1_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
3061 let gl = &self.raw;
3062 if let Some(loc) = location {
3063 gl.Uniform1fv(loc.0 as i32, v.len() as i32, v.as_ptr());
3064 }
3065 }
3066
3067 unsafe fn uniform_2_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
3068 let gl = &self.raw;
3069 if let Some(loc) = location {
3070 gl.Uniform2fv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
3071 }
3072 }
3073
3074 unsafe fn uniform_3_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
3075 let gl = &self.raw;
3076 if let Some(loc) = location {
3077 gl.Uniform3fv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
3078 }
3079 }
3080
3081 unsafe fn uniform_4_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
3082 let gl = &self.raw;
3083 if let Some(loc) = location {
3084 gl.Uniform4fv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
3085 }
3086 }
3087
3088 unsafe fn uniform_matrix_2_f32_slice(
3089 &self,
3090 location: Option<&Self::UniformLocation>,
3091 transpose: bool,
3092 v: &[f32],
3093 ) {
3094 let gl = &self.raw;
3095 if let Some(loc) = location {
3096 gl.UniformMatrix2fv(
3097 loc.0 as i32,
3098 v.len() as i32 / 4,
3099 transpose as u8,
3100 v.as_ptr(),
3101 );
3102 }
3103 }
3104
3105 unsafe fn uniform_matrix_2x3_f32_slice(
3106 &self,
3107 location: Option<&Self::UniformLocation>,
3108 transpose: bool,
3109 v: &[f32],
3110 ) {
3111 let gl = &self.raw;
3112 if let Some(loc) = location {
3113 gl.UniformMatrix2x3fv(
3114 loc.0 as i32,
3115 v.len() as i32 / 6,
3116 transpose as u8,
3117 v.as_ptr(),
3118 );
3119 }
3120 }
3121
3122 unsafe fn uniform_matrix_2x4_f32_slice(
3123 &self,
3124 location: Option<&Self::UniformLocation>,
3125 transpose: bool,
3126 v: &[f32],
3127 ) {
3128 let gl = &self.raw;
3129 if let Some(loc) = location {
3130 gl.UniformMatrix2x4fv(
3131 loc.0 as i32,
3132 v.len() as i32 / 8,
3133 transpose as u8,
3134 v.as_ptr(),
3135 );
3136 }
3137 }
3138
3139 unsafe fn uniform_matrix_3x2_f32_slice(
3140 &self,
3141 location: Option<&Self::UniformLocation>,
3142 transpose: bool,
3143 v: &[f32],
3144 ) {
3145 let gl = &self.raw;
3146 if let Some(loc) = location {
3147 gl.UniformMatrix3x2fv(
3148 loc.0 as i32,
3149 v.len() as i32 / 6,
3150 transpose as u8,
3151 v.as_ptr(),
3152 );
3153 }
3154 }
3155
3156 unsafe fn uniform_matrix_3_f32_slice(
3157 &self,
3158 location: Option<&Self::UniformLocation>,
3159 transpose: bool,
3160 v: &[f32],
3161 ) {
3162 let gl = &self.raw;
3163 if let Some(loc) = location {
3164 gl.UniformMatrix3fv(
3165 loc.0 as i32,
3166 v.len() as i32 / 9,
3167 transpose as u8,
3168 v.as_ptr(),
3169 );
3170 }
3171 }
3172
3173 unsafe fn uniform_matrix_3x4_f32_slice(
3174 &self,
3175 location: Option<&Self::UniformLocation>,
3176 transpose: bool,
3177 v: &[f32],
3178 ) {
3179 let gl = &self.raw;
3180 if let Some(loc) = location {
3181 gl.UniformMatrix3x4fv(
3182 loc.0 as i32,
3183 v.len() as i32 / 12,
3184 transpose as u8,
3185 v.as_ptr(),
3186 );
3187 }
3188 }
3189
3190 unsafe fn uniform_matrix_4x2_f32_slice(
3191 &self,
3192 location: Option<&Self::UniformLocation>,
3193 transpose: bool,
3194 v: &[f32],
3195 ) {
3196 let gl = &self.raw;
3197 if let Some(loc) = location {
3198 gl.UniformMatrix4x2fv(
3199 loc.0 as i32,
3200 v.len() as i32 / 8,
3201 transpose as u8,
3202 v.as_ptr(),
3203 );
3204 }
3205 }
3206
3207 unsafe fn uniform_matrix_4x3_f32_slice(
3208 &self,
3209 location: Option<&Self::UniformLocation>,
3210 transpose: bool,
3211 v: &[f32],
3212 ) {
3213 let gl = &self.raw;
3214 if let Some(loc) = location {
3215 gl.UniformMatrix4x3fv(
3216 loc.0 as i32,
3217 v.len() as i32 / 12,
3218 transpose as u8,
3219 v.as_ptr(),
3220 );
3221 }
3222 }
3223
3224 unsafe fn uniform_matrix_4_f32_slice(
3225 &self,
3226 location: Option<&Self::UniformLocation>,
3227 transpose: bool,
3228 v: &[f32],
3229 ) {
3230 let gl = &self.raw;
3231 if let Some(loc) = location {
3232 gl.UniformMatrix4fv(
3233 loc.0 as i32,
3234 v.len() as i32 / 16,
3235 transpose as u8,
3236 v.as_ptr(),
3237 );
3238 }
3239 }
3240
3241 unsafe fn unmap_buffer(&self, target: u32) {
3242 let gl = &self.raw;
3243 gl.UnmapBuffer(target);
3244 }
3245
3246 unsafe fn cull_face(&self, value: u32) {
3247 let gl = &self.raw;
3248 gl.CullFace(value as u32);
3249 }
3250
3251 unsafe fn color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool) {
3252 let gl = &self.raw;
3253 gl.ColorMask(red as u8, green as u8, blue as u8, alpha as u8);
3254 }
3255
3256 unsafe fn color_mask_draw_buffer(
3257 &self,
3258 draw_buffer: u32,
3259 red: bool,
3260 green: bool,
3261 blue: bool,
3262 alpha: bool,
3263 ) {
3264 let gl = &self.raw;
3265 gl.ColorMaski(draw_buffer, red as u8, green as u8, blue as u8, alpha as u8);
3266 }
3267
3268 unsafe fn depth_mask(&self, value: bool) {
3269 let gl = &self.raw;
3270 gl.DepthMask(value as u8);
3271 }
3272
3273 unsafe fn blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
3274 let gl = &self.raw;
3275 gl.BlendColor(red, green, blue, alpha);
3276 }
3277
3278 unsafe fn line_width(&self, width: f32) {
3279 let gl = &self.raw;
3280 gl.LineWidth(width);
3281 }
3282
3283 unsafe fn map_buffer_range(
3284 &self,
3285 target: u32,
3286 offset: i32,
3287 length: i32,
3288 access: u32,
3289 ) -> *mut u8 {
3290 let gl = &self.raw;
3291 gl.MapBufferRange(target, offset as isize, length as isize, access) as *mut u8
3292 }
3293
3294 unsafe fn flush_mapped_buffer_range(&self, target: u32, offset: i32, length: i32) {
3295 let gl = &self.raw;
3296 gl.FlushMappedBufferRange(target, offset as isize, length as isize)
3297 }
3298
3299 unsafe fn invalidate_buffer_sub_data(&self, target: u32, offset: i32, length: i32) {
3300 let gl = &self.raw;
3301 gl.InvalidateBufferSubData(target, offset as isize, length as isize)
3302 }
3303
3304 unsafe fn invalidate_framebuffer(&self, target: u32, attachments: &[u32]) {
3305 let gl = &self.raw;
3306 gl.InvalidateFramebuffer(target, attachments.len() as i32, attachments.as_ptr());
3307 }
3308
3309 unsafe fn invalidate_sub_framebuffer(
3310 &self,
3311 target: u32,
3312 attachments: &[u32],
3313 x: i32,
3314 y: i32,
3315 width: i32,
3316 height: i32,
3317 ) {
3318 let gl = &self.raw;
3319 gl.InvalidateSubFramebuffer(
3320 target,
3321 attachments.len() as i32,
3322 attachments.as_ptr(),
3323 x,
3324 y,
3325 width,
3326 height,
3327 );
3328 }
3329
3330 unsafe fn polygon_offset(&self, factor: f32, units: f32) {
3331 let gl = &self.raw;
3332 gl.PolygonOffset(factor, units);
3333 }
3334
3335 unsafe fn polygon_mode(&self, face: u32, mode: u32) {
3336 let gl = &self.raw;
3337 gl.PolygonMode(face as u32, mode as u32);
3338 }
3339
3340 unsafe fn finish(&self) {
3341 let gl = &self.raw;
3342 gl.Finish();
3343 }
3344
3345 unsafe fn bind_texture(&self, target: u32, texture: Option<Self::Texture>) {
3346 let gl = &self.raw;
3347 gl.BindTexture(target, texture.map(|t| t.0.get()).unwrap_or(0));
3348 }
3349
3350 unsafe fn bind_texture_unit(&self, unit: u32, texture: Option<Self::Texture>) {
3351 let gl = &self.raw;
3352 gl.BindTextureUnit(unit, texture.map(|t| t.0.get()).unwrap_or(0));
3353 }
3354
3355 unsafe fn bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>) {
3356 let gl = &self.raw;
3357 gl.BindSampler(unit, sampler.map(|s| s.0.get()).unwrap_or(0));
3358 }
3359
3360 unsafe fn active_texture(&self, unit: u32) {
3361 let gl = &self.raw;
3362 gl.ActiveTexture(unit);
3363 }
3364
3365 unsafe fn fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String> {
3366 let gl = &self.raw;
3367 Ok(NativeFence(gl.FenceSync(condition as u32, flags)))
3368 }
3369
3370 unsafe fn tex_parameter_f32(&self, target: u32, parameter: u32, value: f32) {
3371 let gl = &self.raw;
3372 gl.TexParameterf(target, parameter, value);
3373 }
3374
3375 unsafe fn tex_parameter_i32(&self, target: u32, parameter: u32, value: i32) {
3376 let gl = &self.raw;
3377 gl.TexParameteri(target, parameter, value);
3378 }
3379
3380 unsafe fn texture_parameter_i32(&self, texture: Self::Texture, parameter: u32, value: i32) {
3381 let gl = &self.raw;
3382 gl.TextureParameteri(texture.0.get(), parameter, value);
3383 }
3384
3385 unsafe fn tex_parameter_f32_slice(&self, target: u32, parameter: u32, values: &[f32]) {
3386 let gl = &self.raw;
3387 gl.TexParameterfv(target, parameter, values.as_ptr());
3388 }
3389
3390 unsafe fn tex_parameter_i32_slice(&self, target: u32, parameter: u32, values: &[i32]) {
3391 let gl = &self.raw;
3392 gl.TexParameteriv(target, parameter, values.as_ptr());
3393 }
3394
3395 unsafe fn tex_sub_image_2d(
3396 &self,
3397 target: u32,
3398 level: i32,
3399 x_offset: i32,
3400 y_offset: i32,
3401 width: i32,
3402 height: i32,
3403 format: u32,
3404 ty: u32,
3405 pixels: PixelUnpackData,
3406 ) {
3407 let gl = &self.raw;
3408 gl.TexSubImage2D(
3409 target,
3410 level,
3411 x_offset,
3412 y_offset,
3413 width,
3414 height,
3415 format,
3416 ty,
3417 match pixels {
3418 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
3419 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
3420 PixelUnpackData::Slice(None) => ptr::null(),
3421 },
3422 );
3423 }
3424
3425 unsafe fn texture_sub_image_2d(
3426 &self,
3427 texture: Self::Texture,
3428 level: i32,
3429 x_offset: i32,
3430 y_offset: i32,
3431 width: i32,
3432 height: i32,
3433 format: u32,
3434 ty: u32,
3435 pixels: PixelUnpackData,
3436 ) {
3437 let gl = &self.raw;
3438 gl.TextureSubImage2D(
3439 texture.0.get(),
3440 level,
3441 x_offset,
3442 y_offset,
3443 width,
3444 height,
3445 format,
3446 ty,
3447 match pixels {
3448 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
3449 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
3450 PixelUnpackData::Slice(None) => ptr::null(),
3451 },
3452 );
3453 }
3454
3455 unsafe fn compressed_tex_sub_image_2d(
3456 &self,
3457 target: u32,
3458 level: i32,
3459 x_offset: i32,
3460 y_offset: i32,
3461 width: i32,
3462 height: i32,
3463 format: u32,
3464 pixels: CompressedPixelUnpackData,
3465 ) {
3466 let gl = &self.raw;
3467 let (data, image_size) = match pixels {
3468 CompressedPixelUnpackData::BufferRange(ref range) => (
3469 range.start as *const std::ffi::c_void,
3470 (range.end - range.start) as i32,
3471 ),
3472 CompressedPixelUnpackData::Slice(data) => {
3473 (data.as_ptr() as *const std::ffi::c_void, data.len() as i32)
3474 }
3475 };
3476
3477 gl.CompressedTexSubImage2D(
3478 target, level, x_offset, y_offset, width, height, format, image_size, data,
3479 );
3480 }
3481
3482 unsafe fn tex_sub_image_3d(
3483 &self,
3484 target: u32,
3485 level: i32,
3486 x_offset: i32,
3487 y_offset: i32,
3488 z_offset: i32,
3489 width: i32,
3490 height: i32,
3491 depth: i32,
3492 format: u32,
3493 ty: u32,
3494 pixels: PixelUnpackData,
3495 ) {
3496 let gl = &self.raw;
3497 gl.TexSubImage3D(
3498 target,
3499 level,
3500 x_offset,
3501 y_offset,
3502 z_offset,
3503 width,
3504 height,
3505 depth,
3506 format,
3507 ty,
3508 match pixels {
3509 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
3510 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
3511 PixelUnpackData::Slice(None) => ptr::null(),
3512 },
3513 );
3514 }
3515
3516 unsafe fn texture_sub_image_3d(
3517 &self,
3518 texture: Self::Texture,
3519 level: i32,
3520 x_offset: i32,
3521 y_offset: i32,
3522 z_offset: i32,
3523 width: i32,
3524 height: i32,
3525 depth: i32,
3526 format: u32,
3527 ty: u32,
3528 pixels: PixelUnpackData,
3529 ) {
3530 let gl = &self.raw;
3531 gl.TextureSubImage3D(
3532 texture.0.get(),
3533 level,
3534 x_offset,
3535 y_offset,
3536 z_offset,
3537 width,
3538 height,
3539 depth,
3540 format,
3541 ty,
3542 match pixels {
3543 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
3544 PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void,
3545 PixelUnpackData::Slice(None) => ptr::null(),
3546 },
3547 );
3548 }
3549
3550 unsafe fn compressed_tex_sub_image_3d(
3551 &self,
3552 target: u32,
3553 level: i32,
3554 x_offset: i32,
3555 y_offset: i32,
3556 z_offset: i32,
3557 width: i32,
3558 height: i32,
3559 depth: i32,
3560 format: u32,
3561 pixels: CompressedPixelUnpackData,
3562 ) {
3563 let gl = &self.raw;
3564 let (data, image_size) = match pixels {
3565 CompressedPixelUnpackData::BufferRange(ref range) => (
3566 range.start as *const std::ffi::c_void,
3567 (range.end - range.start) as i32,
3568 ),
3569 CompressedPixelUnpackData::Slice(data) => {
3570 (data.as_ptr() as *const std::ffi::c_void, data.len() as i32)
3571 }
3572 };
3573
3574 gl.CompressedTexSubImage3D(
3575 target, level, x_offset, y_offset, z_offset, width, height, depth, format, image_size,
3576 data,
3577 );
3578 }
3579
3580 unsafe fn depth_func(&self, func: u32) {
3581 let gl = &self.raw;
3582 gl.DepthFunc(func as u32);
3583 }
3584
3585 unsafe fn depth_range_f32(&self, near: f32, far: f32) {
3586 let gl = &self.raw;
3587 gl.DepthRangef(near, far);
3588 }
3589
3590 unsafe fn depth_range_f64(&self, near: f64, far: f64) {
3591 let gl = &self.raw;
3592 gl.DepthRange(near, far);
3593 }
3594
3595 unsafe fn depth_range(&self, near: f64, far: f64) {
3596 if self.supports_f64_precision() {
3597 self.depth_range_f64(near, far);
3598 } else {
3599 self.depth_range_f32(near as f32, far as f32);
3600 }
3601 }
3602
3603 unsafe fn depth_range_f64_slice(&self, first: u32, count: i32, values: &[[f64; 2]]) {
3604 let gl = &self.raw;
3605 gl.DepthRangeArrayv(first, count, values.as_ptr() as *const f64);
3606 }
3607
3608 unsafe fn scissor(&self, x: i32, y: i32, width: i32, height: i32) {
3609 let gl = &self.raw;
3610 gl.Scissor(x, y, width, height);
3611 }
3612
3613 unsafe fn scissor_slice(&self, first: u32, count: i32, scissors: &[[i32; 4]]) {
3614 let gl = &self.raw;
3615 gl.ScissorArrayv(first, count, scissors.as_ptr() as *const i32);
3616 }
3617
3618 unsafe fn vertex_array_attrib_binding_f32(
3619 &self,
3620 vao: Self::VertexArray,
3621 index: u32,
3622 binding_index: u32,
3623 ) {
3624 let gl = &self.raw;
3625 gl.VertexArrayAttribBinding(vao.0.get(), index, binding_index);
3626 }
3627
3628 unsafe fn vertex_array_attrib_format_f32(
3629 &self,
3630 vao: Self::VertexArray,
3631 index: u32,
3632 size: i32,
3633 data_type: u32,
3634 normalized: bool,
3635 relative_offset: u32,
3636 ) {
3637 let gl = &self.raw;
3638 gl.VertexArrayAttribFormat(
3639 vao.0.get(),
3640 index,
3641 size,
3642 data_type,
3643 normalized as u8,
3644 relative_offset,
3645 );
3646 }
3647
3648 unsafe fn vertex_array_attrib_format_i32(
3649 &self,
3650 vao: Self::VertexArray,
3651 index: u32,
3652 size: i32,
3653 data_type: u32,
3654 relative_offset: u32,
3655 ) {
3656 let gl = &self.raw;
3657 gl.VertexArrayAttribIFormat(vao.0.get(), index, size, data_type, relative_offset);
3658 }
3659
3660 unsafe fn vertex_array_attrib_format_f64(
3661 &self,
3662 vao: Self::VertexArray,
3663 index: u32,
3664 size: i32,
3665 data_type: u32,
3666 relative_offset: u32,
3667 ) {
3668 let gl = &self.raw;
3669 gl.VertexArrayAttribLFormat(vao.0.get(), index, size, data_type, relative_offset);
3670 }
3671
3672 unsafe fn vertex_array_element_buffer(
3673 &self,
3674 vao: Self::VertexArray,
3675 buffer: Option<Self::Buffer>,
3676 ) {
3677 let gl = &self.raw;
3678 gl.VertexArrayElementBuffer(vao.0.get(), buffer.map(|b| b.0.get()).unwrap_or(0));
3679 }
3680
3681 unsafe fn vertex_array_vertex_buffer(
3682 &self,
3683 vao: Self::VertexArray,
3684 binding_index: u32,
3685 buffer: Option<Self::Buffer>,
3686 offset: i32,
3687 stride: i32,
3688 ) {
3689 let gl = &self.raw;
3690 gl.VertexArrayVertexBuffer(
3691 vao.0.get(),
3692 binding_index,
3693 buffer.map(|b| b.0.get()).unwrap_or(0),
3694 offset as isize,
3695 stride,
3696 );
3697 }
3698
3699 unsafe fn vertex_attrib_divisor(&self, index: u32, divisor: u32) {
3700 let gl = &self.raw;
3701 gl.VertexAttribDivisor(index, divisor);
3702 }
3703
3704 unsafe fn get_vertex_attrib_parameter_f32_slice(
3705 &self,
3706 index: u32,
3707 pname: u32,
3708 result: &mut [f32],
3709 ) {
3710 let gl = &self.raw;
3711 gl.GetVertexAttribfv(index, pname, result.as_mut_ptr());
3712 }
3713
3714 unsafe fn vertex_attrib_pointer_f32(
3715 &self,
3716 index: u32,
3717 size: i32,
3718 data_type: u32,
3719 normalized: bool,
3720 stride: i32,
3721 offset: i32,
3722 ) {
3723 let gl = &self.raw;
3724 gl.VertexAttribPointer(
3725 index,
3726 size,
3727 data_type,
3728 normalized as u8,
3729 stride,
3730 offset as *const std::ffi::c_void,
3731 );
3732 }
3733
3734 unsafe fn vertex_attrib_pointer_i32(
3735 &self,
3736 index: u32,
3737 size: i32,
3738 data_type: u32,
3739 stride: i32,
3740 offset: i32,
3741 ) {
3742 let gl = &self.raw;
3743 gl.VertexAttribIPointer(
3744 index,
3745 size,
3746 data_type,
3747 stride,
3748 offset as *const std::ffi::c_void,
3749 );
3750 }
3751
3752 unsafe fn vertex_attrib_pointer_f64(
3753 &self,
3754 index: u32,
3755 size: i32,
3756 data_type: u32,
3757 stride: i32,
3758 offset: i32,
3759 ) {
3760 let gl = &self.raw;
3761 gl.VertexAttribLPointer(
3762 index,
3763 size,
3764 data_type,
3765 stride,
3766 offset as *const std::ffi::c_void,
3767 );
3768 }
3769
3770 unsafe fn vertex_attrib_format_f32(
3771 &self,
3772 index: u32,
3773 size: i32,
3774 data_type: u32,
3775 normalized: bool,
3776 relative_offset: u32,
3777 ) {
3778 let gl = &self.raw;
3779 gl.VertexAttribFormat(index, size, data_type, normalized as u8, relative_offset);
3780 }
3781
3782 unsafe fn vertex_attrib_format_i32(
3783 &self,
3784 index: u32,
3785 size: i32,
3786 data_type: u32,
3787 relative_offset: u32,
3788 ) {
3789 let gl = &self.raw;
3790 gl.VertexAttribIFormat(index, size, data_type, relative_offset);
3791 }
3792
3793 unsafe fn vertex_attrib_format_f64(
3794 &self,
3795 index: u32,
3796 size: i32,
3797 data_type: u32,
3798 relative_offset: u32,
3799 ) {
3800 let gl = &self.raw;
3801 gl.VertexAttribLFormat(index, size, data_type, relative_offset);
3802 }
3803
3804 unsafe fn vertex_attrib_1_f32(&self, index: u32, x: f32) {
3805 let gl = &self.raw;
3806 gl.VertexAttrib1f(index, x);
3807 }
3808
3809 unsafe fn vertex_attrib_2_f32(&self, index: u32, x: f32, y: f32) {
3810 let gl = &self.raw;
3811 gl.VertexAttrib2f(index, x, y);
3812 }
3813
3814 unsafe fn vertex_attrib_3_f32(&self, index: u32, x: f32, y: f32, z: f32) {
3815 let gl = &self.raw;
3816 gl.VertexAttrib3f(index, x, y, z);
3817 }
3818
3819 unsafe fn vertex_attrib_4_f32(&self, index: u32, x: f32, y: f32, z: f32, w: f32) {
3820 let gl = &self.raw;
3821 gl.VertexAttrib4f(index, x, y, z, w);
3822 }
3823
3824 unsafe fn vertex_attrib_4_i32(&self, index: u32, x: i32, y: i32, z: i32, w: i32) {
3825 let gl = &self.raw;
3826 gl.VertexAttribI4i(index, x, y, z, w);
3827 }
3828
3829 unsafe fn vertex_attrib_4_u32(&self, index: u32, x: u32, y: u32, z: u32, w: u32) {
3830 let gl = &self.raw;
3831 gl.VertexAttribI4ui(index, x, y, z, w);
3832 }
3833
3834 unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]) {
3835 let gl = &self.raw;
3836 gl.VertexAttrib1fv(index, v.as_ptr());
3837 }
3838
3839 unsafe fn vertex_attrib_2_f32_slice(&self, index: u32, v: &[f32]) {
3840 let gl = &self.raw;
3841 gl.VertexAttrib2fv(index, v.as_ptr());
3842 }
3843
3844 unsafe fn vertex_attrib_3_f32_slice(&self, index: u32, v: &[f32]) {
3845 let gl = &self.raw;
3846 gl.VertexAttrib3fv(index, v.as_ptr());
3847 }
3848
3849 unsafe fn vertex_attrib_4_f32_slice(&self, index: u32, v: &[f32]) {
3850 let gl = &self.raw;
3851 gl.VertexAttrib4fv(index, v.as_ptr());
3852 }
3853
3854 unsafe fn vertex_attrib_binding(&self, attrib_index: u32, binding_index: u32) {
3855 let gl = &self.raw;
3856 gl.VertexAttribBinding(attrib_index, binding_index);
3857 }
3858
3859 unsafe fn vertex_binding_divisor(&self, binding_index: u32, divisor: u32) {
3860 let gl = &self.raw;
3861 gl.VertexBindingDivisor(binding_index, divisor);
3862 }
3863
3864 unsafe fn viewport(&self, x: i32, y: i32, width: i32, height: i32) {
3865 let gl = &self.raw;
3866 gl.Viewport(x, y, width, height);
3867 }
3868
3869 unsafe fn viewport_f32_slice(&self, first: u32, count: i32, values: &[[f32; 4]]) {
3870 let gl = &self.raw;
3871 gl.ViewportArrayv(first, count, values.as_ptr() as *const f32);
3872 }
3873
3874 unsafe fn blend_equation(&self, mode: u32) {
3875 let gl = &self.raw;
3876 gl.BlendEquation(mode as u32);
3877 }
3878
3879 unsafe fn blend_equation_draw_buffer(&self, draw_buffer: u32, mode: u32) {
3880 let gl = &self.raw;
3881 gl.BlendEquationi(draw_buffer, mode as u32);
3882 }
3883
3884 unsafe fn blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32) {
3885 let gl = &self.raw;
3886 gl.BlendEquationSeparate(mode_rgb as u32, mode_alpha as u32);
3887 }
3888
3889 unsafe fn blend_equation_separate_draw_buffer(
3890 &self,
3891 draw_buffer: u32,
3892 mode_rgb: u32,
3893 mode_alpha: u32,
3894 ) {
3895 let gl = &self.raw;
3896 gl.BlendEquationSeparatei(draw_buffer, mode_rgb as u32, mode_alpha as u32);
3897 }
3898
3899 unsafe fn blend_func(&self, src: u32, dst: u32) {
3900 let gl = &self.raw;
3901 gl.BlendFunc(src as u32, dst as u32);
3902 }
3903
3904 unsafe fn blend_func_draw_buffer(&self, draw_buffer: u32, src: u32, dst: u32) {
3905 let gl = &self.raw;
3906 gl.BlendFunci(draw_buffer, src as u32, dst as u32);
3907 }
3908
3909 unsafe fn blend_func_separate(
3910 &self,
3911 src_rgb: u32,
3912 dst_rgb: u32,
3913 src_alpha: u32,
3914 dst_alpha: u32,
3915 ) {
3916 let gl = &self.raw;
3917 gl.BlendFuncSeparate(
3918 src_rgb as u32,
3919 dst_rgb as u32,
3920 src_alpha as u32,
3921 dst_alpha as u32,
3922 );
3923 }
3924
3925 unsafe fn blend_func_separate_draw_buffer(
3926 &self,
3927 draw_buffer: u32,
3928 src_rgb: u32,
3929 dst_rgb: u32,
3930 src_alpha: u32,
3931 dst_alpha: u32,
3932 ) {
3933 let gl = &self.raw;
3934 gl.BlendFuncSeparatei(
3935 draw_buffer,
3936 src_rgb as u32,
3937 dst_rgb as u32,
3938 src_alpha as u32,
3939 dst_alpha as u32,
3940 );
3941 }
3942
3943 unsafe fn stencil_func(&self, func: u32, reference: i32, mask: u32) {
3944 let gl = &self.raw;
3945 gl.StencilFunc(func as u32, reference, mask);
3946 }
3947
3948 unsafe fn stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32) {
3949 let gl = &self.raw;
3950 gl.StencilFuncSeparate(face as u32, func as u32, reference, mask);
3951 }
3952
3953 unsafe fn stencil_mask(&self, mask: u32) {
3954 let gl = &self.raw;
3955 gl.StencilMask(mask);
3956 }
3957
3958 unsafe fn stencil_mask_separate(&self, face: u32, mask: u32) {
3959 let gl = &self.raw;
3960 gl.StencilMaskSeparate(face as u32, mask);
3961 }
3962
3963 unsafe fn stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32) {
3964 let gl = &self.raw;
3965 gl.StencilOp(stencil_fail as u32, depth_fail as u32, pass as u32);
3966 }
3967
3968 unsafe fn stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32) {
3969 let gl = &self.raw;
3970 gl.StencilOpSeparate(
3971 face as u32,
3972 stencil_fail as u32,
3973 depth_fail as u32,
3974 pass as u32,
3975 );
3976 }
3977
3978 unsafe fn debug_message_control(
3979 &self,
3980 source: u32,
3981 msg_type: u32,
3982 severity: u32,
3983 ids: &[u32],
3984 enabled: bool,
3985 ) {
3986 let gl = &self.raw;
3987
3988 let ids_ptr = if ids.is_empty() {
3989 std::ptr::null()
3990 } else {
3991 ids.as_ptr()
3992 };
3993
3994 khr_fallback!(
3995 gl.DebugMessageControl_is_loaded,
3996 gl.DebugMessageControlKHR,
3997 gl.DebugMessageControl(
3998 source,
3999 msg_type,
4000 severity,
4001 ids.len() as i32,
4002 ids_ptr,
4003 enabled as u8,
4004 ),
4005 );
4006 }
4007
4008 unsafe fn debug_message_insert<S>(
4009 &self,
4010 source: u32,
4011 msg_type: u32,
4012 id: u32,
4013 severity: u32,
4014 msg: S,
4015 ) where
4016 S: AsRef<str>,
4017 {
4018 let gl = &self.raw;
4019 let message = msg.as_ref().as_bytes();
4020 let length = message.len() as i32;
4021 khr_fallback!(
4022 gl.DebugMessageInsert_is_loaded,
4023 gl.DebugMessageInsertKHR,
4024 gl.DebugMessageInsert(
4025 source,
4026 msg_type,
4027 id,
4028 severity,
4029 length,
4030 message.as_ptr() as *const native_gl::GLchar,
4031 ),
4032 );
4033 }
4034
4035 unsafe fn debug_message_callback<F>(&mut self, callback: F)
4036 where
4037 F: Fn(u32, u32, u32, u32, &str) + Send + Sync + 'static,
4038 {
4039 match self.debug_callback {
4040 Some(_) => {
4041 panic!("Debug callback already set");
4042 }
4043 None => {
4044 let trait_object: DebugCallback = Box::new(callback);
4045 let thin_ptr = Box::new(trait_object);
4046 let raw_ptr = Box::into_raw(thin_ptr) as *mut _ as *mut std::ffi::c_void;
4047
4048 let gl = &self.raw;
4049
4050 khr_fallback!(
4051 gl.DebugMessageCallback_is_loaded,
4052 gl.DebugMessageCallbackKHR,
4053 gl.DebugMessageCallback(Some(raw_debug_message_callback), raw_ptr),
4054 );
4055
4056 self.debug_callback = Some(DebugCallbackRawPtr { callback: raw_ptr });
4057 }
4058 }
4059 }
4060
4061 unsafe fn get_debug_message_log(&self, count: u32) -> Vec<DebugMessageLogEntry> {
4062 let ct = count as usize;
4063 let mut sources = Vec::with_capacity(ct);
4064 let mut types = Vec::with_capacity(ct);
4065 let mut ids = Vec::with_capacity(ct);
4066 let mut severities = Vec::with_capacity(ct);
4067 let mut lengths = Vec::with_capacity(ct);
4068 let buf_size = (count * MAX_DEBUG_MESSAGE_LENGTH) as i32;
4069 let mut message_log = Vec::with_capacity(buf_size as usize);
4070
4071 let gl = &self.raw;
4072 let received = khr_fallback!(
4073 gl.GetDebugMessageLog_is_loaded,
4074 gl.GetDebugMessageLogKHR,
4075 gl.GetDebugMessageLog(
4076 count,
4077 buf_size,
4078 sources.as_mut_ptr(),
4079 types.as_mut_ptr(),
4080 ids.as_mut_ptr(),
4081 severities.as_mut_ptr(),
4082 lengths.as_mut_ptr(),
4083 message_log.as_mut_ptr(),
4084 ),
4085 ) as usize;
4086
4087 sources.set_len(received);
4088 types.set_len(received);
4089 ids.set_len(received);
4090 severities.set_len(received);
4091 lengths.set_len(received);
4092 message_log.set_len(buf_size as usize);
4093
4094 let mut entries = Vec::new();
4095 let mut offset = 0;
4096 for i in 0..received {
4097 let message =
4098 std::ffi::CStr::from_ptr(message_log[offset..].as_ptr()).to_string_lossy();
4099 offset += lengths[i] as usize;
4100 entries.push(DebugMessageLogEntry {
4101 source: sources[i],
4102 msg_type: types[i],
4103 id: ids[i],
4104 severity: severities[i],
4105 message: message.to_string(),
4106 });
4107 }
4108
4109 entries
4110 }
4111
4112 unsafe fn push_debug_group<S>(&self, source: u32, id: u32, message: S)
4113 where
4114 S: AsRef<str>,
4115 {
4116 let gl = &self.raw;
4117 let msg = message.as_ref().as_bytes();
4118 let length = msg.len() as i32;
4119 khr_fallback!(
4120 gl.PushDebugGroup_is_loaded,
4121 gl.PushDebugGroupKHR,
4122 gl.PushDebugGroup(source, id, length, msg.as_ptr() as *const native_gl::GLchar),
4123 );
4124 }
4125
4126 unsafe fn pop_debug_group(&self) {
4127 let gl = &self.raw;
4128 khr_fallback!(
4129 gl.PopDebugGroup_is_loaded,
4130 gl.PopDebugGroupKHR,
4131 gl.PopDebugGroup(),
4132 );
4133 }
4134
4135 unsafe fn object_label<S>(&self, identifier: u32, name: u32, label: Option<S>)
4136 where
4137 S: AsRef<str>,
4138 {
4139 let gl = &self.raw;
4140
4141 match label {
4142 Some(l) => {
4143 let lbl = l.as_ref().as_bytes();
4144 let length = lbl.len() as i32;
4145 khr_fallback!(
4146 gl.ObjectLabel_is_loaded,
4147 gl.ObjectLabelKHR,
4148 gl.ObjectLabel(
4149 identifier,
4150 name,
4151 length,
4152 lbl.as_ptr() as *const native_gl::GLchar,
4153 ),
4154 );
4155 }
4156 None => {
4157 khr_fallback!(
4158 gl.ObjectLabel_is_loaded,
4159 gl.ObjectLabelKHR,
4160 gl.ObjectLabel(identifier, name, 0, std::ptr::null()),
4161 );
4162 }
4163 }
4164 }
4165
4166 unsafe fn get_object_label(&self, identifier: u32, name: u32) -> String {
4167 let gl = &self.raw;
4168 let mut len = 0;
4169 let mut label_buf = Vec::with_capacity(self.constants.max_label_length as usize);
4170 khr_fallback!(
4171 gl.GetObjectLabel_is_loaded,
4172 gl.GetObjectLabelKHR,
4173 gl.GetObjectLabel(
4174 identifier,
4175 name,
4176 self.constants.max_label_length,
4177 &mut len,
4178 label_buf.as_mut_ptr(),
4179 ),
4180 );
4181 label_buf.set_len(len as usize);
4182 std::ffi::CStr::from_ptr(label_buf.as_ptr())
4183 .to_str()
4184 .unwrap()
4185 .to_owned()
4186 }
4187
4188 unsafe fn object_ptr_label<S>(&self, sync: Self::Fence, label: Option<S>)
4189 where
4190 S: AsRef<str>,
4191 {
4192 let gl = &self.raw;
4193
4194 match label {
4195 Some(l) => {
4196 let lbl = l.as_ref().as_bytes();
4197 let length = lbl.len() as i32;
4198 khr_fallback!(
4199 gl.ObjectPtrLabel_is_loaded,
4200 gl.ObjectPtrLabelKHR,
4201 gl.ObjectPtrLabel(
4202 sync.0 as *mut std::ffi::c_void,
4203 length,
4204 lbl.as_ptr() as *const native_gl::GLchar,
4205 ),
4206 );
4207 }
4208 None => {
4209 khr_fallback!(
4210 gl.ObjectPtrLabel_is_loaded,
4211 gl.ObjectPtrLabelKHR,
4212 gl.ObjectPtrLabel(sync.0 as *mut std::ffi::c_void, 0, std::ptr::null()),
4213 );
4214 }
4215 }
4216 }
4217
4218 unsafe fn get_object_ptr_label(&self, sync: Self::Fence) -> String {
4219 let gl = &self.raw;
4220 let mut len = 0;
4221 let mut label_buf = Vec::with_capacity(self.constants.max_label_length as usize);
4222 khr_fallback!(
4223 gl.GetObjectPtrLabel_is_loaded,
4224 gl.GetObjectPtrLabelKHR,
4225 gl.GetObjectPtrLabel(
4226 sync.0 as *mut std::ffi::c_void,
4227 self.constants.max_label_length,
4228 &mut len,
4229 label_buf.as_mut_ptr(),
4230 ),
4231 );
4232 label_buf.set_len(len as usize);
4233 std::ffi::CStr::from_ptr(label_buf.as_ptr())
4234 .to_str()
4235 .unwrap()
4236 .to_owned()
4237 }
4238
4239 unsafe fn get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32> {
4240 let gl = &self.raw;
4241 let name = CString::new(name).unwrap();
4242 let index = gl.GetUniformBlockIndex(program.0.get(), name.as_ptr());
4243 if index == INVALID_INDEX {
4244 None
4245 } else {
4246 Some(index)
4247 }
4248 }
4249
4250 unsafe fn get_uniform_indices(
4251 &self,
4252 program: Self::Program,
4253 names: &[&str],
4254 ) -> Vec<Option<u32>> {
4255 let gl = &self.raw;
4256 let c_names = names
4257 .iter()
4258 .map(|&name| CString::new(name).unwrap())
4259 .collect::<Vec<_>>();
4260 let c_name_ptrs = c_names.iter().map(|name| name.as_ptr()).collect::<Vec<_>>();
4261
4262 let count = names.len();
4263 let mut indices = vec![0; count];
4264 gl.GetUniformIndices(
4265 program.0.get(),
4266 count as _,
4267 c_name_ptrs.as_ptr(),
4268 indices.as_mut_ptr(),
4269 );
4270 indices
4271 .iter()
4272 .map(|&index| {
4273 if index == INVALID_INDEX {
4274 None
4275 } else {
4276 Some(index)
4277 }
4278 })
4279 .collect()
4280 }
4281
4282 unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) {
4283 let gl = &self.raw;
4284 gl.UniformBlockBinding(program.0.get(), index, binding);
4285 }
4286
4287 unsafe fn get_shader_storage_block_index(
4288 &self,
4289 program: Self::Program,
4290 name: &str,
4291 ) -> Option<u32> {
4292 let gl = &self.raw;
4293 let name = CString::new(name).unwrap();
4294 let index =
4295 gl.GetProgramResourceIndex(program.0.get(), SHADER_STORAGE_BLOCK, name.as_ptr());
4296 if index == INVALID_INDEX {
4297 None
4298 } else {
4299 Some(index)
4300 }
4301 }
4302
4303 unsafe fn shader_storage_block_binding(
4304 &self,
4305 program: Self::Program,
4306 index: u32,
4307 binding: u32,
4308 ) {
4309 let gl = &self.raw;
4310 gl.ShaderStorageBlockBinding(program.0.get(), index, binding);
4311 }
4312
4313 unsafe fn read_buffer(&self, src: u32) {
4314 let gl = &self.raw;
4315 gl.ReadBuffer(src);
4316 }
4317
4318 unsafe fn named_framebuffer_read_buffer(
4319 &self,
4320 framebuffer: Option<Self::Framebuffer>,
4321 src: u32,
4322 ) {
4323 let gl = &self.raw;
4324 gl.NamedFramebufferReadBuffer(framebuffer.map(|f| f.0.get()).unwrap_or(0), src);
4325 }
4326
4327 unsafe fn read_pixels(
4328 &self,
4329 x: i32,
4330 y: i32,
4331 width: i32,
4332 height: i32,
4333 format: u32,
4334 gltype: u32,
4335 pixels: PixelPackData,
4336 ) {
4337 let gl = &self.raw;
4338 gl.ReadPixels(
4339 x,
4340 y,
4341 width,
4342 height,
4343 format,
4344 gltype,
4345 match pixels {
4346 PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void,
4347 PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut std::ffi::c_void,
4348 PixelPackData::Slice(None) => ptr::null_mut(),
4349 },
4350 );
4351 }
4352
4353 unsafe fn begin_query(&self, target: u32, query: Self::Query) {
4354 let gl = &self.raw;
4355 if gl.BeginQuery_is_loaded() {
4356 gl.BeginQuery(target, query.0.get());
4357 } else {
4358 gl.BeginQueryEXT(target, query.0.get());
4359 }
4360 }
4361
4362 unsafe fn end_query(&self, target: u32) {
4363 let gl = &self.raw;
4364 if gl.EndQuery_is_loaded() {
4365 gl.EndQuery(target);
4366 } else {
4367 gl.EndQueryEXT(target);
4368 }
4369 }
4370
4371 unsafe fn query_counter(&self, query: Self::Query, target: u32) {
4372 let gl = &self.raw;
4373 if gl.QueryCounter_is_loaded() {
4374 gl.QueryCounter(query.0.get(), target);
4375 } else {
4376 gl.QueryCounterEXT(query.0.get(), target);
4377 }
4378 }
4379
4380 unsafe fn get_query_parameter_u32(&self, query: Self::Query, parameter: u32) -> u32 {
4381 let gl = &self.raw;
4382 let mut value = 0;
4383 if gl.GetQueryBufferObjectiv_is_loaded() {
4384 gl.GetQueryObjectuiv(query.0.get(), parameter, &mut value);
4385 } else {
4386 gl.GetQueryObjectuivEXT(query.0.get(), parameter, &mut value);
4387 }
4388 value
4389 }
4390
4391 unsafe fn get_query_parameter_u64(&self, query: Self::Query, parameter: u32) -> u64 {
4392 let gl = &self.raw;
4393 let mut value = 0;
4394 if gl.GetQueryBufferObjectiv_is_loaded() {
4395 gl.GetQueryObjectui64v(query.0.get(), parameter, &mut value);
4396 } else {
4397 gl.GetQueryObjectui64vEXT(query.0.get(), parameter, &mut value);
4398 }
4399 value
4400 }
4401
4402 unsafe fn get_query_parameter_u64_with_offset(
4403 &self,
4404 query: Self::Query,
4405 parameter: u32,
4406 offset: usize,
4407 ) {
4408 let gl = &self.raw;
4409 if gl.GetQueryObjectui64v_is_loaded() {
4410 gl.GetQueryObjectui64v(query.0.get(), parameter, offset as *mut _);
4411 } else {
4412 gl.GetQueryObjectui64vEXT(query.0.get(), parameter, offset as *mut _);
4413 }
4414 }
4415
4416 unsafe fn create_transform_feedback(&self) -> Result<Self::TransformFeedback, String> {
4417 let gl = &self.raw;
4418 let mut name = 0;
4419 gl.GenTransformFeedbacks(1, &mut name);
4420 NonZeroU32::new(name)
4421 .map(NativeTransformFeedback)
4422 .ok_or_else(|| String::from("Unable to create TransformFeedback object"))
4423 }
4424
4425 unsafe fn is_transform_feedback(&self, transform_feedback: Self::TransformFeedback) -> bool {
4426 let gl = &self.raw;
4427 gl.IsTransformFeedback(transform_feedback.0.get()) != 0
4428 }
4429
4430 unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) {
4431 let gl = &self.raw;
4432 gl.DeleteTransformFeedbacks(1, &transform_feedback.0.get());
4433 }
4434
4435 unsafe fn bind_transform_feedback(
4436 &self,
4437 target: u32,
4438 transform_feedback: Option<Self::TransformFeedback>,
4439 ) {
4440 let gl = &self.raw;
4441 gl.BindTransformFeedback(target, transform_feedback.map(|tf| tf.0.get()).unwrap_or(0));
4442 }
4443
4444 unsafe fn begin_transform_feedback(&self, primitive_mode: u32) {
4445 let gl = &self.raw;
4446 gl.BeginTransformFeedback(primitive_mode);
4447 }
4448
4449 unsafe fn end_transform_feedback(&self) {
4450 let gl = &self.raw;
4451 gl.EndTransformFeedback();
4452 }
4453
4454 unsafe fn pause_transform_feedback(&self) {
4455 let gl = &self.raw;
4456 gl.PauseTransformFeedback();
4457 }
4458
4459 unsafe fn resume_transform_feedback(&self) {
4460 let gl = &self.raw;
4461 gl.ResumeTransformFeedback();
4462 }
4463
4464 unsafe fn transform_feedback_varyings(
4465 &self,
4466 program: Self::Program,
4467 varyings: &[&str],
4468 buffer_mode: u32,
4469 ) {
4470 let gl = &self.raw;
4471
4472 let strings: Vec<CString> = varyings
4473 .iter()
4474 .copied()
4475 .map(CString::new)
4476 .collect::<Result<_, _>>()
4477 .unwrap();
4478 let varyings: Vec<_> = strings.iter().map(|c_str| c_str.as_ptr()).collect();
4479
4480 gl.TransformFeedbackVaryings(
4481 program.0.get(),
4482 varyings.len() as i32,
4483 varyings.as_ptr(),
4484 buffer_mode,
4485 );
4486 }
4487
4488 unsafe fn get_transform_feedback_varying(
4489 &self,
4490 program: Self::Program,
4491 index: u32,
4492 ) -> Option<ActiveTransformFeedback> {
4493 let gl = &self.raw;
4494
4495 const max_name_size: usize = 256;
4496 let mut name_bytes = [0; max_name_size];
4497
4498 let mut size = 0;
4499 let mut tftype = 0;
4500
4501 gl.GetTransformFeedbackVarying(
4502 program.0.get(),
4503 index,
4504 name_bytes.len() as i32,
4505 std::ptr::null_mut(),
4506 &mut size,
4507 &mut tftype,
4508 name_bytes.as_mut_ptr(),
4509 );
4510
4511 let name = CStr::from_ptr(name_bytes.as_mut_ptr())
4512 .to_string_lossy()
4513 .into_owned();
4514
4515 Some(ActiveTransformFeedback { size, tftype, name })
4516 }
4517
4518 unsafe fn memory_barrier(&self, barriers: u32) {
4519 let gl = &self.raw;
4520 gl.MemoryBarrier(barriers);
4521 }
4522
4523 unsafe fn memory_barrier_by_region(&self, barriers: u32) {
4524 let gl = &self.raw;
4525 gl.MemoryBarrierByRegion(barriers);
4526 }
4527
4528 unsafe fn bind_image_texture(
4529 &self,
4530 unit: u32,
4531 texture: Option<Self::Texture>,
4532 level: i32,
4533 layered: bool,
4534 layer: i32,
4535 access: u32,
4536 format: u32,
4537 ) {
4538 let gl = &self.raw;
4539 gl.BindImageTexture(
4540 unit,
4541 texture.map(|tex| tex.0.get()).unwrap_or(0),
4542 level,
4543 layered as u8,
4544 layer,
4545 access,
4546 format,
4547 );
4548 }
4549 unsafe fn get_active_uniform_block_parameter_i32(
4550 &self,
4551 program: Self::Program,
4552 uniform_block_index: u32,
4553 parameter: u32,
4554 ) -> i32 {
4555 let gl = &self.raw;
4556 let mut value = 0;
4557 gl.GetActiveUniformBlockiv(program.0.get(), uniform_block_index, parameter, &mut value);
4558 value
4559 }
4560
4561 unsafe fn get_active_uniform_block_parameter_i32_slice(
4562 &self,
4563 program: Self::Program,
4564 uniform_block_index: u32,
4565 parameter: u32,
4566 out: &mut [i32],
4567 ) {
4568 let gl = &self.raw;
4569 gl.GetActiveUniformBlockiv(
4570 program.0.get(),
4571 uniform_block_index,
4572 parameter,
4573 out.as_mut_ptr(),
4574 );
4575 }
4576 unsafe fn get_active_uniform_block_name(
4577 &self,
4578 program: Self::Program,
4579 uniform_block_index: u32,
4580 ) -> String {
4581 let gl = &self.raw;
4582
4583 let len = self.get_active_uniform_block_parameter_i32(
4588 program,
4589 uniform_block_index,
4590 crate::UNIFORM_BLOCK_NAME_LENGTH,
4591 );
4592 let len = if gl.GetError() == crate::NO_ERROR && len > 0 {
4593 len as usize
4594 } else {
4595 256
4596 };
4597
4598 let mut buffer = vec![0; len];
4599 let mut length = 0;
4600 gl.GetActiveUniformBlockName(
4601 program.0.get(),
4602 uniform_block_index,
4603 buffer.len() as _,
4604 &mut length,
4605 buffer.as_mut_ptr(),
4606 );
4607
4608 if length > 0 {
4609 assert_eq!(
4610 std::mem::size_of::<u8>(),
4611 std::mem::size_of::<native_gl::GLchar>(),
4612 "This operation is only safe in systems in which the length of \
4613 a GLchar is the same as that of an u8"
4614 );
4615 assert_eq!(
4616 std::mem::align_of::<u8>(),
4617 std::mem::align_of::<native_gl::GLchar>(),
4618 "This operation is only safe in systems in which the alignment \
4619 of a GLchar is the same as that of an u8"
4620 );
4621 let buffer = std::slice::from_raw_parts(
4622 buffer.as_ptr() as *const u8,
4623 (length as usize + 1).min(buffer.len()),
4624 );
4625
4626 let name = CStr::from_bytes_with_nul(&buffer[..])
4627 .unwrap()
4628 .to_str()
4629 .unwrap()
4630 .to_owned();
4631
4632 name
4633 } else {
4634 String::from("")
4635 }
4636 }
4637
4638 unsafe fn max_shader_compiler_threads(&self, count: u32) {
4639 let gl = &self.raw;
4640 if gl.MaxShaderCompilerThreadsKHR_is_loaded() {
4641 gl.MaxShaderCompilerThreadsKHR(count);
4642 } else {
4643 gl.MaxShaderCompilerThreadsARB(count);
4644 }
4645 }
4646
4647 unsafe fn hint(&self, target: u32, mode: u32) {
4648 let gl = &self.raw;
4649 gl.Hint(target, mode);
4650 }
4651
4652 unsafe fn sample_coverage(&self, value: f32, invert: bool) {
4653 let gl = &self.raw;
4654 gl.SampleCoverage(value, invert as u8);
4655 }
4656
4657 unsafe fn get_internal_format_i32_slice(
4658 &self,
4659 target: u32,
4660 internal_format: u32,
4661 pname: u32,
4662 result: &mut [i32],
4663 ) {
4664 let gl = &self.raw;
4665 gl.GetInternalformativ(
4666 target,
4667 internal_format,
4668 pname,
4669 result.len() as _,
4670 result.as_mut_ptr(),
4671 )
4672 }
4673}
4674
4675impl Drop for Context {
4676 fn drop(&mut self) {
4677 match self.debug_callback.take() {
4678 Some(_) => {
4679 unsafe {
4681 let gl = &self.raw;
4682 if gl.DebugMessageCallback_is_loaded() {
4683 gl.DebugMessageCallback(None, std::ptr::null());
4684 } else {
4685 gl.DebugMessageCallbackKHR(None, std::ptr::null());
4686 }
4687 }
4688 }
4689 None => {}
4690 }
4691 }
4692}
4693
4694extern "system" fn raw_debug_message_callback(
4695 source: u32,
4696 gltype: u32,
4697 id: u32,
4698 severity: u32,
4699 length: i32,
4700 message: *const native_gl::GLchar,
4701 user_param: *mut std::ffi::c_void,
4702) {
4703 let _result = std::panic::catch_unwind(move || unsafe {
4704 let callback: &DebugCallback = &*(user_param as *const DebugCallback);
4705 let slice = std::slice::from_raw_parts(message as *const u8, length as usize);
4706 let msg = String::from_utf8_lossy(slice);
4707 (callback)(source, gltype, id, severity, &msg);
4708 });
4709}
4710
4711#[cfg(test)]
4712mod tests {
4713 use super::*;
4714
4715 #[test]
4716 fn test_send() {
4717 fn assert_send<T: Send>() {}
4718 assert_send::<Context>();
4719 }
4720
4721 #[test]
4722 fn test_sync() {
4723 fn assert_sync<T: Sync>() {}
4724 assert_sync::<Context>();
4725 }
4726}