1use super::*;
2use crate::{gl46 as native_gl, version::Version};
3use std::ffi::CStr;
4use std::{collections::HashSet, ffi::CString, num::NonZeroU32};
5use crate::gl46::GLuint;
6
7#[derive(Default)]
8struct Constants {
9 max_label_length: i32,
10}
11
12pub struct Context {
13 raw: native_gl::GlFns,
14 extensions: HashSet<String>,
15 constants: Constants,
16 version: Version,
17}
18
19impl Context {
20 pub unsafe fn from_loader_function<F>(mut loader_function: F) -> Self
21 where
22 F: FnMut(&str) -> *const std::os::raw::c_void,
23 {
24 let raw: native_gl::GlFns =
30 native_gl::GlFns::load_with(|p: *const std::os::raw::c_char| {
31 let c_str = std::ffi::CStr::from_ptr(p);
32 loader_function(c_str.to_str().unwrap()) as *mut std::os::raw::c_void
33 });
34
35 let raw_string = raw.GetString(VERSION);
37
38 if raw_string.is_null() {
39 panic!("Reading GL_VERSION failed. Make sure there is a valid GL context currently active.")
40 }
41
42 let raw_version = std::ffi::CStr::from_ptr(raw_string as *const native_gl::GLchar)
43 .to_str()
44 .unwrap()
45 .to_owned();
46 let version = Version::parse(&raw_version).unwrap();
47
48 let mut context = Self {
50 raw,
51 extensions: HashSet::new(),
52 constants: Constants::default(),
53 version,
54 };
55
56 if (context.version >= Version::new(3, 0, None, String::from("")))
58 || (context.version >= Version::new_embedded(3, 0, String::from("")))
59 {
60 let num_extensions = context.get_parameter_i32(NUM_EXTENSIONS);
61 for i in 0..num_extensions {
62 let extension_name = context.get_parameter_indexed_string(EXTENSIONS, i as u32);
63 context.extensions.insert(extension_name);
64 }
65 } else {
66 context.extensions.extend(
68 context
69 .get_parameter_string(EXTENSIONS)
70 .split(' ')
71 .map(|s| s.to_string()),
72 );
73 };
74
75 context.constants.max_label_length = if context.supports_debug() {
78 context.get_parameter_i32(MAX_LABEL_LENGTH)
79 } else {
80 0
81 };
82
83 context
84 }
85
86 pub unsafe fn create_texture_from_gl_name(gl_name: native_gl::GLuint) -> NativeTexture {
91 NativeTexture(non_zero_gl_name(gl_name))
92 }
93
94 pub unsafe fn create_framebuffer_from_gl_name(gl_name: native_gl::GLuint) -> NativeFramebuffer {
99 NativeFramebuffer(non_zero_gl_name(gl_name))
100 }
101}
102
103impl std::fmt::Debug for Context {
104 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
105 write!(f, "Native_GL_Context")
106 }
107}
108
109fn non_zero_gl_name(value: native_gl::GLuint) -> NonZeroU32 {
110 NonZeroU32::new(value as u32).expect("expected non-zero GL name")
111}
112
113#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
114pub struct NativeShader(pub NonZeroU32);
115
116#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
117pub struct NativeProgram(pub NonZeroU32);
118
119#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
120pub struct NativeBuffer(pub NonZeroU32);
121
122#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
123pub struct NativeVertexArray(pub NonZeroU32);
124
125#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
126pub struct NativeTexture(pub NonZeroU32);
127
128#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
129pub struct NativeSampler(pub NonZeroU32);
130
131#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
132pub struct NativeFence(pub native_gl::GLsync);
133
134#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
135pub struct NativeFramebuffer(pub NonZeroU32);
136
137#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
138pub struct NativeRenderbuffer(pub NonZeroU32);
139
140#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
141pub struct NativeQuery(pub NonZeroU32);
142
143#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
144pub struct NativeUniformLocation(pub native_gl::GLuint);
145
146#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
147pub struct NativeTransformFeedback(pub NonZeroU32);
148
149impl HasContext for Context {
150 type Shader = NativeShader;
151 type Program = NativeProgram;
152 type Buffer = NativeBuffer;
153 type VertexArray = NativeVertexArray;
154 type Texture = NativeTexture;
155 type Sampler = NativeSampler;
156 type Fence = NativeFence;
157 type Framebuffer = NativeFramebuffer;
158 type Renderbuffer = NativeRenderbuffer;
159 type Query = NativeQuery;
160 type UniformLocation = NativeUniformLocation;
161 type TransformFeedback = NativeTransformFeedback;
162
163 fn supported_extensions(&self) -> &HashSet<String> {
164 &self.extensions
165 }
166
167 fn supports_debug(&self) -> bool {
168 self.extensions.contains("GL_KHR_debug")
169 }
170
171 fn version(&self) -> &Version {
172 &self.version
173 }
174
175 unsafe fn create_framebuffer(&self) -> Result<Self::Framebuffer, String> {
176 let gl = &self.raw;
177 let mut name = 0;
178 gl.GenFramebuffers(1, &mut name);
179 Ok(NativeFramebuffer(non_zero_gl_name(name)))
180 }
181
182 unsafe fn is_framebuffer(&self, framebuffer: Self::Framebuffer) -> bool {
183 let gl = &self.raw;
184 gl.IsFramebuffer(framebuffer.0.get()) != 0
185 }
186
187 unsafe fn create_query(&self) -> Result<Self::Query, String> {
188 let gl = &self.raw;
189 let mut name = 0;
190 gl.GenQueries(1, &mut name);
191 Ok(NativeQuery(non_zero_gl_name(name)))
192 }
193
194 unsafe fn create_renderbuffer(&self) -> Result<Self::Renderbuffer, String> {
195 let gl = &self.raw;
196 let mut name = 0;
197 gl.GenRenderbuffers(1, &mut name);
198 Ok(NativeRenderbuffer(non_zero_gl_name(name)))
199 }
200
201 unsafe fn is_renderbuffer(&self, renderbuffer: Self::Renderbuffer) -> bool {
202 let gl = &self.raw;
203 gl.IsRenderbuffer(renderbuffer.0.get()) != 0
204 }
205
206 unsafe fn create_sampler(&self) -> Result<Self::Sampler, String> {
207 let gl = &self.raw;
208 let mut name = 0;
209 gl.GenSamplers(1, &mut name);
210 Ok(NativeSampler(non_zero_gl_name(name)))
211 }
212
213 unsafe fn create_shader(&self, shader_type: u32) -> Result<Self::Shader, String> {
214 let gl = &self.raw;
215 Ok(NativeShader(non_zero_gl_name(
216 gl.CreateShader(shader_type as u32),
217 )))
218 }
219
220 unsafe fn is_shader(&self, shader: Self::Shader) -> bool {
221 let gl = &self.raw;
222 gl.IsShader(shader.0.get()) != 0
223 }
224
225 unsafe fn create_texture(&self) -> Result<Self::Texture, String> {
226 let gl = &self.raw;
227 let mut name = 0;
228 gl.GenTextures(1, &mut name);
229 Ok(NativeTexture(non_zero_gl_name(name)))
230 }
231
232 unsafe fn create_named_texture(&self, target: u32) -> Result<Self::Texture, String> {
233 let gl = &self.raw;
234 let mut name = 0;
235 gl.CreateTextures(target, 1, &mut name);
236 Ok(NativeTexture(non_zero_gl_name(name)))
237 }
238
239 unsafe fn is_texture(&self, texture: Self::Texture) -> bool {
240 let gl = &self.raw;
241 gl.IsTexture(texture.0.get()) != 0
242 }
243
244 unsafe fn delete_shader(&self, shader: Self::Shader) {
245 let gl = &self.raw;
246 gl.DeleteShader(shader.0.get());
247 }
248
249 unsafe fn shader_source(&self, shader: Self::Shader, source: &str) {
250 let gl = &self.raw;
251 gl.ShaderSource(
252 shader.0.get(),
253 1,
254 &(source.as_ptr() as *const native_gl::GLchar),
255 &(source.len() as native_gl::GLint),
256 );
257 }
258
259 unsafe fn compile_shader(&self, shader: Self::Shader) {
260 let gl = &self.raw;
261 gl.CompileShader(shader.0.get());
262 }
263
264 unsafe fn get_shader_compile_status(&self, shader: Self::Shader) -> bool {
265 let gl = &self.raw;
266 let mut status = 0;
267 gl.GetShaderiv(shader.0.get(), COMPILE_STATUS, &mut status);
268 1 == status
269 }
270
271 unsafe fn get_shader_info_log(&self, shader: Self::Shader) -> String {
272 let gl = &self.raw;
273 let mut length = 0;
274 gl.GetShaderiv(shader.0.get(), INFO_LOG_LENGTH, &mut length);
275 if length > 0 {
276 let mut log = String::with_capacity(length as usize);
277 log.extend(std::iter::repeat('\0').take(length as usize));
278 gl.GetShaderInfoLog(
279 shader.0.get(),
280 length,
281 &mut length,
282 (&log[..]).as_ptr() as *mut native_gl::GLchar,
283 );
284 log.truncate(length as usize);
285 log
286 } else {
287 String::from("")
288 }
289 }
290
291 unsafe fn get_tex_image(
292 &self,
293 target: u32,
294 level: i32,
295 format: u32,
296 ty: u32,
297 pixels: PixelPackData,
298 ) {
299 let gl = &self.raw;
300 gl.GetTexImage(
301 target,
302 level,
303 format,
304 ty,
305 match pixels {
306 PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void,
307 PixelPackData::Slice(data) => data.as_mut_ptr() as *mut std::ffi::c_void,
308 },
309 );
310 }
311
312 unsafe fn create_program(&self) -> Result<Self::Program, String> {
313 let gl = &self.raw;
314 Ok(NativeProgram(non_zero_gl_name(gl.CreateProgram())))
315 }
316
317 unsafe fn is_program(&self, program: Self::Program) -> bool {
318 let gl = &self.raw;
319 gl.IsProgram(program.0.get()) != 0
320 }
321
322 unsafe fn delete_program(&self, program: Self::Program) {
323 let gl = &self.raw;
324 gl.DeleteProgram(program.0.get());
325 }
326
327 unsafe fn attach_shader(&self, program: Self::Program, shader: Self::Shader) {
328 let gl = &self.raw;
329 gl.AttachShader(program.0.get(), shader.0.get());
330 }
331
332 unsafe fn detach_shader(&self, program: Self::Program, shader: Self::Shader) {
333 let gl = &self.raw;
334 gl.DetachShader(program.0.get(), shader.0.get());
335 }
336
337 unsafe fn link_program(&self, program: Self::Program) {
338 let gl = &self.raw;
339 gl.LinkProgram(program.0.get());
340 }
341
342 unsafe fn get_program_link_status(&self, program: Self::Program) -> bool {
343 let gl = &self.raw;
344 let mut status = 0;
345 gl.GetProgramiv(program.0.get(), LINK_STATUS, &mut status);
346 1 == status
347 }
348
349 unsafe fn get_program_info_log(&self, program: Self::Program) -> String {
350 let gl = &self.raw;
351 let mut length = 0;
352 gl.GetProgramiv(program.0.get(), INFO_LOG_LENGTH, &mut length);
353 if length > 0 {
354 let mut log = String::with_capacity(length as usize);
355 log.extend(std::iter::repeat('\0').take(length as usize));
356 gl.GetProgramInfoLog(
357 program.0.get(),
358 length,
359 &mut length,
360 (&log[..]).as_ptr() as *mut native_gl::GLchar,
361 );
362 log.truncate(length as usize);
363 log
364 } else {
365 String::from("")
366 }
367 }
368
369 unsafe fn get_active_uniforms(&self, program: Self::Program) -> u32 {
370 let gl = &self.raw;
371 let mut count = 0;
372 gl.GetProgramiv(program.0.get(), ACTIVE_UNIFORMS, &mut count);
373 count as u32
374 }
375
376 unsafe fn get_active_uniform(
377 &self,
378 program: Self::Program,
379 index: u32,
380 ) -> Option<ActiveUniform> {
381 let gl = &self.raw;
382 let mut uniform_max_size = 0;
383 gl.GetProgramiv(
384 program.0.get(),
385 ACTIVE_UNIFORM_MAX_LENGTH,
386 &mut uniform_max_size,
387 );
388
389 let mut name = String::with_capacity(uniform_max_size as usize);
390 name.extend(std::iter::repeat('\0').take(uniform_max_size as usize));
391 let mut length = 0;
392 let mut size = 0;
393 let mut utype = 0;
394 gl.GetActiveUniform(
395 program.0.get(),
396 index,
397 uniform_max_size,
398 &mut length,
399 &mut size,
400 &mut utype,
401 name.as_ptr() as *mut native_gl::GLchar,
402 );
403 name.truncate(length as usize);
404
405 Some(ActiveUniform { size, utype, name })
406 }
407
408 unsafe fn use_program(&self, program: Option<Self::Program>) {
409 let gl = &self.raw;
410 gl.UseProgram(program.map(|p| p.0.get()).unwrap_or(0));
411 }
412
413 unsafe fn create_buffer(&self) -> Result<Self::Buffer, String> {
414 let gl = &self.raw;
415 let mut buffer = 0;
416 gl.GenBuffers(1, &mut buffer);
417 Ok(NativeBuffer(non_zero_gl_name(buffer)))
418 }
419
420 unsafe fn create_named_buffer(&self) -> Result<Self::Buffer, String> {
421 let gl = &self.raw;
422 let mut buffer = 0;
423 gl.CreateBuffers(1, &mut buffer);
424 Ok(NativeBuffer(non_zero_gl_name(buffer)))
425 }
426
427 unsafe fn is_buffer(&self, buffer: Self::Buffer) -> bool {
428 let gl = &self.raw;
429 gl.IsBuffer(buffer.0.get()) != 0
430 }
431
432 unsafe fn bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>) {
433 let gl = &self.raw;
434 gl.BindBuffer(target, buffer.map(|b| b.0.get()).unwrap_or(0));
435 }
436
437 unsafe fn bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>) {
438 let gl = &self.raw;
439 gl.BindBufferBase(target, index, buffer.map(|b| b.0.get()).unwrap_or(0));
440 }
441
442 unsafe fn bind_buffer_range(
443 &self,
444 target: u32,
445 index: u32,
446 buffer: Option<Self::Buffer>,
447 offset: i32,
448 size: i32,
449 ) {
450 let gl = &self.raw;
451 gl.BindBufferRange(
452 target,
453 index,
454 buffer.map(|b| b.0.get()).unwrap_or(0),
455 offset as isize,
456 size as isize,
457 );
458 }
459
460 unsafe fn bind_vertex_buffer(
461 &self,
462 binding_index: u32,
463 buffer: Option<Buffer>,
464 offset: i32,
465 stride: i32,
466 ) {
467 let gl = &self.raw;
468 gl.BindVertexBuffer(
469 binding_index,
470 buffer.map(|b| b.0.get()).unwrap_or(0),
471 offset as isize,
472 stride,
473 );
474 }
475
476 unsafe fn bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>) {
477 let gl = &self.raw;
478 gl.BindFramebuffer(target, framebuffer.map(|fb| fb.0.get()).unwrap_or(0));
479 }
480
481 unsafe fn bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>) {
482 let gl = &self.raw;
483 gl.BindRenderbuffer(target, renderbuffer.map(|rb| rb.0.get()).unwrap_or(0));
484 }
485
486 unsafe fn blit_framebuffer(
487 &self,
488 src_x0: i32,
489 src_y0: i32,
490 src_x1: i32,
491 src_y1: i32,
492 dst_x0: i32,
493 dst_y0: i32,
494 dst_x1: i32,
495 dst_y1: i32,
496 mask: u32,
497 filter: u32,
498 ) {
499 let gl = &self.raw;
500 gl.BlitFramebuffer(
501 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
502 );
503 }
504
505 unsafe fn create_vertex_array(&self) -> Result<Self::VertexArray, String> {
506 let gl = &self.raw;
507 let mut vertex_array = 0;
508 gl.GenVertexArrays(1, &mut vertex_array);
509 Ok(NativeVertexArray(non_zero_gl_name(vertex_array)))
510 }
511
512 unsafe fn delete_vertex_array(&self, vertex_array: Self::VertexArray) {
513 let gl = &self.raw;
514 gl.DeleteVertexArrays(1, &vertex_array.0.get());
515 }
516
517 unsafe fn bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>) {
518 let gl = &self.raw;
519 gl.BindVertexArray(vertex_array.map(|va| va.0.get()).unwrap_or(0));
520 }
521
522 unsafe fn clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
523 let gl = &self.raw;
524 gl.ClearColor(red, green, blue, alpha);
525 }
526
527 unsafe fn supports_f64_precision() -> bool {
528 true
530 }
531
532 unsafe fn clear_depth_f64(&self, depth: f64) {
533 let gl = &self.raw;
534 gl.ClearDepth(depth);
535 }
536
537 unsafe fn clear_depth_f32(&self, depth: f32) {
538 let gl = &self.raw;
539 gl.ClearDepthf(depth);
540 }
541
542 unsafe fn clear_stencil(&self, stencil: i32) {
543 let gl = &self.raw;
544 gl.ClearStencil(stencil);
545 }
546
547 unsafe fn clear(&self, mask: u32) {
548 let gl = &self.raw;
549 gl.Clear(mask);
550 }
551
552 unsafe fn patch_parameter_i32(&self, parameter: u32, value: i32) {
553 let gl = &self.raw;
554 gl.PatchParameteri(parameter, value);
555 }
556
557 unsafe fn pixel_store_i32(&self, parameter: u32, value: i32) {
558 let gl = &self.raw;
559 gl.PixelStorei(parameter, value);
560 }
561
562 unsafe fn pixel_store_bool(&self, parameter: u32, value: bool) {
563 let gl = &self.raw;
564 gl.PixelStorei(parameter, value as i32);
565 }
566
567 unsafe fn bind_frag_data_location(
568 &self,
569 program: Self::Program,
570 color_number: u32,
571 name: &str,
572 ) {
573 let gl = &self.raw;
574 gl.BindFragDataLocation(
575 program.0.get(),
576 color_number,
577 name.as_ptr() as *const native_gl::GLchar,
578 );
579 }
580
581 unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32) {
582 let gl = &self.raw;
583 gl.BufferData(target, size as isize, std::ptr::null(), usage);
584 }
585
586 unsafe fn buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32) {
587 let gl = &self.raw;
588 gl.BufferData(
589 target,
590 data.len() as isize,
591 data.as_ptr() as *const std::ffi::c_void,
592 usage,
593 );
594 }
595
596 unsafe fn named_buffer_data_u8_slice(&self, buffer: Self::Buffer, data: &[u8], usage: u32) {
597 let gl = &self.raw;
598 gl.NamedBufferData(
599 buffer.0.get(),
600 data.len() as isize,
601 data.as_ptr() as *const std::ffi::c_void,
602 usage,
603 );
604 }
605
606 unsafe fn buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8]) {
607 let gl = &self.raw;
608 gl.BufferSubData(
609 target,
610 offset as isize,
611 src_data.len() as isize,
612 src_data.as_ptr() as *const std::ffi::c_void,
613 );
614 }
615
616 unsafe fn get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8]) {
617 let gl = &self.raw;
618 gl.GetBufferSubData(
619 target,
620 offset as isize,
621 dst_data.len() as isize,
622 dst_data.as_mut_ptr() as *mut std::ffi::c_void,
623 );
624 }
625
626 unsafe fn buffer_storage(&self, target: u32, size: i32, data: Option<&[u8]>, flags: u32) {
627 let gl = &self.raw;
628 let size = size as isize;
629 let data = data.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void;
630 if gl.BufferStorage_is_loaded() {
631 gl.BufferStorage(target, size, data, flags);
632 } else {
633 gl.BufferStorageEXT(target, size, data, flags);
634 }
635 }
636
637 unsafe fn check_framebuffer_status(&self, target: u32) -> u32 {
638 let gl = &self.raw;
639 gl.CheckFramebufferStatus(target)
640 }
641
642 unsafe fn clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &[i32]) {
643 let gl = &self.raw;
644 gl.ClearBufferiv(target, draw_buffer as i32, values.as_ptr());
645 }
646
647 unsafe fn clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &[u32]) {
648 let gl = &self.raw;
649 gl.ClearBufferuiv(target, draw_buffer as i32, values.as_ptr());
650 }
651
652 unsafe fn clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &[f32]) {
653 let gl = &self.raw;
654 gl.ClearBufferfv(target, draw_buffer as i32, values.as_ptr());
655 }
656
657 unsafe fn clear_buffer_depth_stencil(
658 &self,
659 target: u32,
660 draw_buffer: u32,
661 depth: f32,
662 stencil: i32,
663 ) {
664 let gl = &self.raw;
665 gl.ClearBufferfi(target, draw_buffer as i32, depth, stencil);
666 }
667
668 unsafe fn client_wait_sync(&self, fence: Self::Fence, flags: u32, timeout: i32) -> u32 {
669 let gl = &self.raw;
670 gl.ClientWaitSync(fence.0, flags, timeout as u64)
671 }
672
673 unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64) {
674 let gl = &self.raw;
675 gl.WaitSync(fence.0, flags, timeout)
676 }
677
678 unsafe fn copy_buffer_sub_data(
679 &self,
680 src_target: u32,
681 dst_target: u32,
682 src_offset: i32,
683 dst_offset: i32,
684 size: i32,
685 ) {
686 let gl = &self.raw;
687 gl.CopyBufferSubData(
688 src_target,
689 dst_target,
690 src_offset as isize,
691 dst_offset as isize,
692 size as isize,
693 );
694 }
695
696 unsafe fn copy_image_sub_data(
697 &self,
698 src_name: Self::Texture,
699 src_target: u32,
700 src_level: i32,
701 src_x: i32,
702 src_y: i32,
703 src_z: i32,
704 dst_name: Self::Texture,
705 dst_target: u32,
706 dst_level: i32,
707 dst_x: i32,
708 dst_y: i32,
709 dst_z: i32,
710 src_width: i32,
711 src_height: i32,
712 src_depth: i32,
713 ) {
714 let gl = &self.raw;
715 gl.CopyImageSubData(
716 src_name.0.get(),
717 src_target,
718 src_level,
719 src_x,
720 src_y,
721 src_z,
722 dst_name.0.get(),
723 dst_target,
724 dst_level,
725 dst_x,
726 dst_y,
727 dst_z,
728 src_width,
729 src_height,
730 src_depth,
731 );
732 }
733
734 unsafe fn copy_tex_image_2d(
735 &self,
736 target: u32,
737 level: i32,
738 internal_format: u32,
739 x: i32,
740 y: i32,
741 width: i32,
742 height: i32,
743 border: i32,
744 ) {
745 let gl = &self.raw;
746 gl.CopyTexImage2D(target, level, internal_format, x, y, width, height, border);
747 }
748
749 unsafe fn copy_tex_sub_image_2d(
750 &self,
751 target: u32,
752 level: i32,
753 x_offset: i32,
754 y_offset: i32,
755 x: i32,
756 y: i32,
757 width: i32,
758 height: i32,
759 ) {
760 let gl = &self.raw;
761 gl.CopyTexSubImage2D(target, level, x_offset, y_offset, x, y, width, height);
762 }
763
764 unsafe fn copy_tex_sub_image_3d(
765 &self,
766 target: u32,
767 level: i32,
768 x_offset: i32,
769 y_offset: i32,
770 z_offset: i32,
771 x: i32,
772 y: i32,
773 width: i32,
774 height: i32,
775 ) {
776 let gl = &self.raw;
777 gl.CopyTexSubImage3D(
778 target, level, x_offset, y_offset, z_offset, x, y, width, height,
779 );
780 }
781
782 unsafe fn delete_buffer(&self, buffer: Self::Buffer) {
783 let gl = &self.raw;
784 gl.DeleteBuffers(1, &buffer.0.get());
785 }
786
787 unsafe fn delete_framebuffer(&self, framebuffer: Self::Framebuffer) {
788 let gl = &self.raw;
789 gl.DeleteFramebuffers(1, &framebuffer.0.get());
790 }
791
792 unsafe fn delete_query(&self, query: Self::Query) {
793 let gl = &self.raw;
794 gl.DeleteQueries(1, &query.0.get());
795 }
796
797 unsafe fn delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer) {
798 let gl = &self.raw;
799 gl.DeleteRenderbuffers(1, &renderbuffer.0.get());
800 }
801
802 unsafe fn delete_sampler(&self, sampler: Self::Sampler) {
803 let gl = &self.raw;
804 gl.DeleteSamplers(1, &sampler.0.get());
805 }
806
807 unsafe fn delete_sync(&self, fence: Self::Fence) {
808 let gl = &self.raw;
809 gl.DeleteSync(fence.0);
810 }
811
812 unsafe fn delete_texture(&self, texture: Self::Texture) {
813 let gl = &self.raw;
814 gl.DeleteTextures(1, &texture.0.get());
815 }
816
817 unsafe fn disable(&self, parameter: u32) {
818 let gl = &self.raw;
819 gl.Disable(parameter);
820 }
821
822 unsafe fn disable_draw_buffer(&self, parameter: u32, draw_buffer: u32) {
823 let gl = &self.raw;
824 gl.Disablei(parameter, draw_buffer);
825 }
826
827 unsafe fn disable_vertex_attrib_array(&self, index: u32) {
828 let gl = &self.raw;
829 gl.DisableVertexAttribArray(index);
830 }
831
832 unsafe fn dispatch_compute(&self, groups_x: u32, groups_y: u32, groups_z: u32) {
833 let gl = &self.raw;
834 gl.DispatchCompute(groups_x, groups_y, groups_z);
835 }
836
837 unsafe fn dispatch_compute_indirect(&self, offset: i32) {
838 let gl = &self.raw;
839 gl.DispatchComputeIndirect(offset as isize);
840 }
841
842 unsafe fn draw_arrays(&self, mode: u32, first: i32, count: i32) {
843 let gl = &self.raw;
844 gl.DrawArrays(mode as u32, first, count);
845 }
846
847 unsafe fn draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32) {
848 let gl = &self.raw;
849 gl.DrawArraysInstanced(mode as u32, first, count, instance_count);
850 }
851
852 unsafe fn draw_arrays_instanced_base_instance(
853 &self,
854 mode: u32,
855 first: i32,
856 count: i32,
857 instance_count: i32,
858 base_instance: u32,
859 ) {
860 let gl = &self.raw;
861 gl.DrawArraysInstancedBaseInstance(
862 mode as u32,
863 first,
864 count,
865 instance_count,
866 base_instance,
867 );
868 }
869
870 unsafe fn draw_arrays_indirect_offset(&self, mode: u32, offset: i32) {
871 let gl = &self.raw;
872 gl.DrawArraysIndirect(mode, offset as *const std::ffi::c_void);
873 }
874
875 unsafe fn draw_buffer(&self, draw_buffer: u32) {
876 let gl = &self.raw;
877 gl.DrawBuffer(draw_buffer);
878 }
879
880 unsafe fn draw_buffers(&self, buffers: &[u32]) {
881 let gl = &self.raw;
882 gl.DrawBuffers(buffers.len() as i32, buffers.as_ptr());
883 }
884
885 unsafe fn draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32) {
886 let gl = &self.raw;
887 gl.DrawElements(
888 mode as u32,
889 count,
890 element_type as u32,
891 offset as *const std::ffi::c_void,
892 );
893 }
894
895 unsafe fn draw_elements_base_vertex(
896 &self,
897 mode: u32,
898 count: i32,
899 element_type: u32,
900 offset: i32,
901 base_vertex: i32,
902 ) {
903 let gl = &self.raw;
904 gl.DrawElementsBaseVertex(
905 mode as u32,
906 count,
907 element_type as u32,
908 offset as *const std::ffi::c_void,
909 base_vertex,
910 );
911 }
912
913 unsafe fn draw_elements_instanced(
914 &self,
915 mode: u32,
916 count: i32,
917 element_type: u32,
918 offset: i32,
919 instance_count: i32,
920 ) {
921 let gl = &self.raw;
922 gl.DrawElementsInstanced(
923 mode as u32,
924 count,
925 element_type as u32,
926 offset as *const std::ffi::c_void,
927 instance_count,
928 );
929 }
930
931 unsafe fn draw_elements_instanced_base_vertex(
932 &self,
933 mode: u32,
934 count: i32,
935 element_type: u32,
936 offset: i32,
937 instance_count: i32,
938 base_vertex: i32,
939 ) {
940 let gl = &self.raw;
941 gl.DrawElementsInstancedBaseVertex(
942 mode as u32,
943 count,
944 element_type as u32,
945 offset as *const std::ffi::c_void,
946 instance_count,
947 base_vertex,
948 );
949 }
950
951 unsafe fn draw_elements_instanced_base_vertex_base_instance(
952 &self,
953 mode: u32,
954 count: i32,
955 element_type: u32,
956 offset: i32,
957 instance_count: i32,
958 base_vertex: i32,
959 base_instance: u32,
960 ) {
961 let gl = &self.raw;
962 gl.DrawElementsInstancedBaseVertexBaseInstance(
963 mode as u32,
964 count,
965 element_type as u32,
966 offset as *const std::ffi::c_void,
967 instance_count,
968 base_vertex,
969 base_instance,
970 );
971 }
972
973 unsafe fn draw_elements_indirect_offset(&self, mode: u32, element_type: u32, offset: i32) {
974 let gl = &self.raw;
975 gl.DrawElementsIndirect(mode, element_type, offset as *const std::ffi::c_void);
976 }
977
978 unsafe fn enable(&self, parameter: u32) {
979 let gl = &self.raw;
980 gl.Enable(parameter);
981 }
982
983 unsafe fn is_enabled(&self, parameter: u32) -> bool {
984 let gl = &self.raw;
985 gl.IsEnabled(parameter) != 0
986 }
987
988 unsafe fn enable_draw_buffer(&self, parameter: u32, draw_buffer: u32) {
989 let gl = &self.raw;
990 gl.Enablei(parameter, draw_buffer);
991 }
992
993 unsafe fn enable_vertex_array_attrib(&self, vao: Self::VertexArray, index: u32) {
994 let gl = &self.raw;
995 gl.EnableVertexArrayAttrib(vao.0.get(), index);
996 }
997
998 unsafe fn enable_vertex_attrib_array(&self, index: u32) {
999 let gl = &self.raw;
1000 gl.EnableVertexAttribArray(index);
1001 }
1002
1003 unsafe fn flush(&self) {
1004 let gl = &self.raw;
1005 gl.Flush();
1006 }
1007
1008 unsafe fn framebuffer_renderbuffer(
1009 &self,
1010 target: u32,
1011 attachment: u32,
1012 renderbuffer_target: u32,
1013 renderbuffer: Option<Self::Renderbuffer>,
1014 ) {
1015 let gl = &self.raw;
1016 gl.FramebufferRenderbuffer(
1017 target,
1018 attachment,
1019 renderbuffer_target,
1020 renderbuffer.map(|rb| rb.0.get()).unwrap_or(0),
1021 );
1022 }
1023
1024 unsafe fn framebuffer_texture(
1025 &self,
1026 target: u32,
1027 attachment: u32,
1028 texture: Option<Self::Texture>,
1029 level: i32,
1030 ) {
1031 let gl = &self.raw;
1032 gl.FramebufferTexture(
1033 target,
1034 attachment,
1035 texture.map(|t| t.0.get()).unwrap_or(0),
1036 level,
1037 );
1038 }
1039
1040 unsafe fn framebuffer_texture_2d(
1041 &self,
1042 target: u32,
1043 attachment: u32,
1044 texture_target: u32,
1045 texture: Option<Self::Texture>,
1046 level: i32,
1047 ) {
1048 let gl = &self.raw;
1049 gl.FramebufferTexture2D(
1050 target,
1051 attachment,
1052 texture_target,
1053 texture.map(|t| t.0.get()).unwrap_or(0),
1054 level,
1055 );
1056 }
1057
1058 unsafe fn framebuffer_texture_3d(
1059 &self,
1060 target: u32,
1061 attachment: u32,
1062 texture_target: u32,
1063 texture: Option<Self::Texture>,
1064 level: i32,
1065 layer: i32,
1066 ) {
1067 let gl = &self.raw;
1068 gl.FramebufferTexture3D(
1069 target,
1070 attachment,
1071 texture_target,
1072 texture.map(|t| t.0.get()).unwrap_or(0),
1073 level,
1074 layer,
1075 );
1076 }
1077
1078 unsafe fn framebuffer_texture_layer(
1079 &self,
1080 target: u32,
1081 attachment: u32,
1082 texture: Option<Self::Texture>,
1083 level: i32,
1084 layer: i32,
1085 ) {
1086 let gl = &self.raw;
1087 gl.FramebufferTextureLayer(
1088 target,
1089 attachment,
1090 texture.map(|t| t.0.get()).unwrap_or(0),
1091 level,
1092 layer,
1093 );
1094 }
1095
1096 unsafe fn front_face(&self, value: u32) {
1097 let gl = &self.raw;
1098 gl.FrontFace(value as u32);
1099 }
1100
1101 unsafe fn get_error(&self) -> u32 {
1102 let gl = &self.raw;
1103 gl.GetError()
1104 }
1105
1106 unsafe fn get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1107 let gl = &self.raw;
1108 let mut value = 0;
1109 gl.GetTexParameteriv(target, parameter, &mut value);
1110 value
1111 }
1112
1113 unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1114 let gl = &self.raw;
1115 let mut value = 0;
1116 gl.GetBufferParameteriv(target, parameter, &mut value);
1117 value
1118 }
1119
1120 unsafe fn get_parameter_i32(&self, parameter: u32) -> i32 {
1121 let gl = &self.raw;
1122 let mut value = 0;
1123 gl.GetIntegerv(parameter, &mut value);
1124 value
1125 }
1126
1127 unsafe fn get_parameter_i32_slice(&self, parameter: u32, out: &mut [i32]) {
1128 let gl = &self.raw;
1129 gl.GetIntegerv(parameter, &mut out[0]);
1130 }
1131
1132 unsafe fn get_parameter_f32(&self, parameter: u32) -> f32 {
1133 let gl = &self.raw;
1134 let mut value: f32 = 0.0;
1135 gl.GetFloatv(parameter, &mut value);
1136 value
1137 }
1138
1139 unsafe fn get_parameter_f32_slice(&self, parameter: u32, out: &mut [f32]) {
1140 let gl = &self.raw;
1141 gl.GetFloatv(parameter, &mut out[0]);
1142 }
1143
1144 unsafe fn get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i32 {
1145 let gl = &self.raw;
1146 let mut value = 0;
1147 gl.GetIntegeri_v(parameter, index, &mut value);
1148 value
1149 }
1150
1151 unsafe fn get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String {
1152 let gl = &self.raw;
1153 let raw_ptr = gl.GetStringi(parameter, index);
1154 std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar)
1155 .to_str()
1156 .unwrap()
1157 .to_owned()
1158 }
1159
1160 unsafe fn get_parameter_string(&self, parameter: u32) -> String {
1161 let gl = &self.raw;
1162 let raw_ptr = gl.GetString(parameter);
1163 std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar)
1164 .to_str()
1165 .unwrap()
1166 .to_owned()
1167 }
1168
1169 unsafe fn get_uniform_location(
1170 &self,
1171 program: Self::Program,
1172 name: &str,
1173 ) -> Option<Self::UniformLocation> {
1174 let gl = &self.raw;
1175 let name = CString::new(name).unwrap();
1176 let uniform_location =
1177 gl.GetUniformLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar);
1178 if uniform_location < 0 {
1179 None
1180 } else {
1181 Some(NativeUniformLocation(uniform_location as u32))
1182 }
1183 }
1184
1185 unsafe fn get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32> {
1186 let gl = &self.raw;
1187 let name = CString::new(name).unwrap();
1188 let attrib_location =
1189 gl.GetAttribLocation(program.0.get(), name.as_ptr() as *const native_gl::GLchar);
1190 if attrib_location < 0 {
1191 None
1192 } else {
1193 Some(attrib_location as u32)
1194 }
1195 }
1196
1197 unsafe fn bind_attrib_location(&self, program: Self::Program, index: u32, name: &str) {
1198 let gl = &self.raw;
1199 let name = CString::new(name).unwrap();
1200 gl.BindAttribLocation(
1201 program.0.get(),
1202 index,
1203 name.as_ptr() as *const native_gl::GLchar,
1204 );
1205 }
1206
1207 unsafe fn get_active_attributes(&self, program: Self::Program) -> u32 {
1208 let gl = &self.raw;
1209 let mut count = 0;
1210 gl.GetProgramiv(program.0.get(), ACTIVE_ATTRIBUTES, &mut count);
1211 count as u32
1212 }
1213
1214 unsafe fn get_active_attribute(
1215 &self,
1216 program: Self::Program,
1217 index: u32,
1218 ) -> Option<ActiveAttribute> {
1219 let gl = &self.raw;
1220 let mut attribute_max_size = 0;
1221 gl.GetProgramiv(
1222 program.0.get(),
1223 ACTIVE_ATTRIBUTE_MAX_LENGTH,
1224 &mut attribute_max_size,
1225 );
1226 let mut name = String::with_capacity(attribute_max_size as usize);
1227 name.extend(std::iter::repeat('\0').take(attribute_max_size as usize));
1228 let mut length = 0;
1229 let mut size = 0;
1230 let mut atype = 0;
1231 gl.GetActiveAttrib(
1232 program.0.get(),
1233 index,
1234 attribute_max_size,
1235 &mut length,
1236 &mut size,
1237 &mut atype,
1238 name.as_ptr() as *mut native_gl::GLchar,
1239 );
1240
1241 name.truncate(length as usize);
1242
1243 Some(ActiveAttribute { name, size, atype })
1244 }
1245
1246 unsafe fn get_sync_status(&self, fence: Self::Fence) -> u32 {
1247 let gl = &self.raw;
1248 let mut len = 0;
1249 let mut values = [UNSIGNALED as i32];
1250 gl.GetSynciv(
1251 fence.0,
1252 SYNC_STATUS,
1253 values.len() as i32,
1254 &mut len,
1255 values.as_mut_ptr(),
1256 );
1257 values[0] as u32
1258 }
1259
1260 unsafe fn is_sync(&self, fence: Self::Fence) -> bool {
1261 let gl = &self.raw;
1262 1 == gl.IsSync(fence.0)
1263 }
1264
1265 unsafe fn renderbuffer_storage(
1266 &self,
1267 target: u32,
1268 internal_format: u32,
1269 width: i32,
1270 height: i32,
1271 ) {
1272 let gl = &self.raw;
1273 gl.RenderbufferStorage(target, internal_format, width, height);
1274 }
1275
1276 unsafe fn renderbuffer_storage_multisample(
1277 &self,
1278 target: u32,
1279 samples: i32,
1280 internal_format: u32,
1281 width: i32,
1282 height: i32,
1283 ) {
1284 let gl = &self.raw;
1285 gl.RenderbufferStorageMultisample(target, samples, internal_format, width, height);
1286 }
1287
1288 unsafe fn sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32) {
1289 let gl = &self.raw;
1290 gl.SamplerParameterf(sampler.0.get(), name, value);
1291 }
1292
1293 unsafe fn sampler_parameter_f32_slice(&self, sampler: Self::Sampler, name: u32, value: &[f32]) {
1294 let gl = &self.raw;
1295 gl.SamplerParameterfv(sampler.0.get(), name, value.as_ptr());
1296 }
1297
1298 unsafe fn sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32) {
1299 let gl = &self.raw;
1300 gl.SamplerParameteri(sampler.0.get(), name, value);
1301 }
1302
1303 unsafe fn generate_mipmap(&self, target: u32) {
1304 let gl = &self.raw;
1305 gl.GenerateMipmap(target);
1306 }
1307
1308 unsafe fn generate_texture_mipmap(&self, texture: Self::Texture) {
1309 let gl = &self.raw;
1310 gl.GenerateTextureMipmap(texture.0.get());
1311 }
1312
1313 unsafe fn tex_image_1d(
1314 &self,
1315 target: u32,
1316 level: i32,
1317 internal_format: i32,
1318 width: i32,
1319 border: i32,
1320 format: u32,
1321 ty: u32,
1322 pixels: Option<&[u8]>,
1323 ) {
1324 let gl = &self.raw;
1325 gl.TexImage1D(
1326 target,
1327 level,
1328 internal_format,
1329 width,
1330 border,
1331 format,
1332 ty,
1333 pixels.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void,
1334 );
1335 }
1336
1337 unsafe fn compressed_tex_image_1d(
1338 &self,
1339 target: u32,
1340 level: i32,
1341 internal_format: i32,
1342 width: i32,
1343 border: i32,
1344 image_size: i32,
1345 pixels: &[u8],
1346 ) {
1347 let gl = &self.raw;
1348 gl.CompressedTexImage1D(
1349 target,
1350 level,
1351 internal_format as u32,
1352 width,
1353 border,
1354 image_size,
1355 pixels.as_ptr() as *const std::ffi::c_void,
1356 );
1357 }
1358
1359 unsafe fn tex_image_2d(
1360 &self,
1361 target: u32,
1362 level: i32,
1363 internal_format: i32,
1364 width: i32,
1365 height: i32,
1366 border: i32,
1367 format: u32,
1368 ty: u32,
1369 pixels: Option<&[u8]>,
1370 ) {
1371 let gl = &self.raw;
1372 gl.TexImage2D(
1373 target,
1374 level,
1375 internal_format,
1376 width,
1377 height,
1378 border,
1379 format,
1380 ty,
1381 pixels.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void,
1382 );
1383 }
1384
1385 unsafe fn tex_image_2d_multisample(
1386 &self,
1387 target: u32,
1388 samples: i32,
1389 internal_format: i32,
1390 width: i32,
1391 height: i32,
1392 fixed_sample_locations: bool,
1393 ) {
1394 let gl = &self.raw;
1395 gl.TexImage2DMultisample(
1396 target,
1397 samples,
1398 internal_format as u32,
1399 width,
1400 height,
1401 if fixed_sample_locations { 1 } else { 0 },
1402 );
1403 }
1404
1405 unsafe fn compressed_tex_image_2d(
1406 &self,
1407 target: u32,
1408 level: i32,
1409 internal_format: i32,
1410 width: i32,
1411 height: i32,
1412 border: i32,
1413 image_size: i32,
1414 pixels: &[u8],
1415 ) {
1416 let gl = &self.raw;
1417 gl.CompressedTexImage2D(
1418 target,
1419 level,
1420 internal_format as u32,
1421 width,
1422 height,
1423 border,
1424 image_size,
1425 pixels.as_ptr() as *const std::ffi::c_void,
1426 );
1427 }
1428
1429 unsafe fn tex_image_3d(
1430 &self,
1431 target: u32,
1432 level: i32,
1433 internal_format: i32,
1434 width: i32,
1435 height: i32,
1436 depth: i32,
1437 border: i32,
1438 format: u32,
1439 ty: u32,
1440 pixels: Option<&[u8]>,
1441 ) {
1442 let gl = &self.raw;
1443 gl.TexImage3D(
1444 target,
1445 level,
1446 internal_format,
1447 width,
1448 height,
1449 depth,
1450 border,
1451 format,
1452 ty,
1453 pixels.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void,
1454 );
1455 }
1456
1457 unsafe fn compressed_tex_image_3d(
1458 &self,
1459 target: u32,
1460 level: i32,
1461 internal_format: i32,
1462 width: i32,
1463 height: i32,
1464 depth: i32,
1465 border: i32,
1466 image_size: i32,
1467 pixels: &[u8],
1468 ) {
1469 let gl = &self.raw;
1470 gl.CompressedTexImage3D(
1471 target,
1472 level,
1473 internal_format as u32,
1474 width,
1475 height,
1476 depth,
1477 border,
1478 image_size,
1479 pixels.as_ptr() as *const std::ffi::c_void,
1480 );
1481 }
1482
1483 unsafe fn tex_storage_1d(&self, target: u32, levels: i32, internal_format: u32, width: i32) {
1484 let gl = &self.raw;
1485 gl.TexStorage1D(target, levels, internal_format, width);
1486 }
1487
1488 unsafe fn tex_storage_2d(
1489 &self,
1490 target: u32,
1491 levels: i32,
1492 internal_format: u32,
1493 width: i32,
1494 height: i32,
1495 ) {
1496 let gl = &self.raw;
1497 gl.TexStorage2D(target, levels, internal_format, width, height);
1498 }
1499
1500 unsafe fn tex_storage_2d_multisample(
1501 &self,
1502 target: u32,
1503 samples: i32,
1504 internal_format: u32,
1505 width: i32,
1506 height: i32,
1507 fixed_sample_locations: bool,
1508 ) {
1509 let gl = &self.raw;
1510 gl.TexStorage2DMultisample(
1511 target,
1512 samples,
1513 internal_format,
1514 width,
1515 height,
1516 if fixed_sample_locations { 1 } else { 0 },
1517 );
1518 }
1519
1520 unsafe fn tex_storage_3d(
1521 &self,
1522 target: u32,
1523 levels: i32,
1524 internal_format: u32,
1525 width: i32,
1526 height: i32,
1527 depth: i32,
1528 ) {
1529 let gl = &self.raw;
1530 gl.TexStorage3D(target, levels, internal_format, width, height, depth);
1531 }
1532
1533 unsafe fn texture_storage_3d(
1534 &self,
1535 texture: Self::Texture,
1536 levels: i32,
1537 internal_format: u32,
1538 width: i32,
1539 height: i32,
1540 depth: i32,
1541 ) {
1542 let gl = &self.raw;
1543 gl.TextureStorage3D(
1544 texture.0.get(),
1545 levels,
1546 internal_format,
1547 width,
1548 height,
1549 depth,
1550 );
1551 }
1552
1553 unsafe fn get_uniform_i32(
1554 &self,
1555 program: Self::Program,
1556 location: &Self::UniformLocation,
1557 v: &mut [i32],
1558 ) {
1559 let gl = &self.raw;
1560 gl.GetUniformiv(
1561 program.0.get() as u32,
1562 location.0 as i32,
1563 v.as_mut_ptr() as *mut i32,
1564 )
1565 }
1566
1567 unsafe fn get_uniform_f32(
1568 &self,
1569 program: Self::Program,
1570 location: &Self::UniformLocation,
1571 v: &mut [f32],
1572 ) {
1573 let gl = &self.raw;
1574 gl.GetUniformfv(
1575 program.0.get() as u32,
1576 location.0 as i32,
1577 v.as_mut_ptr() as *mut f32,
1578 )
1579 }
1580
1581 unsafe fn uniform_1_i32(&self, location: Option<&Self::UniformLocation>, x: i32) {
1582 let gl = &self.raw;
1583 if let Some(loc) = location {
1584 gl.Uniform1i(loc.0 as i32, x);
1585 }
1586 }
1587
1588 unsafe fn uniform_2_i32(&self, location: Option<&Self::UniformLocation>, x: i32, y: i32) {
1589 let gl = &self.raw;
1590 if let Some(loc) = location {
1591 gl.Uniform2i(loc.0 as i32, x, y);
1592 }
1593 }
1594
1595 unsafe fn uniform_3_i32(
1596 &self,
1597 location: Option<&Self::UniformLocation>,
1598 x: i32,
1599 y: i32,
1600 z: i32,
1601 ) {
1602 let gl = &self.raw;
1603 if let Some(loc) = location {
1604 gl.Uniform3i(loc.0 as i32, x, y, z);
1605 }
1606 }
1607
1608 unsafe fn uniform_4_i32(
1609 &self,
1610 location: Option<&Self::UniformLocation>,
1611 x: i32,
1612 y: i32,
1613 z: i32,
1614 w: i32,
1615 ) {
1616 let gl = &self.raw;
1617 if let Some(loc) = location {
1618 gl.Uniform4i(loc.0 as i32, x, y, z, w);
1619 }
1620 }
1621
1622 unsafe fn uniform_1_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
1623 let gl = &self.raw;
1624 if let Some(loc) = location {
1625 gl.Uniform1iv(loc.0 as i32, v.len() as i32, v.as_ptr());
1626 }
1627 }
1628
1629 unsafe fn uniform_2_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
1630 let gl = &self.raw;
1631 if let Some(loc) = location {
1632 gl.Uniform2iv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
1633 }
1634 }
1635
1636 unsafe fn uniform_3_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
1637 let gl = &self.raw;
1638 if let Some(loc) = location {
1639 gl.Uniform3iv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
1640 }
1641 }
1642
1643 unsafe fn uniform_4_i32_slice(&self, location: Option<&Self::UniformLocation>, v: &[i32]) {
1644 let gl = &self.raw;
1645 if let Some(loc) = location {
1646 gl.Uniform4iv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
1647 }
1648 }
1649
1650 unsafe fn uniform_1_u32(&self, location: Option<&Self::UniformLocation>, x: u32) {
1651 let gl = &self.raw;
1652 if let Some(loc) = location {
1653 gl.Uniform1ui(loc.0 as i32, x);
1654 }
1655 }
1656
1657 unsafe fn uniform_2_u32(&self, location: Option<&Self::UniformLocation>, x: u32, y: u32) {
1658 let gl = &self.raw;
1659 if let Some(loc) = location {
1660 gl.Uniform2ui(loc.0 as i32, x, y);
1661 }
1662 }
1663
1664 unsafe fn uniform_3_u32(
1665 &self,
1666 location: Option<&Self::UniformLocation>,
1667 x: u32,
1668 y: u32,
1669 z: u32,
1670 ) {
1671 let gl = &self.raw;
1672 if let Some(loc) = location {
1673 gl.Uniform3ui(loc.0 as i32, x, y, z);
1674 }
1675 }
1676
1677 unsafe fn uniform_4_u32(
1678 &self,
1679 location: Option<&Self::UniformLocation>,
1680 x: u32,
1681 y: u32,
1682 z: u32,
1683 w: u32,
1684 ) {
1685 let gl = &self.raw;
1686 if let Some(loc) = location {
1687 gl.Uniform4ui(loc.0 as i32, x, y, z, w);
1688 }
1689 }
1690
1691 unsafe fn uniform_1_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
1692 let gl = &self.raw;
1693 if let Some(loc) = location {
1694 gl.Uniform1uiv(loc.0 as i32, v.len() as i32, v.as_ptr());
1695 }
1696 }
1697
1698 unsafe fn uniform_2_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
1699 let gl = &self.raw;
1700 if let Some(loc) = location {
1701 gl.Uniform2uiv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
1702 }
1703 }
1704
1705 unsafe fn uniform_3_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
1706 let gl = &self.raw;
1707 if let Some(loc) = location {
1708 gl.Uniform3uiv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
1709 }
1710 }
1711
1712 unsafe fn uniform_4_u32_slice(&self, location: Option<&Self::UniformLocation>, v: &[u32]) {
1713 let gl = &self.raw;
1714 if let Some(loc) = location {
1715 gl.Uniform4uiv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
1716 }
1717 }
1718
1719 unsafe fn uniform_1_f32(&self, location: Option<&Self::UniformLocation>, x: f32) {
1720 let gl = &self.raw;
1721 if let Some(loc) = location {
1722 gl.Uniform1f(loc.0 as i32, x);
1723 }
1724 }
1725
1726 unsafe fn uniform_2_f32(&self, location: Option<&Self::UniformLocation>, x: f32, y: f32) {
1727 let gl = &self.raw;
1728 if let Some(loc) = location {
1729 gl.Uniform2f(loc.0 as i32, x, y);
1730 }
1731 }
1732
1733 unsafe fn uniform_3_f32(
1734 &self,
1735 location: Option<&Self::UniformLocation>,
1736 x: f32,
1737 y: f32,
1738 z: f32,
1739 ) {
1740 let gl = &self.raw;
1741 if let Some(loc) = location {
1742 gl.Uniform3f(loc.0 as i32, x, y, z);
1743 }
1744 }
1745
1746 unsafe fn uniform_4_f32(
1747 &self,
1748 location: Option<&Self::UniformLocation>,
1749 x: f32,
1750 y: f32,
1751 z: f32,
1752 w: f32,
1753 ) {
1754 let gl = &self.raw;
1755 if let Some(loc) = location {
1756 gl.Uniform4f(loc.0 as i32, x, y, z, w);
1757 }
1758 }
1759
1760 unsafe fn uniform_1_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
1761 let gl = &self.raw;
1762 if let Some(loc) = location {
1763 gl.Uniform1fv(loc.0 as i32, v.len() as i32, v.as_ptr());
1764 }
1765 }
1766
1767 unsafe fn uniform_2_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
1768 let gl = &self.raw;
1769 if let Some(loc) = location {
1770 gl.Uniform2fv(loc.0 as i32, v.len() as i32 / 2, v.as_ptr());
1771 }
1772 }
1773
1774 unsafe fn uniform_3_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
1775 let gl = &self.raw;
1776 if let Some(loc) = location {
1777 gl.Uniform3fv(loc.0 as i32, v.len() as i32 / 3, v.as_ptr());
1778 }
1779 }
1780
1781 unsafe fn uniform_4_f32_slice(&self, location: Option<&Self::UniformLocation>, v: &[f32]) {
1782 let gl = &self.raw;
1783 if let Some(loc) = location {
1784 gl.Uniform4fv(loc.0 as i32, v.len() as i32 / 4, v.as_ptr());
1785 }
1786 }
1787
1788 unsafe fn uniform_matrix_2_f32_slice(
1789 &self,
1790 location: Option<&Self::UniformLocation>,
1791 transpose: bool,
1792 v: &[f32],
1793 ) {
1794 let gl = &self.raw;
1795 if let Some(loc) = location {
1796 gl.UniformMatrix2fv(
1797 loc.0 as i32,
1798 v.len() as i32 / 4,
1799 transpose as u8,
1800 v.as_ptr(),
1801 );
1802 }
1803 }
1804
1805 unsafe fn uniform_matrix_3_f32_slice(
1806 &self,
1807 location: Option<&Self::UniformLocation>,
1808 transpose: bool,
1809 v: &[f32],
1810 ) {
1811 let gl = &self.raw;
1812 if let Some(loc) = location {
1813 gl.UniformMatrix3fv(
1814 loc.0 as i32,
1815 v.len() as i32 / 9,
1816 transpose as u8,
1817 v.as_ptr(),
1818 );
1819 }
1820 }
1821
1822 unsafe fn uniform_matrix_4_f32_slice(
1823 &self,
1824 location: Option<&Self::UniformLocation>,
1825 transpose: bool,
1826 v: &[f32],
1827 ) {
1828 let gl = &self.raw;
1829 if let Some(loc) = location {
1830 gl.UniformMatrix4fv(
1831 loc.0 as i32,
1832 v.len() as i32 / 16,
1833 transpose as u8,
1834 v.as_ptr(),
1835 );
1836 }
1837 }
1838
1839 unsafe fn unmap_buffer(&self, target: u32) {
1840 let gl = &self.raw;
1841 gl.UnmapBuffer(target);
1842 }
1843
1844 unsafe fn cull_face(&self, value: u32) {
1845 let gl = &self.raw;
1846 gl.CullFace(value as u32);
1847 }
1848
1849 unsafe fn color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool) {
1850 let gl = &self.raw;
1851 gl.ColorMask(red as u8, green as u8, blue as u8, alpha as u8);
1852 }
1853
1854 unsafe fn color_mask_draw_buffer(
1855 &self,
1856 draw_buffer: u32,
1857 red: bool,
1858 green: bool,
1859 blue: bool,
1860 alpha: bool,
1861 ) {
1862 let gl = &self.raw;
1863 gl.ColorMaski(draw_buffer, red as u8, green as u8, blue as u8, alpha as u8);
1864 }
1865
1866 unsafe fn depth_mask(&self, value: bool) {
1867 let gl = &self.raw;
1868 gl.DepthMask(value as u8);
1869 }
1870
1871 unsafe fn blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
1872 let gl = &self.raw;
1873 gl.BlendColor(red, green, blue, alpha);
1874 }
1875
1876 unsafe fn line_width(&self, width: f32) {
1877 let gl = &self.raw;
1878 gl.LineWidth(width);
1879 }
1880
1881 unsafe fn map_buffer_range(
1882 &self,
1883 target: u32,
1884 offset: i32,
1885 length: i32,
1886 access: u32,
1887 ) -> *mut u8 {
1888 let gl = &self.raw;
1889 gl.MapBufferRange(target, offset as isize, length as isize, access) as *mut u8
1890 }
1891
1892 unsafe fn flush_mapped_buffer_range(&self, target: u32, offset: i32, length: i32) {
1893 let gl = &self.raw;
1894 gl.FlushMappedBufferRange(target, offset as isize, length as isize)
1895 }
1896
1897 unsafe fn invalidate_buffer_sub_data(&self, target: u32, offset: i32, length: i32) {
1898 let gl = &self.raw;
1899 gl.InvalidateBufferSubData(target, offset as isize, length as isize)
1900 }
1901
1902 unsafe fn invalidate_framebuffer(&self, target: u32, attachments: &[u32]) {
1903 let gl = &self.raw;
1904 gl.InvalidateFramebuffer(target, attachments.len() as i32, attachments.as_ptr());
1905 }
1906
1907 unsafe fn polygon_offset(&self, factor: f32, units: f32) {
1908 let gl = &self.raw;
1909 gl.PolygonOffset(factor, units);
1910 }
1911
1912 unsafe fn polygon_mode(&self, face: u32, mode: u32) {
1913 let gl = &self.raw;
1914 gl.PolygonMode(face as u32, mode as u32);
1915 }
1916
1917 unsafe fn finish(&self) {
1918 let gl = &self.raw;
1919 gl.Finish();
1920 }
1921
1922 unsafe fn bind_texture(&self, target: u32, texture: Option<Self::Texture>) {
1923 let gl = &self.raw;
1924 gl.BindTexture(target, texture.map(|t| t.0.get()).unwrap_or(0));
1925 }
1926
1927 unsafe fn bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>) {
1928 let gl = &self.raw;
1929 gl.BindSampler(unit, sampler.map(|s| s.0.get()).unwrap_or(0));
1930 }
1931
1932 unsafe fn active_texture(&self, unit: u32) {
1933 let gl = &self.raw;
1934 gl.ActiveTexture(unit);
1935 }
1936
1937 unsafe fn fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String> {
1938 let gl = &self.raw;
1939 Ok(NativeFence(gl.FenceSync(condition as u32, flags)))
1940 }
1941
1942 unsafe fn tex_parameter_f32(&self, target: u32, parameter: u32, value: f32) {
1943 let gl = &self.raw;
1944 gl.TexParameterf(target, parameter, value);
1945 }
1946
1947 unsafe fn tex_parameter_i32(&self, target: u32, parameter: u32, value: i32) {
1948 let gl = &self.raw;
1949 gl.TexParameteri(target, parameter, value);
1950 }
1951
1952 unsafe fn texture_parameter_i32(&self, texture: Self::Texture, parameter: u32, value: i32) {
1953 let gl = &self.raw;
1954 gl.TextureParameteri(texture.0.get(), parameter, value);
1955 }
1956
1957 unsafe fn tex_parameter_f32_slice(&self, target: u32, parameter: u32, values: &[f32]) {
1958 let gl = &self.raw;
1959 gl.TexParameterfv(target, parameter, values.as_ptr());
1960 }
1961
1962 unsafe fn tex_parameter_i32_slice(&self, target: u32, parameter: u32, values: &[i32]) {
1963 let gl = &self.raw;
1964 gl.TexParameteriv(target, parameter, values.as_ptr());
1965 }
1966
1967 unsafe fn tex_sub_image_2d(
1968 &self,
1969 target: u32,
1970 level: i32,
1971 x_offset: i32,
1972 y_offset: i32,
1973 width: i32,
1974 height: i32,
1975 format: u32,
1976 ty: u32,
1977 pixels: PixelUnpackData,
1978 ) {
1979 let gl = &self.raw;
1980 gl.TexSubImage2D(
1981 target,
1982 level,
1983 x_offset,
1984 y_offset,
1985 width,
1986 height,
1987 format,
1988 ty,
1989 match pixels {
1990 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
1991 PixelUnpackData::Slice(data) => data.as_ptr() as *const std::ffi::c_void,
1992 },
1993 );
1994 }
1995
1996 unsafe fn compressed_tex_sub_image_2d(
1997 &self,
1998 target: u32,
1999 level: i32,
2000 x_offset: i32,
2001 y_offset: i32,
2002 width: i32,
2003 height: i32,
2004 format: u32,
2005 pixels: CompressedPixelUnpackData,
2006 ) {
2007 let gl = &self.raw;
2008 let (data, image_size) = match pixels {
2009 CompressedPixelUnpackData::BufferRange(ref range) => (
2010 range.start as *const std::ffi::c_void,
2011 (range.end - range.start) as i32,
2012 ),
2013 CompressedPixelUnpackData::Slice(data) => {
2014 (data.as_ptr() as *const std::ffi::c_void, data.len() as i32)
2015 }
2016 };
2017
2018 gl.CompressedTexSubImage2D(
2019 target, level, x_offset, y_offset, width, height, format, image_size, data,
2020 );
2021 }
2022
2023 unsafe fn tex_sub_image_3d(
2024 &self,
2025 target: u32,
2026 level: i32,
2027 x_offset: i32,
2028 y_offset: i32,
2029 z_offset: i32,
2030 width: i32,
2031 height: i32,
2032 depth: i32,
2033 format: u32,
2034 ty: u32,
2035 pixels: PixelUnpackData,
2036 ) {
2037 let gl = &self.raw;
2038 gl.TexSubImage3D(
2039 target,
2040 level,
2041 x_offset,
2042 y_offset,
2043 z_offset,
2044 width,
2045 height,
2046 depth,
2047 format,
2048 ty,
2049 match pixels {
2050 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
2051 PixelUnpackData::Slice(data) => data.as_ptr() as *const std::ffi::c_void,
2052 },
2053 );
2054 }
2055
2056 unsafe fn texture_sub_image_3d(
2057 &self,
2058 texture: Self::Texture,
2059 level: i32,
2060 x_offset: i32,
2061 y_offset: i32,
2062 z_offset: i32,
2063 width: i32,
2064 height: i32,
2065 depth: i32,
2066 format: u32,
2067 ty: u32,
2068 pixels: PixelUnpackData,
2069 ) {
2070 let gl = &self.raw;
2071 gl.TextureSubImage3D(
2072 texture.0.get(),
2073 level,
2074 x_offset,
2075 y_offset,
2076 z_offset,
2077 width,
2078 height,
2079 depth,
2080 format,
2081 ty,
2082 match pixels {
2083 PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void,
2084 PixelUnpackData::Slice(data) => data.as_ptr() as *const std::ffi::c_void,
2085 },
2086 );
2087 }
2088
2089 unsafe fn compressed_tex_sub_image_3d(
2090 &self,
2091 target: u32,
2092 level: i32,
2093 x_offset: i32,
2094 y_offset: i32,
2095 z_offset: i32,
2096 width: i32,
2097 height: i32,
2098 depth: i32,
2099 format: u32,
2100 pixels: CompressedPixelUnpackData,
2101 ) {
2102 let gl = &self.raw;
2103 let (data, image_size) = match pixels {
2104 CompressedPixelUnpackData::BufferRange(ref range) => (
2105 range.start as *const std::ffi::c_void,
2106 (range.end - range.start) as i32,
2107 ),
2108 CompressedPixelUnpackData::Slice(data) => {
2109 (data.as_ptr() as *const std::ffi::c_void, data.len() as i32)
2110 }
2111 };
2112
2113 gl.CompressedTexSubImage3D(
2114 target, level, x_offset, y_offset, z_offset, width, height, depth, format, image_size,
2115 data,
2116 );
2117 }
2118
2119 unsafe fn depth_func(&self, func: u32) {
2120 let gl = &self.raw;
2121 gl.DepthFunc(func as u32);
2122 }
2123
2124 unsafe fn depth_range_f32(&self, near: f32, far: f32) {
2125 let gl = &self.raw;
2126 gl.DepthRangef(near, far);
2127 }
2128
2129 unsafe fn depth_range_f64(&self, near: f64, far: f64) {
2130 let gl = &self.raw;
2131 gl.DepthRange(near, far);
2132 }
2133
2134 unsafe fn depth_range_f64_slice(&self, first: u32, count: i32, values: &[[f64; 2]]) {
2135 let gl = &self.raw;
2136 gl.DepthRangeArrayv(first, count, values.as_ptr() as *const f64);
2137 }
2138
2139 unsafe fn scissor(&self, x: i32, y: i32, width: i32, height: i32) {
2140 let gl = &self.raw;
2141 gl.Scissor(x, y, width, height);
2142 }
2143
2144 unsafe fn scissor_slice(&self, first: u32, count: i32, scissors: &[[i32; 4]]) {
2145 let gl = &self.raw;
2146 gl.ScissorArrayv(first, count, scissors.as_ptr() as *const i32);
2147 }
2148
2149 unsafe fn vertex_array_attrib_binding_f32(
2150 &self,
2151 vao: Self::VertexArray,
2152 index: u32,
2153 binding_index: u32,
2154 ) {
2155 let gl = &self.raw;
2156 gl.VertexArrayAttribBinding(vao.0.get(), index, binding_index);
2157 }
2158
2159 unsafe fn vertex_array_attrib_format_f32(
2160 &self,
2161 vao: Self::VertexArray,
2162 index: u32,
2163 size: i32,
2164 data_type: u32,
2165 normalized: bool,
2166 relative_offset: u32,
2167 ) {
2168 let gl = &self.raw;
2169 gl.VertexArrayAttribFormat(
2170 vao.0.get(),
2171 index,
2172 size,
2173 data_type,
2174 normalized as u8,
2175 relative_offset,
2176 );
2177 }
2178
2179 unsafe fn vertex_array_attrib_format_i32(
2180 &self,
2181 vao: Self::VertexArray,
2182 index: u32,
2183 size: i32,
2184 data_type: u32,
2185 relative_offset: u32,
2186 ) {
2187 let gl = &self.raw;
2188 gl.VertexArrayAttribIFormat(vao.0.get(), index, size, data_type, relative_offset);
2189 }
2190
2191 unsafe fn vertex_array_element_buffer(
2192 &self,
2193 vao: Self::VertexArray,
2194 buffer: Option<Self::Buffer>,
2195 ) {
2196 let gl = &self.raw;
2197 gl.VertexArrayElementBuffer(vao.0.get(), buffer.map(|b| b.0.get()).unwrap_or(0));
2198 }
2199
2200 unsafe fn vertex_array_vertex_buffer(
2201 &self,
2202 vao: Self::VertexArray,
2203 binding_index: u32,
2204 buffer: Option<Self::Buffer>,
2205 offset: i32,
2206 stride: i32,
2207 ) {
2208 let gl = &self.raw;
2209 gl.VertexArrayVertexBuffer(
2210 vao.0.get(),
2211 binding_index,
2212 buffer.map(|b| b.0.get()).unwrap_or(0),
2213 offset as isize,
2214 stride,
2215 );
2216 }
2217
2218 unsafe fn vertex_attrib_divisor(&self, index: u32, divisor: u32) {
2219 let gl = &self.raw;
2220 gl.VertexAttribDivisor(index, divisor);
2221 }
2222
2223 unsafe fn vertex_attrib_pointer_f32(
2224 &self,
2225 index: u32,
2226 size: i32,
2227 data_type: u32,
2228 normalized: bool,
2229 stride: i32,
2230 offset: i32,
2231 ) {
2232 let gl = &self.raw;
2233 gl.VertexAttribPointer(
2234 index,
2235 size,
2236 data_type,
2237 normalized as u8,
2238 stride,
2239 offset as *const std::ffi::c_void,
2240 );
2241 }
2242
2243 unsafe fn vertex_attrib_pointer_i32(
2244 &self,
2245 index: u32,
2246 size: i32,
2247 data_type: u32,
2248 stride: i32,
2249 offset: i32,
2250 ) {
2251 let gl = &self.raw;
2252 gl.VertexAttribIPointer(
2253 index,
2254 size,
2255 data_type,
2256 stride,
2257 offset as *const std::ffi::c_void,
2258 );
2259 }
2260
2261 unsafe fn vertex_attrib_pointer_f64(
2262 &self,
2263 index: u32,
2264 size: i32,
2265 data_type: u32,
2266 stride: i32,
2267 offset: i32,
2268 ) {
2269 let gl = &self.raw;
2270 gl.VertexAttribLPointer(
2271 index,
2272 size,
2273 data_type,
2274 stride,
2275 offset as *const std::ffi::c_void,
2276 );
2277 }
2278
2279 unsafe fn vertex_attrib_format_f32(
2280 &self,
2281 index: u32,
2282 size: i32,
2283 data_type: u32,
2284 normalized: bool,
2285 relative_offset: u32,
2286 ) {
2287 let gl = &self.raw;
2288 gl.VertexAttribFormat(index, size, data_type, normalized as u8, relative_offset);
2289 }
2290
2291 unsafe fn vertex_attrib_format_i32(
2292 &self,
2293 index: u32,
2294 size: i32,
2295 data_type: u32,
2296 relative_offset: u32,
2297 ) {
2298 let gl = &self.raw;
2299 gl.VertexAttribIFormat(index, size, data_type, relative_offset);
2300 }
2301
2302 unsafe fn vertex_attrib_1_f32(&self, index: u32, x: f32) {
2303 let gl = &self.raw;
2304 gl.VertexAttrib1f(index, x);
2305 }
2306
2307 unsafe fn vertex_attrib_2_f32(&self, index: u32, x: f32, y: f32) {
2308 let gl = &self.raw;
2309 gl.VertexAttrib2f(index, x, y);
2310 }
2311
2312 unsafe fn vertex_attrib_3_f32(&self, index: u32, x: f32, y: f32, z: f32) {
2313 let gl = &self.raw;
2314 gl.VertexAttrib3f(index, x, y, z);
2315 }
2316
2317 unsafe fn vertex_attrib_4_f32(&self, index: u32, x: f32, y: f32, z: f32, w: f32) {
2318 let gl = &self.raw;
2319 gl.VertexAttrib4f(index, x, y, z, w);
2320 }
2321
2322 unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]) {
2323 let gl = &self.raw;
2324 gl.VertexAttrib1fv(index, v.as_ptr());
2325 }
2326
2327 unsafe fn vertex_attrib_2_f32_slice(&self, index: u32, v: &[f32]) {
2328 let gl = &self.raw;
2329 gl.VertexAttrib2fv(index, v.as_ptr());
2330 }
2331
2332 unsafe fn vertex_attrib_3_f32_slice(&self, index: u32, v: &[f32]) {
2333 let gl = &self.raw;
2334 gl.VertexAttrib3fv(index, v.as_ptr());
2335 }
2336
2337 unsafe fn vertex_attrib_4_f32_slice(&self, index: u32, v: &[f32]) {
2338 let gl = &self.raw;
2339 gl.VertexAttrib4fv(index, v.as_ptr());
2340 }
2341
2342 unsafe fn vertex_attrib_binding(&self, attrib_index: u32, binding_index: u32) {
2343 let gl = &self.raw;
2344 gl.VertexAttribBinding(attrib_index, binding_index);
2345 }
2346
2347 unsafe fn vertex_binding_divisor(&self, binding_index: u32, divisor: u32) {
2348 let gl = &self.raw;
2349 gl.VertexBindingDivisor(binding_index, divisor);
2350 }
2351
2352 unsafe fn viewport(&self, x: i32, y: i32, width: i32, height: i32) {
2353 let gl = &self.raw;
2354 gl.Viewport(x, y, width, height);
2355 }
2356
2357 unsafe fn viewport_f32_slice(&self, first: u32, count: i32, values: &[[f32; 4]]) {
2358 let gl = &self.raw;
2359 gl.ViewportArrayv(first, count, values.as_ptr() as *const f32);
2360 }
2361
2362 unsafe fn blend_equation(&self, mode: u32) {
2363 let gl = &self.raw;
2364 gl.BlendEquation(mode as u32);
2365 }
2366
2367 unsafe fn blend_equation_draw_buffer(&self, draw_buffer: u32, mode: u32) {
2368 let gl = &self.raw;
2369 gl.BlendEquationi(draw_buffer, mode as u32);
2370 }
2371
2372 unsafe fn blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32) {
2373 let gl = &self.raw;
2374 gl.BlendEquationSeparate(mode_rgb as u32, mode_alpha as u32);
2375 }
2376
2377 unsafe fn blend_equation_separate_draw_buffer(
2378 &self,
2379 draw_buffer: u32,
2380 mode_rgb: u32,
2381 mode_alpha: u32,
2382 ) {
2383 let gl = &self.raw;
2384 gl.BlendEquationSeparatei(draw_buffer, mode_rgb as u32, mode_alpha as u32);
2385 }
2386
2387 unsafe fn blend_func(&self, src: u32, dst: u32) {
2388 let gl = &self.raw;
2389 gl.BlendFunc(src as u32, dst as u32);
2390 }
2391
2392 unsafe fn blend_func_draw_buffer(&self, draw_buffer: u32, src: u32, dst: u32) {
2393 let gl = &self.raw;
2394 gl.BlendFunci(draw_buffer, src as u32, dst as u32);
2395 }
2396
2397 unsafe fn blend_func_separate(
2398 &self,
2399 src_rgb: u32,
2400 dst_rgb: u32,
2401 src_alpha: u32,
2402 dst_alpha: u32,
2403 ) {
2404 let gl = &self.raw;
2405 gl.BlendFuncSeparate(
2406 src_rgb as u32,
2407 dst_rgb as u32,
2408 src_alpha as u32,
2409 dst_alpha as u32,
2410 );
2411 }
2412
2413 unsafe fn blend_func_separate_draw_buffer(
2414 &self,
2415 draw_buffer: u32,
2416 src_rgb: u32,
2417 dst_rgb: u32,
2418 src_alpha: u32,
2419 dst_alpha: u32,
2420 ) {
2421 let gl = &self.raw;
2422 gl.BlendFuncSeparatei(
2423 draw_buffer,
2424 src_rgb as u32,
2425 dst_rgb as u32,
2426 src_alpha as u32,
2427 dst_alpha as u32,
2428 );
2429 }
2430
2431 unsafe fn stencil_func(&self, func: u32, reference: i32, mask: u32) {
2432 let gl = &self.raw;
2433 gl.StencilFunc(func as u32, reference, mask);
2434 }
2435
2436 unsafe fn stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32) {
2437 let gl = &self.raw;
2438 gl.StencilFuncSeparate(face as u32, func as u32, reference, mask);
2439 }
2440
2441 unsafe fn stencil_mask(&self, mask: u32) {
2442 let gl = &self.raw;
2443 gl.StencilMask(mask);
2444 }
2445
2446 unsafe fn stencil_mask_separate(&self, face: u32, mask: u32) {
2447 let gl = &self.raw;
2448 gl.StencilMaskSeparate(face as u32, mask);
2449 }
2450
2451 unsafe fn stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32) {
2452 let gl = &self.raw;
2453 gl.StencilOp(stencil_fail as u32, depth_fail as u32, pass as u32);
2454 }
2455
2456 unsafe fn stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32) {
2457 let gl = &self.raw;
2458 gl.StencilOpSeparate(
2459 face as u32,
2460 stencil_fail as u32,
2461 depth_fail as u32,
2462 pass as u32,
2463 );
2464 }
2465
2466 unsafe fn debug_message_control(
2467 &self,
2468 source: u32,
2469 msg_type: u32,
2470 severity: u32,
2471 ids: &[u32],
2472 enabled: bool,
2473 ) {
2474 let gl = &self.raw;
2475
2476 let ids_ptr = if ids.is_empty() {
2477 std::ptr::null()
2478 } else {
2479 ids.as_ptr()
2480 };
2481
2482 gl.DebugMessageControl(
2483 source,
2484 msg_type,
2485 severity,
2486 ids.len() as i32,
2487 ids_ptr,
2488 enabled as u8,
2489 );
2490 }
2491
2492 unsafe fn debug_message_insert<S>(
2493 &self,
2494 source: u32,
2495 msg_type: u32,
2496 id: u32,
2497 severity: u32,
2498 msg: S,
2499 ) where
2500 S: AsRef<str>,
2501 {
2502 let gl = &self.raw;
2503 let message = msg.as_ref().as_bytes();
2504 let length = message.len() as i32;
2505 gl.DebugMessageInsert(
2506 source,
2507 msg_type,
2508 id,
2509 severity,
2510 length,
2511 message.as_ptr() as *const native_gl::GLchar,
2512 );
2513 }
2514
2515 unsafe fn debug_message_callback<F>(&self, mut callback: F)
2516 where
2517 F: FnMut(u32, u32, u32, u32, &str),
2518 {
2519 let gl = &self.raw;
2520 gl.DebugMessageCallback(
2521 Some(raw_debug_message_callback::<F>),
2522 &mut callback as *mut _ as *mut std::ffi::c_void,
2523 );
2524 }
2525
2526 unsafe fn get_debug_message_log(&self, count: u32) -> Vec<DebugMessageLogEntry> {
2527 let ct = count as usize;
2528 let mut sources = Vec::with_capacity(ct);
2529 let mut types = Vec::with_capacity(ct);
2530 let mut ids = Vec::with_capacity(ct);
2531 let mut severities = Vec::with_capacity(ct);
2532 let mut lengths = Vec::with_capacity(ct);
2533 let buf_size = (count * MAX_DEBUG_MESSAGE_LENGTH) as i32;
2534 let mut message_log = Vec::with_capacity(buf_size as usize);
2535
2536 let gl = &self.raw;
2537 let received = gl.GetDebugMessageLog(
2538 count,
2539 buf_size,
2540 sources.as_mut_ptr(),
2541 types.as_mut_ptr(),
2542 ids.as_mut_ptr(),
2543 severities.as_mut_ptr(),
2544 lengths.as_mut_ptr(),
2545 message_log.as_mut_ptr(),
2546 ) as usize;
2547
2548 sources.set_len(received);
2549 types.set_len(received);
2550 ids.set_len(received);
2551 severities.set_len(received);
2552 lengths.set_len(received);
2553 message_log.set_len(buf_size as usize);
2554
2555 let mut entries = Vec::new();
2556 let mut offset = 0;
2557 for i in 0..received {
2558 let message =
2559 std::ffi::CStr::from_ptr(message_log[offset..].as_ptr()).to_string_lossy();
2560 offset += lengths[i] as usize;
2561 entries.push(DebugMessageLogEntry {
2562 source: sources[i],
2563 msg_type: types[i],
2564 id: ids[i],
2565 severity: severities[i],
2566 message: message.to_string(),
2567 });
2568 }
2569
2570 entries
2571 }
2572
2573 unsafe fn push_debug_group<S>(&self, source: u32, id: u32, message: S)
2574 where
2575 S: AsRef<str>,
2576 {
2577 let gl = &self.raw;
2578 let msg = message.as_ref().as_bytes();
2579 let length = msg.len() as i32;
2580 gl.PushDebugGroup(source, id, length, msg.as_ptr() as *const native_gl::GLchar);
2581 }
2582
2583 unsafe fn pop_debug_group(&self) {
2584 let gl = &self.raw;
2585 gl.PopDebugGroup();
2586 }
2587
2588 unsafe fn object_label<S>(&self, identifier: u32, name: u32, label: Option<S>)
2589 where
2590 S: AsRef<str>,
2591 {
2592 let gl = &self.raw;
2593
2594 match label {
2595 Some(l) => {
2596 let lbl = l.as_ref().as_bytes();
2597 let length = lbl.len() as i32;
2598 gl.ObjectLabel(
2599 identifier,
2600 name,
2601 length,
2602 lbl.as_ptr() as *const native_gl::GLchar,
2603 );
2604 }
2605 None => gl.ObjectLabel(identifier, name, 0, std::ptr::null()),
2606 }
2607 }
2608
2609 unsafe fn get_object_label(&self, identifier: u32, name: u32) -> String {
2610 let gl = &self.raw;
2611 let mut len = 0;
2612 let mut label_buf = Vec::with_capacity(self.constants.max_label_length as usize);
2613 gl.GetObjectLabel(
2614 identifier,
2615 name,
2616 self.constants.max_label_length,
2617 &mut len,
2618 label_buf.as_mut_ptr(),
2619 );
2620 label_buf.set_len(len as usize);
2621 std::ffi::CStr::from_ptr(label_buf.as_ptr())
2622 .to_str()
2623 .unwrap()
2624 .to_owned()
2625 }
2626
2627 unsafe fn object_ptr_label<S>(&self, sync: Self::Fence, label: Option<S>)
2628 where
2629 S: AsRef<str>,
2630 {
2631 let gl = &self.raw;
2632
2633 match label {
2634 Some(l) => {
2635 let lbl = l.as_ref().as_bytes();
2636 let length = lbl.len() as i32;
2637 gl.ObjectPtrLabel(
2638 sync.0 as *mut std::ffi::c_void,
2639 length,
2640 lbl.as_ptr() as *const native_gl::GLchar,
2641 );
2642 }
2643 None => gl.ObjectPtrLabel(sync.0 as *mut std::ffi::c_void, 0, std::ptr::null()),
2644 }
2645 }
2646
2647 unsafe fn get_object_ptr_label(&self, sync: Self::Fence) -> String {
2648 let gl = &self.raw;
2649 let mut len = 0;
2650 let mut label_buf = Vec::with_capacity(self.constants.max_label_length as usize);
2651 gl.GetObjectPtrLabel(
2652 sync.0 as *mut std::ffi::c_void,
2653 self.constants.max_label_length,
2654 &mut len,
2655 label_buf.as_mut_ptr(),
2656 );
2657 label_buf.set_len(len as usize);
2658 std::ffi::CStr::from_ptr(label_buf.as_ptr())
2659 .to_str()
2660 .unwrap()
2661 .to_owned()
2662 }
2663
2664 unsafe fn get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32> {
2665 let gl = &self.raw;
2666 let name = CString::new(name).unwrap();
2667 let index = gl.GetUniformBlockIndex(program.0.get(), name.as_ptr());
2668 if index == INVALID_INDEX {
2669 None
2670 } else {
2671 Some(index)
2672 }
2673 }
2674
2675 unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) {
2676 let gl = &self.raw;
2677 gl.UniformBlockBinding(program.0.get(), index, binding);
2678 }
2679
2680 unsafe fn get_shader_storage_block_index(
2681 &self,
2682 program: Self::Program,
2683 name: &str,
2684 ) -> Option<u32> {
2685 let gl = &self.raw;
2686 let name = CString::new(name).unwrap();
2687 let index =
2688 gl.GetProgramResourceIndex(program.0.get(), SHADER_STORAGE_BLOCK, name.as_ptr());
2689 if index == INVALID_INDEX {
2690 None
2691 } else {
2692 Some(index)
2693 }
2694 }
2695
2696 unsafe fn shader_storage_block_binding(
2697 &self,
2698 program: Self::Program,
2699 index: u32,
2700 binding: u32,
2701 ) {
2702 let gl = &self.raw;
2703 gl.ShaderStorageBlockBinding(program.0.get(), index, binding);
2704 }
2705
2706 unsafe fn read_buffer(&self, src: u32) {
2707 let gl = &self.raw;
2708 gl.ReadBuffer(src);
2709 }
2710
2711 unsafe fn read_pixels(
2712 &self,
2713 x: i32,
2714 y: i32,
2715 width: i32,
2716 height: i32,
2717 format: u32,
2718 gltype: u32,
2719 pixels: PixelPackData,
2720 ) {
2721 let gl = &self.raw;
2722 gl.ReadPixels(
2723 x,
2724 y,
2725 width,
2726 height,
2727 format,
2728 gltype,
2729 match pixels {
2730 PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void,
2731 PixelPackData::Slice(data) => data.as_mut_ptr() as *mut std::ffi::c_void,
2732 },
2733 );
2734 }
2735
2736 unsafe fn begin_query(&self, target: u32, query: Self::Query) {
2737 let gl = &self.raw;
2738 gl.BeginQuery(target, query.0.get());
2739 }
2740
2741 unsafe fn end_query(&self, target: u32) {
2742 let gl = &self.raw;
2743 gl.EndQuery(target);
2744 }
2745
2746 unsafe fn get_query_parameter_u32(&self, query: Self::Query, parameter: u32, mut default: u32) -> u32 {
2747 let gl = &self.raw;
2748 gl.GetQueryObjectuiv(query.0.get(), parameter, &mut default);
2749 default
2750 }
2751
2752 unsafe fn create_transform_feedback(&self) -> Result<Self::TransformFeedback, String> {
2753 let gl = &self.raw;
2754 let mut name = 0;
2755 gl.GenTransformFeedbacks(1, &mut name);
2756 Ok(NativeTransformFeedback(non_zero_gl_name(name)))
2757 }
2758
2759 unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) {
2760 let gl = &self.raw;
2761 gl.DeleteTransformFeedbacks(1, &transform_feedback.0.get());
2762 }
2763
2764 unsafe fn bind_transform_feedback(
2765 &self,
2766 target: u32,
2767 transform_feedback: Option<Self::TransformFeedback>,
2768 ) {
2769 let gl = &self.raw;
2770 gl.BindTransformFeedback(target, transform_feedback.map(|tf| tf.0.get()).unwrap_or(0));
2771 }
2772
2773 unsafe fn begin_transform_feedback(&self, primitive_mode: u32) {
2774 let gl = &self.raw;
2775 gl.BeginTransformFeedback(primitive_mode);
2776 }
2777
2778 unsafe fn end_transform_feedback(&self) {
2779 let gl = &self.raw;
2780 gl.EndTransformFeedback();
2781 }
2782
2783 unsafe fn pause_transform_feedback(&self) {
2784 let gl = &self.raw;
2785 gl.PauseTransformFeedback();
2786 }
2787
2788 unsafe fn resume_transform_feedback(&self) {
2789 let gl = &self.raw;
2790 gl.ResumeTransformFeedback();
2791 }
2792
2793 unsafe fn transform_feedback_varyings(
2794 &self,
2795 program: Self::Program,
2796 varyings: &[&str],
2797 buffer_mode: u32,
2798 ) {
2799 let gl = &self.raw;
2800
2801 let strings: Vec<CString> = varyings
2802 .iter()
2803 .copied()
2804 .map(CString::new)
2805 .collect::<Result<_, _>>()
2806 .unwrap();
2807 let varyings: Vec<_> = strings.iter().map(|c_str| c_str.as_ptr()).collect();
2808
2809 gl.TransformFeedbackVaryings(
2810 program.0.get(),
2811 varyings.len() as i32,
2812 varyings.as_ptr(),
2813 buffer_mode,
2814 );
2815 }
2816
2817 unsafe fn get_transform_feedback_varying(
2818 &self,
2819 program: Self::Program,
2820 index: u32,
2821 ) -> Option<ActiveTransformFeedback> {
2822 let gl = &self.raw;
2823
2824 const buf_size: usize = 256;
2825 const bytes: [u8; buf_size] = [0; buf_size];
2826
2827 let size: i32 = 0;
2828 let tftype: u32 = 0;
2829 let c_name = CString::new(bytes.to_vec()).unwrap();
2830 let c_name_buf = c_name.into_raw();
2831
2832 gl.GetTransformFeedbackVarying(
2833 program.0.get(),
2834 index,
2835 buf_size as i32,
2836 std::ptr::null_mut(),
2837 size as *mut i32,
2838 tftype as *mut u32,
2839 c_name_buf,
2840 );
2841
2842 let name = CString::from_raw(c_name_buf).into_string().unwrap();
2843
2844 Some(ActiveTransformFeedback { size, tftype, name })
2845 }
2846
2847 unsafe fn memory_barrier(&self, barriers: u32) {
2848 let gl = &self.raw;
2849 gl.MemoryBarrier(barriers);
2850 }
2851
2852 unsafe fn memory_barrier_by_region(&self, barriers: u32) {
2853 let gl = &self.raw;
2854 gl.MemoryBarrierByRegion(barriers);
2855 }
2856
2857 unsafe fn bind_image_texture(
2858 &self,
2859 unit: u32,
2860 texture: Self::Texture,
2861 level: i32,
2862 layered: bool,
2863 layer: i32,
2864 access: u32,
2865 format: u32,
2866 ) {
2867 let gl = &self.raw;
2868 gl.BindImageTexture(
2869 unit,
2870 texture.0.get(),
2871 level,
2872 layered as u8,
2873 layer,
2874 access,
2875 format,
2876 );
2877 }
2878 unsafe fn get_active_uniform_block_parameter_i32(
2879 &self,
2880 program: Self::Program,
2881 uniform_block_index: u32,
2882 parameter: u32,
2883 ) -> i32 {
2884 let gl = &self.raw;
2885 let mut value = 0;
2886 gl.GetActiveUniformBlockiv(program.0.get(), uniform_block_index, parameter, &mut value);
2887 value
2888 }
2889
2890 unsafe fn get_active_uniform_block_parameter_i32_slice(
2891 &self,
2892 program: Self::Program,
2893 uniform_block_index: u32,
2894 parameter: u32,
2895 out: &mut [i32],
2896 ) {
2897 let gl = &self.raw;
2898 gl.GetActiveUniformBlockiv(
2899 program.0.get(),
2900 uniform_block_index,
2901 parameter,
2902 out.as_mut_ptr(),
2903 );
2904 }
2905 unsafe fn get_active_uniform_block_name(
2906 &self,
2907 program: Self::Program,
2908 uniform_block_index: u32,
2909 ) -> String {
2910 let gl = &self.raw;
2911
2912 let len = self.get_active_uniform_block_parameter_i32(
2917 program,
2918 uniform_block_index,
2919 crate::UNIFORM_BLOCK_NAME_LENGTH,
2920 );
2921 let len = if gl.GetError() == crate::NO_ERROR && len > 0 {
2922 len as usize
2923 } else {
2924 256
2925 };
2926
2927 let mut buffer = vec![0; len];
2928 let mut length = 0;
2929 gl.GetActiveUniformBlockName(
2930 program.0.get(),
2931 uniform_block_index,
2932 buffer.len() as _,
2933 &mut length,
2934 buffer.as_mut_ptr(),
2935 );
2936
2937 if length > 0 {
2938 assert_eq!(
2939 std::mem::size_of::<u8>(),
2940 std::mem::size_of::<native_gl::GLchar>(),
2941 "This operation is only safe in systems in which the length of \
2942 a GLchar is the same as that of an u8"
2943 );
2944 assert_eq!(
2945 std::mem::align_of::<u8>(),
2946 std::mem::align_of::<native_gl::GLchar>(),
2947 "This operation is only safe in systems in which the alignment \
2948 of a GLchar is the same as that of an u8"
2949 );
2950 let buffer = std::slice::from_raw_parts(
2951 buffer.as_ptr() as *const u8,
2952 (length as usize + 1).min(buffer.len()),
2953 );
2954
2955 let name = CStr::from_bytes_with_nul(&buffer[..])
2956 .unwrap()
2957 .to_str()
2958 .unwrap()
2959 .to_owned();
2960
2961 name
2962 } else {
2963 String::from("")
2964 }
2965 }
2966}
2967
2968extern "system" fn raw_debug_message_callback<F>(
2969 source: u32,
2970 gltype: u32,
2971 id: u32,
2972 severity: u32,
2973 length: i32,
2974 message: *const native_gl::GLchar,
2975 user_param: *mut std::ffi::c_void,
2976) where
2977 F: FnMut(u32, u32, u32, u32, &str),
2978{
2979 std::panic::catch_unwind(move || unsafe {
2980 let callback: &mut F = &mut *(user_param as *mut _);
2981 let slice = std::slice::from_raw_parts(message as *const u8, length as usize);
2982 let msg = std::str::from_utf8(slice).unwrap();
2983 (callback)(source, gltype, id, severity, msg);
2984 })
2985 .ok();
2986}