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