1#![allow(unused_variables)]
2use alloc::{
3 boxed::Box,
4 rc::Rc,
5 string::{String, ToString},
6 vec::Vec,
7};
8use core::{
9 ffi, fmt,
10 hash::{Hash, Hasher},
11 sync::atomic::{AtomicUsize, Ordering as AtomicOrdering},
12};
13
14use azul_css::{
15 props::{
16 basic::{ColorF, ColorU},
17 style::StyleTransformVec,
18 },
19 AzString, OptionUsize, StringVec, U8Vec,
20};
21pub use gl_context_loader::{
22 ctypes::*, gl, GLeglImageOES, GLsync, GLvoid, GenericGlContext, GlType as GlContextGlType,
23};
24
25pub use crate::glconst::*;
26use crate::{
27 geom::PhysicalSizeU32,
28 hit_test::DocumentId,
29 resources::{Epoch, ExternalImageId, ImageDescriptor, ImageDescriptorFlags, RawImageFormat},
30 svg::{TessellatedGPUSvgNode, TessellatedSvgNode},
31 window::RendererType,
32 FastHashMap,
33};
34
35pub type GLuint = u32;
36pub type GLint = i32;
37pub type GLint64 = i64;
38pub type GLuint64 = u64;
39pub type GLenum = u32;
40pub type GLintptr = isize;
41pub type GLboolean = u8;
42pub type GLsizeiptr = isize;
43pub type GLbitfield = u32;
44pub type GLsizei = i32;
45pub type GLclampf = f32;
46pub type GLfloat = f32;
47
48pub const GL_RESTART_INDEX: u32 = core::u32::MAX;
49
50#[repr(C)]
53#[derive(Debug)]
54pub struct GlVoidPtrConst {
55 pub ptr: *const GLvoid,
56 pub run_destructor: bool,
57}
58
59impl Clone for GlVoidPtrConst {
60 fn clone(&self) -> Self {
61 Self {
62 ptr: self.ptr,
63 run_destructor: true,
64 }
65 }
66}
67
68impl Drop for GlVoidPtrConst {
69 fn drop(&mut self) {
70 self.run_destructor = false;
71 }
72}
73
74#[repr(C)]
79#[derive(Debug)]
80pub struct GlVoidPtrMut {
81 pub ptr: *mut GLvoid,
82}
83
84impl Clone for GlVoidPtrMut {
85 fn clone(&self) -> Self {
86 Self { ptr: self.ptr }
87 }
88}
89
90#[repr(C)]
92pub struct Refstr {
93 pub ptr: *const u8,
94 pub len: usize,
95}
96
97impl Clone for Refstr {
98 fn clone(&self) -> Self {
99 Self {
100 ptr: self.ptr,
101 len: self.len,
102 }
103 }
104}
105
106impl core::fmt::Debug for Refstr {
107 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
108 self.as_str().fmt(f)
109 }
110}
111
112impl Refstr {
113 pub fn as_str(&self) -> &str {
114 unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(self.ptr, self.len)) }
115 }
116}
117
118impl From<&str> for Refstr {
119 fn from(s: &str) -> Self {
120 Self {
121 ptr: s.as_ptr(),
122 len: s.len(),
123 }
124 }
125}
126
127#[repr(C)]
129pub struct RefstrVecRef {
130 pub ptr: *const Refstr,
131 pub len: usize,
132}
133
134impl Clone for RefstrVecRef {
135 fn clone(&self) -> Self {
136 Self {
137 ptr: self.ptr,
138 len: self.len,
139 }
140 }
141}
142
143impl core::fmt::Debug for RefstrVecRef {
144 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
145 self.as_slice().fmt(f)
146 }
147}
148
149impl RefstrVecRef {
150 pub fn as_slice(&self) -> &[Refstr] {
151 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
152 }
153}
154
155impl From<&[Refstr]> for RefstrVecRef {
156 fn from(s: &[Refstr]) -> Self {
157 Self {
158 ptr: s.as_ptr(),
159 len: s.len(),
160 }
161 }
162}
163
164#[repr(C)]
166pub struct GLint64VecRefMut {
167 pub ptr: *mut i64,
168 pub len: usize,
169}
170
171impl Clone for GLint64VecRefMut {
172 fn clone(&self) -> Self {
173 Self {
174 ptr: self.ptr,
175 len: self.len,
176 }
177 }
178}
179
180impl core::fmt::Debug for GLint64VecRefMut {
181 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
182 self.as_slice().fmt(f)
183 }
184}
185
186impl From<&mut [GLint64]> for GLint64VecRefMut {
187 fn from(s: &mut [GLint64]) -> Self {
188 Self {
189 ptr: s.as_mut_ptr(),
190 len: s.len(),
191 }
192 }
193}
194
195impl GLint64VecRefMut {
196 pub fn as_slice(&self) -> &[GLint64] {
197 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
198 }
199 fn as_mut_slice(&mut self) -> &mut [GLint64] {
200 unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
201 }
202}
203
204#[repr(C)]
206pub struct GLfloatVecRefMut {
207 pub ptr: *mut f32,
208 pub len: usize,
209}
210
211impl Clone for GLfloatVecRefMut {
212 fn clone(&self) -> Self {
213 Self {
214 ptr: self.ptr,
215 len: self.len,
216 }
217 }
218}
219
220impl core::fmt::Debug for GLfloatVecRefMut {
221 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
222 self.as_slice().fmt(f)
223 }
224}
225
226impl From<&mut [GLfloat]> for GLfloatVecRefMut {
227 fn from(s: &mut [GLfloat]) -> Self {
228 Self {
229 ptr: s.as_mut_ptr(),
230 len: s.len(),
231 }
232 }
233}
234
235impl GLfloatVecRefMut {
236 pub fn as_slice(&self) -> &[GLfloat] {
237 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
238 }
239 fn as_mut_slice(&mut self) -> &mut [GLfloat] {
240 unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
241 }
242}
243
244#[repr(C)]
246pub struct GLintVecRefMut {
247 pub ptr: *mut i32,
248 pub len: usize,
249}
250
251impl Clone for GLintVecRefMut {
252 fn clone(&self) -> Self {
253 Self {
254 ptr: self.ptr,
255 len: self.len,
256 }
257 }
258}
259
260impl core::fmt::Debug for GLintVecRefMut {
261 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
262 self.as_slice().fmt(f)
263 }
264}
265
266impl From<&mut [GLint]> for GLintVecRefMut {
267 fn from(s: &mut [GLint]) -> Self {
268 Self {
269 ptr: s.as_mut_ptr(),
270 len: s.len(),
271 }
272 }
273}
274
275impl GLintVecRefMut {
276 pub fn as_slice(&self) -> &[GLint] {
277 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
278 }
279 fn as_mut_slice(&mut self) -> &mut [GLint] {
280 unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
281 }
282}
283
284#[repr(C)]
286pub struct GLuintVecRef {
287 pub ptr: *const u32,
288 pub len: usize,
289}
290
291impl Clone for GLuintVecRef {
292 fn clone(&self) -> Self {
293 Self {
294 ptr: self.ptr,
295 len: self.len,
296 }
297 }
298}
299
300impl core::fmt::Debug for GLuintVecRef {
301 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
302 self.as_slice().fmt(f)
303 }
304}
305
306impl From<&[GLuint]> for GLuintVecRef {
307 fn from(s: &[GLuint]) -> Self {
308 Self {
309 ptr: s.as_ptr(),
310 len: s.len(),
311 }
312 }
313}
314
315impl GLuintVecRef {
316 pub fn as_slice(&self) -> &[GLuint] {
317 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
318 }
319}
320
321#[repr(C)]
323pub struct GLenumVecRef {
324 pub ptr: *const u32,
325 pub len: usize,
326}
327
328impl Clone for GLenumVecRef {
329 fn clone(&self) -> Self {
330 Self {
331 ptr: self.ptr,
332 len: self.len,
333 }
334 }
335}
336
337impl core::fmt::Debug for GLenumVecRef {
338 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
339 self.as_slice().fmt(f)
340 }
341}
342
343impl From<&[GLenum]> for GLenumVecRef {
344 fn from(s: &[GLenum]) -> Self {
345 Self {
346 ptr: s.as_ptr(),
347 len: s.len(),
348 }
349 }
350}
351
352impl GLenumVecRef {
353 pub fn as_slice(&self) -> &[GLenum] {
354 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
355 }
356}
357
358#[repr(C)]
360pub struct U8VecRef {
361 pub ptr: *const u8,
362 pub len: usize,
363}
364
365impl Clone for U8VecRef {
366 fn clone(&self) -> Self {
367 Self {
368 ptr: self.ptr,
369 len: self.len,
370 }
371 }
372}
373
374impl From<&[u8]> for U8VecRef {
375 fn from(s: &[u8]) -> Self {
376 Self {
377 ptr: s.as_ptr(),
378 len: s.len(),
379 }
380 }
381}
382
383impl U8VecRef {
384 pub fn as_slice(&self) -> &[u8] {
385 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
386 }
387}
388
389impl fmt::Debug for U8VecRef {
390 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391 self.as_slice().fmt(f)
392 }
393}
394
395impl PartialOrd for U8VecRef {
396 fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
397 self.as_slice().partial_cmp(rhs.as_slice())
398 }
399}
400
401impl Ord for U8VecRef {
402 fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
403 self.as_slice().cmp(rhs.as_slice())
404 }
405}
406
407impl PartialEq for U8VecRef {
408 fn eq(&self, rhs: &Self) -> bool {
409 self.as_slice().eq(rhs.as_slice())
410 }
411}
412
413impl Eq for U8VecRef {}
414
415impl core::hash::Hash for U8VecRef {
416 fn hash<H>(&self, state: &mut H)
417 where
418 H: core::hash::Hasher,
419 {
420 self.as_slice().hash(state)
421 }
422}
423
424#[repr(C)]
426pub struct F32VecRef {
427 pub ptr: *const f32,
428 pub len: usize,
429}
430
431impl Clone for F32VecRef {
432 fn clone(&self) -> Self {
433 Self {
434 ptr: self.ptr,
435 len: self.len,
436 }
437 }
438}
439
440impl core::fmt::Debug for F32VecRef {
441 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
442 self.as_slice().fmt(f)
443 }
444}
445
446impl From<&[f32]> for F32VecRef {
447 fn from(s: &[f32]) -> Self {
448 Self {
449 ptr: s.as_ptr(),
450 len: s.len(),
451 }
452 }
453}
454
455impl F32VecRef {
456 pub fn as_slice(&self) -> &[f32] {
457 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
458 }
459}
460
461#[repr(C)]
463pub struct I32VecRef {
464 pub ptr: *const i32,
465 pub len: usize,
466}
467
468impl Clone for I32VecRef {
469 fn clone(&self) -> Self {
470 Self {
471 ptr: self.ptr,
472 len: self.len,
473 }
474 }
475}
476
477impl core::fmt::Debug for I32VecRef {
478 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
479 self.as_slice().fmt(f)
480 }
481}
482
483impl From<&[i32]> for I32VecRef {
484 fn from(s: &[i32]) -> Self {
485 Self {
486 ptr: s.as_ptr(),
487 len: s.len(),
488 }
489 }
490}
491
492impl I32VecRef {
493 pub fn as_slice(&self) -> &[i32] {
494 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
495 }
496}
497
498#[repr(C)]
500pub struct GLbooleanVecRefMut {
501 pub ptr: *mut u8,
502 pub len: usize,
503}
504
505impl Clone for GLbooleanVecRefMut {
506 fn clone(&self) -> Self {
507 Self {
508 ptr: self.ptr,
509 len: self.len,
510 }
511 }
512}
513
514impl core::fmt::Debug for GLbooleanVecRefMut {
515 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
516 self.as_slice().fmt(f)
517 }
518}
519
520impl From<&mut [GLboolean]> for GLbooleanVecRefMut {
521 fn from(s: &mut [GLboolean]) -> Self {
522 Self {
523 ptr: s.as_mut_ptr(),
524 len: s.len(),
525 }
526 }
527}
528
529impl GLbooleanVecRefMut {
530 pub fn as_slice(&self) -> &[GLboolean] {
531 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
532 }
533 fn as_mut_slice(&mut self) -> &mut [GLboolean] {
534 unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
535 }
536}
537
538#[repr(C)]
540pub struct U8VecRefMut {
541 pub ptr: *mut u8,
542 pub len: usize,
543}
544
545impl Clone for U8VecRefMut {
546 fn clone(&self) -> Self {
547 Self {
548 ptr: self.ptr,
549 len: self.len,
550 }
551 }
552}
553
554impl core::fmt::Debug for U8VecRefMut {
555 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
556 self.as_slice().fmt(f)
557 }
558}
559
560impl From<&mut [u8]> for U8VecRefMut {
561 fn from(s: &mut [u8]) -> Self {
562 Self {
563 ptr: s.as_mut_ptr(),
564 len: s.len(),
565 }
566 }
567}
568
569impl U8VecRefMut {
570 pub fn as_slice(&self) -> &[u8] {
571 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
572 }
573 fn as_mut_slice(&mut self) -> &mut [u8] {
574 unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
575 }
576}
577
578impl_option!(
579 U8VecRef,
580 OptionU8VecRef,
581 copy = false,
582 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
583);
584
585#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
586#[repr(C)]
587pub struct DebugMessage {
588 pub message: AzString,
589 pub source: GLenum,
590 pub ty: GLenum,
591 pub id: GLenum,
592 pub severity: GLenum,
593}
594
595impl_vec!(
596 DebugMessage,
597 DebugMessageVec,
598 DebugMessageVecDestructor,
599 DebugMessageVecDestructorType
600);
601impl_vec_debug!(DebugMessage, DebugMessageVec);
602impl_vec_partialord!(DebugMessage, DebugMessageVec);
603impl_vec_ord!(DebugMessage, DebugMessageVec);
604impl_vec_clone!(DebugMessage, DebugMessageVec, DebugMessageVecDestructor);
605impl_vec_partialeq!(DebugMessage, DebugMessageVec);
606impl_vec_eq!(DebugMessage, DebugMessageVec);
607impl_vec_hash!(DebugMessage, DebugMessageVec);
608
609impl_vec!(GLint, GLintVec, GLintVecDestructor, GLintVecDestructorType);
610impl_vec_debug!(GLint, GLintVec);
611impl_vec_partialord!(GLint, GLintVec);
612impl_vec_ord!(GLint, GLintVec);
613impl_vec_clone!(GLint, GLintVec, GLintVecDestructor);
614impl_vec_partialeq!(GLint, GLintVec);
615impl_vec_eq!(GLint, GLintVec);
616impl_vec_hash!(GLint, GLintVec);
617
618impl_vec!(
619 GLuint,
620 GLuintVec,
621 GLuintVecDestructor,
622 GLuintVecDestructorType
623);
624impl_vec_debug!(GLuint, GLuintVec);
625impl_vec_partialord!(GLuint, GLuintVec);
626impl_vec_ord!(GLuint, GLuintVec);
627impl_vec_clone!(GLuint, GLuintVec, GLuintVecDestructor);
628impl_vec_partialeq!(GLuint, GLuintVec);
629impl_vec_eq!(GLuint, GLuintVec);
630impl_vec_hash!(GLuint, GLuintVec);
631
632#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
633#[repr(C)]
634pub enum GlType {
635 Gl,
636 Gles,
637}
638
639impl From<GlContextGlType> for GlType {
640 fn from(a: GlContextGlType) -> GlType {
641 match a {
642 GlContextGlType::Gl => GlType::Gl,
643 GlContextGlType::GlEs => GlType::Gles,
644 }
645 }
646}
647
648#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
650#[repr(C)]
651pub struct GetProgramBinaryReturn {
652 pub _0: U8Vec,
653 pub _1: u32,
654}
655
656#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
658#[repr(C)]
659pub struct GetActiveAttribReturn {
660 pub _0: i32,
661 pub _1: u32,
662 pub _2: AzString,
663}
664
665#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
667#[repr(C)]
668pub struct GetActiveUniformReturn {
669 pub _0: i32,
670 pub _1: u32,
671 pub _2: AzString,
672}
673
674#[repr(C)]
675pub struct GLsyncPtr {
676 pub ptr: *const c_void, pub run_destructor: bool,
678}
679
680impl Clone for GLsyncPtr {
681 fn clone(&self) -> Self {
682 Self {
683 ptr: self.ptr,
684 run_destructor: true,
685 }
686 }
687}
688
689impl core::fmt::Debug for GLsyncPtr {
690 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
691 write!(f, "0x{:0x}", self.ptr as usize)
692 }
693}
694
695impl GLsyncPtr {
696 pub fn new(p: GLsync) -> Self {
697 Self {
698 ptr: p as *const c_void,
699 run_destructor: true,
700 }
701 }
702 pub fn get(self) -> GLsync {
703 self.ptr as GLsync
704 }
705}
706
707impl Drop for GLsyncPtr {
708 fn drop(&mut self) {
709 self.run_destructor = false;
710 }
711}
712
713pub type GlTextureStorage = FastHashMap<Epoch, FastHashMap<ExternalImageId, Texture>>;
716
717static mut ACTIVE_GL_TEXTURES: Option<FastHashMap<DocumentId, GlTextureStorage>> = None;
734
735pub fn insert_into_active_gl_textures(
740 document_id: DocumentId,
741 epoch: Epoch,
742 texture: Texture,
743) -> ExternalImageId {
744 let external_image_id = ExternalImageId::new();
745
746 unsafe {
747 if ACTIVE_GL_TEXTURES.is_none() {
748 ACTIVE_GL_TEXTURES = Some(FastHashMap::new());
749 }
750 let active_textures = ACTIVE_GL_TEXTURES.as_mut().unwrap();
751 let active_epochs = active_textures
752 .entry(document_id)
753 .or_insert_with(|| FastHashMap::new());
754 let active_textures_for_epoch = active_epochs
755 .entry(epoch)
756 .or_insert_with(|| FastHashMap::new());
757 active_textures_for_epoch.insert(external_image_id, texture);
758 }
759
760 external_image_id
761}
762
763pub fn gl_textures_remove_epochs_from_pipeline(document_id: &DocumentId, epoch: Epoch) {
766 unsafe {
768 let active_textures = match ACTIVE_GL_TEXTURES.as_mut() {
769 Some(s) => s,
770 None => return,
771 };
772
773 let active_epochs = match active_textures.get_mut(document_id) {
774 Some(s) => s,
775 None => return,
776 };
777
778 let mut epochs_to_remove = Vec::new();
781
782 for (gl_texture_epoch, _) in active_epochs.iter() {
783 if *gl_texture_epoch < epoch {
784 epochs_to_remove.push(*gl_texture_epoch);
785 }
786 }
787
788 for epoch in epochs_to_remove {
789 active_epochs.remove(&epoch);
790 }
791 }
792}
793
794pub fn remove_single_texture_from_active_gl_textures(
796 document_id: &DocumentId,
797 epoch: &Epoch,
798 external_image_id: &ExternalImageId,
799) -> Option<()> {
800 let mut active_textures = unsafe { ACTIVE_GL_TEXTURES.as_mut()? };
801 let mut epochs = active_textures.get_mut(document_id)?;
802 let mut images_in_epoch = epochs.get_mut(epoch)?;
803 images_in_epoch.remove(external_image_id);
804 Some(())
805}
806
807pub fn gl_textures_remove_active_pipeline(document_id: &DocumentId) {
809 unsafe {
810 let active_textures = match ACTIVE_GL_TEXTURES.as_mut() {
811 Some(s) => s,
812 None => return,
813 };
814 active_textures.remove(document_id);
815 }
816}
817
818pub fn gl_textures_clear_opengl_cache() {
820 unsafe {
821 ACTIVE_GL_TEXTURES = None;
822 }
823}
824
825pub fn get_opengl_texture(image_key: &ExternalImageId) -> Option<(GLuint, (f32, f32))> {
836 let active_textures = unsafe { ACTIVE_GL_TEXTURES.as_ref()? };
837 active_textures
838 .values()
839 .flat_map(|active_document| active_document.values())
840 .find_map(|active_epoch| active_epoch.get(image_key))
841 .map(|tex| {
842 (
843 tex.texture_id,
844 (tex.size.width as f32, tex.size.height as f32),
845 )
846 })
847}
848
849#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
851#[repr(C)]
852pub struct GlShaderPrecisionFormatReturn {
853 pub _0: GLint,
854 pub _1: GLint,
855 pub _2: GLint,
856}
857
858#[repr(C)]
859pub struct GlContextPtr {
860 pub ptr: Box<Rc<GlContextPtrInner>>,
861 pub renderer_type: RendererType,
863 pub run_destructor: bool,
864}
865
866impl Clone for GlContextPtr {
867 fn clone(&self) -> Self {
868 Self {
869 ptr: self.ptr.clone(),
870 renderer_type: self.renderer_type.clone(),
871 run_destructor: true,
872 }
873 }
874}
875
876impl Drop for GlContextPtr {
877 fn drop(&mut self) {
878 self.run_destructor = false;
879 }
880}
881
882impl GlContextPtr {
883 pub fn get_svg_shader(&self) -> GLuint {
884 self.ptr.svg_shader
885 }
886 pub fn get_fxaa_shader(&self) -> GLuint {
887 self.ptr.fxaa_shader
888 }
889}
890
891#[repr(C)]
892pub struct GlContextPtrInner {
893 pub ptr: Rc<GenericGlContext>,
894 pub svg_shader: GLuint,
896 pub svg_multicolor_shader: GLuint,
898 pub fxaa_shader: GLuint,
900}
901
902impl Drop for GlContextPtrInner {
903 fn drop(&mut self) {
904 self.ptr.delete_program(self.svg_shader);
905 self.ptr.delete_program(self.svg_multicolor_shader);
906 self.ptr.delete_program(self.fxaa_shader);
907 }
908}
909
910impl_option!(
911 GlContextPtr,
912 OptionGlContextPtr,
913 copy = false,
914 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord]
915);
916
917impl core::fmt::Debug for GlContextPtr {
918 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
919 write!(f, "0x{:0x}", self.as_usize())
920 }
921}
922
923static SVG_VERTEX_SHADER: &[u8] = b"#version 150
924
925#if __VERSION__ != 100
926 #define varying out
927 #define attribute in
928#endif
929
930uniform vec2 vBboxSize;
931uniform mat4 vTransformMatrix;
932
933attribute vec2 vAttrXY;
934
935void main() {
936 vec4 vTransposed = vec4(vAttrXY, 1.0, 1.0) * vTransformMatrix;
937 vec2 vTransposedInScreen = vTransposed.xy / vBboxSize;
938 vec2 vCalcFinal = (vTransposedInScreen * vec2(2.0)) - vec2(1.0);
939 gl_Position = vec4(vCalcFinal, 1.0, 1.0);
940}";
941
942static SVG_FRAGMENT_SHADER: &[u8] = b"#version 150
943
944precision highp float;
945
946uniform vec4 fDrawColor;
947
948#if __VERSION__ == 100
949 #define oFragColor gl_FragColor
950#else
951 out vec4 oFragColor;
952#endif
953
954void main() {
955 oFragColor = fDrawColor;
956}";
957
958static SVG_MULTICOLOR_VERTEX_SHADER: &[u8] = b"#version 150
959
960#if __VERSION__ != 100
961 #define varying out
962 #define attribute in
963#endif
964
965uniform vec2 vBboxSize;
966uniform mat4 vTransformMatrix;
967
968attribute vec3 vAttrXY;
969attribute vec4 vColor;
970varying vec4 fColor;
971
972void main() {
973 vec4 vTransposed = vec4(vAttrXY.xy, 1.0, 1.0) * vTransformMatrix;
974 vec2 vTransposedInScreen = vTransposed.xy / vBboxSize;
975 vec2 vCalcFinal = (vTransposedInScreen * vec2(2.0)) - vec2(1.0);
976 gl_Position = vec4(vCalcFinal, vAttrXY.z, 1.0);
977 fColor = vColor;
978}";
979
980static SVG_MULTICOLOR_FRAGMENT_SHADER: &[u8] = b"#version 150
981
982precision highp float;
983
984#if __VERSION__ != 100
985 #define varying out
986 #define attribute in
987#endif
988
989#if __VERSION__ == 100
990 #define oFragColor gl_FragColor
991#else
992 out vec4 oFragColor;
993#endif
994
995attribute vec4 fColor;
996
997void main() {
998 oFragColor = fColor;
999}";
1000
1001impl GlContextPtr {
1002 pub fn new(renderer_type: RendererType, gl_context: Rc<GenericGlContext>) -> Self {
1003 let vertex_shader_object = gl_context.create_shader(gl::VERTEX_SHADER);
1005 gl_context.shader_source(vertex_shader_object, &[SVG_VERTEX_SHADER]);
1006 gl_context.compile_shader(vertex_shader_object);
1007
1008 let fragment_shader_object = gl_context.create_shader(gl::FRAGMENT_SHADER);
1009 gl_context.shader_source(fragment_shader_object, &[SVG_FRAGMENT_SHADER]);
1010 gl_context.compile_shader(fragment_shader_object);
1011
1012 let svg_program_id = gl_context.create_program();
1013
1014 gl_context.attach_shader(svg_program_id, vertex_shader_object);
1015 gl_context.attach_shader(svg_program_id, fragment_shader_object);
1016 gl_context.bind_attrib_location(svg_program_id, 0, "vAttrXY".into());
1017 gl_context.link_program(svg_program_id);
1018
1019 gl_context.delete_shader(vertex_shader_object);
1020 gl_context.delete_shader(fragment_shader_object);
1021
1022 let vertex_shader_object = gl_context.create_shader(gl::VERTEX_SHADER);
1024 gl_context.shader_source(vertex_shader_object, &[SVG_MULTICOLOR_VERTEX_SHADER]);
1025 gl_context.compile_shader(vertex_shader_object);
1026
1027 let fragment_shader_object = gl_context.create_shader(gl::FRAGMENT_SHADER);
1028 gl_context.shader_source(fragment_shader_object, &[SVG_MULTICOLOR_FRAGMENT_SHADER]);
1029 gl_context.compile_shader(fragment_shader_object);
1030
1031 let svg_multicolor_program_id = gl_context.create_program();
1032
1033 gl_context.attach_shader(svg_multicolor_program_id, vertex_shader_object);
1034 gl_context.attach_shader(svg_multicolor_program_id, fragment_shader_object);
1035 gl_context.bind_attrib_location(svg_multicolor_program_id, 0, "vAttrXY".into());
1036 gl_context.bind_attrib_location(svg_multicolor_program_id, 1, "vColor".into());
1037 gl_context.link_program(svg_multicolor_program_id);
1038
1039 gl_context.delete_shader(vertex_shader_object);
1040 gl_context.delete_shader(fragment_shader_object);
1041
1042 use crate::gl_fxaa::{FXAA_FRAGMENT_SHADER, FXAA_VERTEX_SHADER};
1044
1045 let vertex_shader_object = gl_context.create_shader(gl::VERTEX_SHADER);
1046 gl_context.shader_source(vertex_shader_object, &[FXAA_VERTEX_SHADER]);
1047 gl_context.compile_shader(vertex_shader_object);
1048
1049 let fragment_shader_object = gl_context.create_shader(gl::FRAGMENT_SHADER);
1050 gl_context.shader_source(fragment_shader_object, &[FXAA_FRAGMENT_SHADER]);
1051 gl_context.compile_shader(fragment_shader_object);
1052
1053 let fxaa_program_id = gl_context.create_program();
1054
1055 gl_context.attach_shader(fxaa_program_id, vertex_shader_object);
1056 gl_context.attach_shader(fxaa_program_id, fragment_shader_object);
1057 gl_context.bind_attrib_location(fxaa_program_id, 0, "vAttrXY".into());
1058 gl_context.link_program(fxaa_program_id);
1059
1060 gl_context.delete_shader(vertex_shader_object);
1061 gl_context.delete_shader(fragment_shader_object);
1062
1063 Self {
1064 ptr: Box::new(Rc::new(GlContextPtrInner {
1065 svg_shader: svg_program_id,
1066 svg_multicolor_shader: svg_multicolor_program_id,
1067 fxaa_shader: fxaa_program_id,
1068 ptr: gl_context,
1069 })),
1070 renderer_type,
1071 run_destructor: true,
1072 }
1073 }
1074
1075 pub fn get<'a>(&'a self) -> &'a Rc<GenericGlContext> {
1076 &self.ptr.ptr
1077 }
1078 fn as_usize(&self) -> usize {
1079 (Rc::as_ptr(&self.ptr.ptr) as *const c_void) as usize
1080 }
1081}
1082
1083impl GlContextPtr {
1084 pub fn get_type(&self) -> GlType {
1085 self.get().get_type().into()
1086 }
1087 pub fn buffer_data_untyped(
1088 &self,
1089 target: GLenum,
1090 size: GLsizeiptr,
1091 data: GlVoidPtrConst,
1092 usage: GLenum,
1093 ) {
1094 self.get()
1095 .buffer_data_untyped(target, size, data.ptr, usage)
1096 }
1097 pub fn buffer_sub_data_untyped(
1098 &self,
1099 target: GLenum,
1100 offset: isize,
1101 size: GLsizeiptr,
1102 data: GlVoidPtrConst,
1103 ) {
1104 self.get()
1105 .buffer_sub_data_untyped(target, offset, size, data.ptr)
1106 }
1107 pub fn map_buffer(&self, target: GLenum, access: GLbitfield) -> GlVoidPtrMut {
1108 GlVoidPtrMut {
1109 ptr: self.get().map_buffer(target, access),
1110 }
1111 }
1112 pub fn map_buffer_range(
1113 &self,
1114 target: GLenum,
1115 offset: GLintptr,
1116 length: GLsizeiptr,
1117 access: GLbitfield,
1118 ) -> GlVoidPtrMut {
1119 GlVoidPtrMut {
1120 ptr: self.get().map_buffer_range(target, offset, length, access),
1121 }
1122 }
1123 pub fn unmap_buffer(&self, target: GLenum) -> GLboolean {
1124 self.get().unmap_buffer(target)
1125 }
1126 pub fn tex_buffer(&self, target: GLenum, internal_format: GLenum, buffer: GLuint) {
1127 self.get().tex_buffer(target, internal_format, buffer)
1128 }
1129 pub fn shader_source(&self, shader: GLuint, strings: StringVec) {
1130 fn str_to_bytes(input: &str) -> Vec<u8> {
1131 let mut v: Vec<u8> = input.into();
1132 v.push(0);
1133 v
1134 }
1135 let shaders_as_bytes = strings
1136 .iter()
1137 .map(|s| str_to_bytes(s.as_str()))
1138 .collect::<Vec<_>>();
1139 let shaders_as_bytes = shaders_as_bytes
1140 .iter()
1141 .map(|s| s.as_ref())
1142 .collect::<Vec<_>>();
1143 self.get().shader_source(shader, &shaders_as_bytes)
1144 }
1145 pub fn read_buffer(&self, mode: GLenum) {
1146 self.get().read_buffer(mode)
1147 }
1148 pub fn read_pixels_into_buffer(
1149 &self,
1150 x: GLint,
1151 y: GLint,
1152 width: GLsizei,
1153 height: GLsizei,
1154 format: GLenum,
1155 pixel_type: GLenum,
1156 mut dst_buffer: U8VecRefMut,
1157 ) {
1158 self.get().read_pixels_into_buffer(
1159 x,
1160 y,
1161 width,
1162 height,
1163 format,
1164 pixel_type,
1165 dst_buffer.as_mut_slice(),
1166 )
1167 }
1168 pub fn read_pixels(
1169 &self,
1170 x: GLint,
1171 y: GLint,
1172 width: GLsizei,
1173 height: GLsizei,
1174 format: GLenum,
1175 pixel_type: GLenum,
1176 ) -> U8Vec {
1177 self.get()
1178 .read_pixels(x, y, width, height, format, pixel_type)
1179 .into()
1180 }
1181 pub fn read_pixels_into_pbo(
1182 &self,
1183 x: GLint,
1184 y: GLint,
1185 width: GLsizei,
1186 height: GLsizei,
1187 format: GLenum,
1188 pixel_type: GLenum,
1189 ) {
1190 unsafe {
1191 self.get()
1192 .read_pixels_into_pbo(x, y, width, height, format, pixel_type)
1193 }
1194 }
1195 pub fn sample_coverage(&self, value: GLclampf, invert: bool) {
1196 self.get().sample_coverage(value, invert)
1197 }
1198 pub fn polygon_offset(&self, factor: GLfloat, units: GLfloat) {
1199 self.get().polygon_offset(factor, units)
1200 }
1201 pub fn pixel_store_i(&self, name: GLenum, param: GLint) {
1202 self.get().pixel_store_i(name, param)
1203 }
1204 pub fn gen_buffers(&self, n: GLsizei) -> GLuintVec {
1205 self.get().gen_buffers(n).into()
1206 }
1207 pub fn gen_renderbuffers(&self, n: GLsizei) -> GLuintVec {
1208 self.get().gen_renderbuffers(n).into()
1209 }
1210 pub fn gen_framebuffers(&self, n: GLsizei) -> GLuintVec {
1211 self.get().gen_framebuffers(n).into()
1212 }
1213 pub fn gen_textures(&self, n: GLsizei) -> GLuintVec {
1214 self.get().gen_textures(n).into()
1215 }
1216 pub fn gen_vertex_arrays(&self, n: GLsizei) -> GLuintVec {
1217 self.get().gen_vertex_arrays(n).into()
1218 }
1219 pub fn gen_queries(&self, n: GLsizei) -> GLuintVec {
1220 self.get().gen_queries(n).into()
1221 }
1222 pub fn begin_query(&self, target: GLenum, id: GLuint) {
1223 self.get().begin_query(target, id)
1224 }
1225 pub fn end_query(&self, target: GLenum) {
1226 self.get().end_query(target)
1227 }
1228 pub fn query_counter(&self, id: GLuint, target: GLenum) {
1229 self.get().query_counter(id, target)
1230 }
1231 pub fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 {
1232 self.get().get_query_object_iv(id, pname)
1233 }
1234 pub fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 {
1235 self.get().get_query_object_uiv(id, pname)
1236 }
1237 pub fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 {
1238 self.get().get_query_object_i64v(id, pname)
1239 }
1240 pub fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 {
1241 self.get().get_query_object_ui64v(id, pname)
1242 }
1243 pub fn delete_queries(&self, queries: GLuintVecRef) {
1244 self.get().delete_queries(queries.as_slice())
1245 }
1246 pub fn delete_vertex_arrays(&self, vertex_arrays: GLuintVecRef) {
1247 self.get().delete_vertex_arrays(vertex_arrays.as_slice())
1248 }
1249 pub fn delete_buffers(&self, buffers: GLuintVecRef) {
1250 self.get().delete_buffers(buffers.as_slice())
1251 }
1252 pub fn delete_renderbuffers(&self, renderbuffers: GLuintVecRef) {
1253 self.get().delete_renderbuffers(renderbuffers.as_slice())
1254 }
1255 pub fn delete_framebuffers(&self, framebuffers: GLuintVecRef) {
1256 self.get().delete_framebuffers(framebuffers.as_slice())
1257 }
1258 pub fn delete_textures(&self, textures: GLuintVecRef) {
1259 self.get().delete_textures(textures.as_slice())
1260 }
1261 pub fn framebuffer_renderbuffer(
1262 &self,
1263 target: GLenum,
1264 attachment: GLenum,
1265 renderbuffertarget: GLenum,
1266 renderbuffer: GLuint,
1267 ) {
1268 self.get()
1269 .framebuffer_renderbuffer(target, attachment, renderbuffertarget, renderbuffer)
1270 }
1271 pub fn renderbuffer_storage(
1272 &self,
1273 target: GLenum,
1274 internalformat: GLenum,
1275 width: GLsizei,
1276 height: GLsizei,
1277 ) {
1278 self.get()
1279 .renderbuffer_storage(target, internalformat, width, height)
1280 }
1281 pub fn depth_func(&self, func: GLenum) {
1282 self.get().depth_func(func)
1283 }
1284 pub fn active_texture(&self, texture: GLenum) {
1285 self.get().active_texture(texture)
1286 }
1287 pub fn attach_shader(&self, program: GLuint, shader: GLuint) {
1288 self.get().attach_shader(program, shader)
1289 }
1290 pub fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) {
1291 self.get()
1292 .bind_attrib_location(program, index, name)
1293 }
1294 pub fn get_uniform_iv(&self, program: GLuint, location: GLint, mut result: GLintVecRefMut) {
1295 unsafe {
1296 self.get()
1297 .get_uniform_iv(program, location, result.as_mut_slice())
1298 }
1299 }
1300 pub fn get_uniform_fv(&self, program: GLuint, location: GLint, mut result: GLfloatVecRefMut) {
1301 unsafe {
1302 self.get()
1303 .get_uniform_fv(program, location, result.as_mut_slice())
1304 }
1305 }
1306 pub fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint {
1307 self.get().get_uniform_block_index(program, name)
1308 }
1309 pub fn get_uniform_indices(&self, program: GLuint, names: RefstrVecRef) -> GLuintVec {
1310 let names_vec = names
1311 .as_slice()
1312 .iter()
1313 .map(|n| n.as_str())
1314 .collect::<Vec<_>>();
1315 self.get().get_uniform_indices(program, &names_vec).into()
1316 }
1317 pub fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint) {
1318 self.get().bind_buffer_base(target, index, buffer)
1319 }
1320 pub fn bind_buffer_range(
1321 &self,
1322 target: GLenum,
1323 index: GLuint,
1324 buffer: GLuint,
1325 offset: GLintptr,
1326 size: GLsizeiptr,
1327 ) {
1328 self.get()
1329 .bind_buffer_range(target, index, buffer, offset, size)
1330 }
1331 pub fn uniform_block_binding(
1332 &self,
1333 program: GLuint,
1334 uniform_block_index: GLuint,
1335 uniform_block_binding: GLuint,
1336 ) {
1337 self.get()
1338 .uniform_block_binding(program, uniform_block_index, uniform_block_binding)
1339 }
1340 pub fn bind_buffer(&self, target: GLenum, buffer: GLuint) {
1341 self.get().bind_buffer(target, buffer)
1342 }
1343 pub fn bind_vertex_array(&self, vao: GLuint) {
1344 self.get().bind_vertex_array(vao)
1345 }
1346 pub fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) {
1347 self.get().bind_renderbuffer(target, renderbuffer)
1348 }
1349 pub fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) {
1350 self.get().bind_framebuffer(target, framebuffer)
1351 }
1352 pub fn bind_texture(&self, target: GLenum, texture: GLuint) {
1353 self.get().bind_texture(target, texture)
1354 }
1355 pub fn draw_buffers(&self, bufs: GLenumVecRef) {
1356 self.get().draw_buffers(bufs.as_slice())
1357 }
1358 pub fn tex_image_2d(
1359 &self,
1360 target: GLenum,
1361 level: GLint,
1362 internal_format: GLint,
1363 width: GLsizei,
1364 height: GLsizei,
1365 border: GLint,
1366 format: GLenum,
1367 ty: GLenum,
1368 opt_data: OptionU8VecRef,
1369 ) {
1370 let opt_data = opt_data.as_option();
1371 let opt_data: Option<&[u8]> = opt_data.map(|o| o.as_slice());
1372 self.get().tex_image_2d(
1373 target,
1374 level,
1375 internal_format,
1376 width,
1377 height,
1378 border,
1379 format,
1380 ty,
1381 opt_data,
1382 )
1383 }
1384 pub fn compressed_tex_image_2d(
1385 &self,
1386 target: GLenum,
1387 level: GLint,
1388 internal_format: GLenum,
1389 width: GLsizei,
1390 height: GLsizei,
1391 border: GLint,
1392 data: U8VecRef,
1393 ) {
1394 self.get().compressed_tex_image_2d(
1395 target,
1396 level,
1397 internal_format,
1398 width,
1399 height,
1400 border,
1401 data.as_slice(),
1402 )
1403 }
1404 pub fn compressed_tex_sub_image_2d(
1405 &self,
1406 target: GLenum,
1407 level: GLint,
1408 xoffset: GLint,
1409 yoffset: GLint,
1410 width: GLsizei,
1411 height: GLsizei,
1412 format: GLenum,
1413 data: U8VecRef,
1414 ) {
1415 self.get().compressed_tex_sub_image_2d(
1416 target,
1417 level,
1418 xoffset,
1419 yoffset,
1420 width,
1421 height,
1422 format,
1423 data.as_slice(),
1424 )
1425 }
1426 pub fn tex_image_3d(
1427 &self,
1428 target: GLenum,
1429 level: GLint,
1430 internal_format: GLint,
1431 width: GLsizei,
1432 height: GLsizei,
1433 depth: GLsizei,
1434 border: GLint,
1435 format: GLenum,
1436 ty: GLenum,
1437 opt_data: OptionU8VecRef,
1438 ) {
1439 let opt_data = opt_data.as_option();
1440 let opt_data: Option<&[u8]> = opt_data.map(|o| o.as_slice());
1441 self.get().tex_image_3d(
1442 target,
1443 level,
1444 internal_format,
1445 width,
1446 height,
1447 depth,
1448 border,
1449 format,
1450 ty,
1451 opt_data,
1452 )
1453 }
1454 pub fn copy_tex_image_2d(
1455 &self,
1456 target: GLenum,
1457 level: GLint,
1458 internal_format: GLenum,
1459 x: GLint,
1460 y: GLint,
1461 width: GLsizei,
1462 height: GLsizei,
1463 border: GLint,
1464 ) {
1465 self.get()
1466 .copy_tex_image_2d(target, level, internal_format, x, y, width, height, border)
1467 }
1468 pub fn copy_tex_sub_image_2d(
1469 &self,
1470 target: GLenum,
1471 level: GLint,
1472 xoffset: GLint,
1473 yoffset: GLint,
1474 x: GLint,
1475 y: GLint,
1476 width: GLsizei,
1477 height: GLsizei,
1478 ) {
1479 self.get()
1480 .copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height)
1481 }
1482 pub fn copy_tex_sub_image_3d(
1483 &self,
1484 target: GLenum,
1485 level: GLint,
1486 xoffset: GLint,
1487 yoffset: GLint,
1488 zoffset: GLint,
1489 x: GLint,
1490 y: GLint,
1491 width: GLsizei,
1492 height: GLsizei,
1493 ) {
1494 self.get().copy_tex_sub_image_3d(
1495 target, level, xoffset, yoffset, zoffset, x, y, width, height,
1496 )
1497 }
1498 pub fn tex_sub_image_2d(
1499 &self,
1500 target: GLenum,
1501 level: GLint,
1502 xoffset: GLint,
1503 yoffset: GLint,
1504 width: GLsizei,
1505 height: GLsizei,
1506 format: GLenum,
1507 ty: GLenum,
1508 data: U8VecRef,
1509 ) {
1510 self.get().tex_sub_image_2d(
1511 target,
1512 level,
1513 xoffset,
1514 yoffset,
1515 width,
1516 height,
1517 format,
1518 ty,
1519 data.as_slice(),
1520 )
1521 }
1522 pub fn tex_sub_image_2d_pbo(
1523 &self,
1524 target: GLenum,
1525 level: GLint,
1526 xoffset: GLint,
1527 yoffset: GLint,
1528 width: GLsizei,
1529 height: GLsizei,
1530 format: GLenum,
1531 ty: GLenum,
1532 offset: usize,
1533 ) {
1534 self.get().tex_sub_image_2d_pbo(
1535 target, level, xoffset, yoffset, width, height, format, ty, offset,
1536 )
1537 }
1538 pub fn tex_sub_image_3d(
1539 &self,
1540 target: GLenum,
1541 level: GLint,
1542 xoffset: GLint,
1543 yoffset: GLint,
1544 zoffset: GLint,
1545 width: GLsizei,
1546 height: GLsizei,
1547 depth: GLsizei,
1548 format: GLenum,
1549 ty: GLenum,
1550 data: U8VecRef,
1551 ) {
1552 self.get().tex_sub_image_3d(
1553 target,
1554 level,
1555 xoffset,
1556 yoffset,
1557 zoffset,
1558 width,
1559 height,
1560 depth,
1561 format,
1562 ty,
1563 data.as_slice(),
1564 )
1565 }
1566 pub fn tex_sub_image_3d_pbo(
1567 &self,
1568 target: GLenum,
1569 level: GLint,
1570 xoffset: GLint,
1571 yoffset: GLint,
1572 zoffset: GLint,
1573 width: GLsizei,
1574 height: GLsizei,
1575 depth: GLsizei,
1576 format: GLenum,
1577 ty: GLenum,
1578 offset: usize,
1579 ) {
1580 self.get().tex_sub_image_3d_pbo(
1581 target, level, xoffset, yoffset, zoffset, width, height, depth, format, ty, offset,
1582 )
1583 }
1584 pub fn tex_storage_2d(
1585 &self,
1586 target: GLenum,
1587 levels: GLint,
1588 internal_format: GLenum,
1589 width: GLsizei,
1590 height: GLsizei,
1591 ) {
1592 self.get()
1593 .tex_storage_2d(target, levels, internal_format, width, height)
1594 }
1595 pub fn tex_storage_3d(
1596 &self,
1597 target: GLenum,
1598 levels: GLint,
1599 internal_format: GLenum,
1600 width: GLsizei,
1601 height: GLsizei,
1602 depth: GLsizei,
1603 ) {
1604 self.get()
1605 .tex_storage_3d(target, levels, internal_format, width, height, depth)
1606 }
1607 pub fn get_tex_image_into_buffer(
1608 &self,
1609 target: GLenum,
1610 level: GLint,
1611 format: GLenum,
1612 ty: GLenum,
1613 mut output: U8VecRefMut,
1614 ) {
1615 self.get()
1616 .get_tex_image_into_buffer(target, level, format, ty, output.as_mut_slice())
1617 }
1618 pub fn copy_image_sub_data(
1619 &self,
1620 src_name: GLuint,
1621 src_target: GLenum,
1622 src_level: GLint,
1623 src_x: GLint,
1624 src_y: GLint,
1625 src_z: GLint,
1626 dst_name: GLuint,
1627 dst_target: GLenum,
1628 dst_level: GLint,
1629 dst_x: GLint,
1630 dst_y: GLint,
1631 dst_z: GLint,
1632 src_width: GLsizei,
1633 src_height: GLsizei,
1634 src_depth: GLsizei,
1635 ) {
1636 unsafe {
1637 self.get().copy_image_sub_data(
1638 src_name, src_target, src_level, src_x, src_y, src_z, dst_name, dst_target,
1639 dst_level, dst_x, dst_y, dst_z, src_width, src_height, src_depth,
1640 )
1641 }
1642 }
1643 pub fn invalidate_framebuffer(&self, target: GLenum, attachments: GLenumVecRef) {
1644 self.get()
1645 .invalidate_framebuffer(target, attachments.as_slice())
1646 }
1647 pub fn invalidate_sub_framebuffer(
1648 &self,
1649 target: GLenum,
1650 attachments: GLenumVecRef,
1651 xoffset: GLint,
1652 yoffset: GLint,
1653 width: GLsizei,
1654 height: GLsizei,
1655 ) {
1656 self.get().invalidate_sub_framebuffer(
1657 target,
1658 attachments.as_slice(),
1659 xoffset,
1660 yoffset,
1661 width,
1662 height,
1663 )
1664 }
1665 pub fn get_integer_v(&self, name: GLenum, mut result: GLintVecRefMut) {
1666 unsafe { self.get().get_integer_v(name, result.as_mut_slice()) }
1667 }
1668 pub fn get_integer_64v(&self, name: GLenum, mut result: GLint64VecRefMut) {
1669 unsafe { self.get().get_integer_64v(name, result.as_mut_slice()) }
1670 }
1671 pub fn get_integer_iv(&self, name: GLenum, index: GLuint, mut result: GLintVecRefMut) {
1672 unsafe {
1673 self.get()
1674 .get_integer_iv(name, index, result.as_mut_slice())
1675 }
1676 }
1677 pub fn get_integer_64iv(&self, name: GLenum, index: GLuint, mut result: GLint64VecRefMut) {
1678 unsafe {
1679 self.get()
1680 .get_integer_64iv(name, index, result.as_mut_slice())
1681 }
1682 }
1683 pub fn get_boolean_v(&self, name: GLenum, mut result: GLbooleanVecRefMut) {
1684 unsafe { self.get().get_boolean_v(name, result.as_mut_slice()) }
1685 }
1686 pub fn get_float_v(&self, name: GLenum, mut result: GLfloatVecRefMut) {
1687 unsafe { self.get().get_float_v(name, result.as_mut_slice()) }
1688 }
1689 pub fn get_framebuffer_attachment_parameter_iv(
1690 &self,
1691 target: GLenum,
1692 attachment: GLenum,
1693 pname: GLenum,
1694 ) -> GLint {
1695 self.get()
1696 .get_framebuffer_attachment_parameter_iv(target, attachment, pname)
1697 }
1698 pub fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
1699 self.get().get_renderbuffer_parameter_iv(target, pname)
1700 }
1701 pub fn get_tex_parameter_iv(&self, target: GLenum, name: GLenum) -> GLint {
1702 self.get().get_tex_parameter_iv(target, name)
1703 }
1704 pub fn get_tex_parameter_fv(&self, target: GLenum, name: GLenum) -> GLfloat {
1705 self.get().get_tex_parameter_fv(target, name)
1706 }
1707 pub fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) {
1708 self.get().tex_parameter_i(target, pname, param)
1709 }
1710 pub fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) {
1711 self.get().tex_parameter_f(target, pname, param)
1712 }
1713 pub fn framebuffer_texture_2d(
1714 &self,
1715 target: GLenum,
1716 attachment: GLenum,
1717 textarget: GLenum,
1718 texture: GLuint,
1719 level: GLint,
1720 ) {
1721 self.get()
1722 .framebuffer_texture_2d(target, attachment, textarget, texture, level)
1723 }
1724 pub fn framebuffer_texture_layer(
1725 &self,
1726 target: GLenum,
1727 attachment: GLenum,
1728 texture: GLuint,
1729 level: GLint,
1730 layer: GLint,
1731 ) {
1732 self.get()
1733 .framebuffer_texture_layer(target, attachment, texture, level, layer)
1734 }
1735 pub fn blit_framebuffer(
1736 &self,
1737 src_x0: GLint,
1738 src_y0: GLint,
1739 src_x1: GLint,
1740 src_y1: GLint,
1741 dst_x0: GLint,
1742 dst_y0: GLint,
1743 dst_x1: GLint,
1744 dst_y1: GLint,
1745 mask: GLbitfield,
1746 filter: GLenum,
1747 ) {
1748 self.get().blit_framebuffer(
1749 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
1750 )
1751 }
1752 pub fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1753 self.get().vertex_attrib_4f(index, x, y, z, w)
1754 }
1755 pub fn vertex_attrib_pointer_f32(
1756 &self,
1757 index: GLuint,
1758 size: GLint,
1759 normalized: bool,
1760 stride: GLsizei,
1761 offset: GLuint,
1762 ) {
1763 self.get()
1764 .vertex_attrib_pointer_f32(index, size, normalized, stride, offset)
1765 }
1766 pub fn vertex_attrib_pointer(
1767 &self,
1768 index: GLuint,
1769 size: GLint,
1770 type_: GLenum,
1771 normalized: bool,
1772 stride: GLsizei,
1773 offset: GLuint,
1774 ) {
1775 self.get()
1776 .vertex_attrib_pointer(index, size, type_, normalized, stride, offset)
1777 }
1778 pub fn vertex_attrib_i_pointer(
1779 &self,
1780 index: GLuint,
1781 size: GLint,
1782 type_: GLenum,
1783 stride: GLsizei,
1784 offset: GLuint,
1785 ) {
1786 self.get()
1787 .vertex_attrib_i_pointer(index, size, type_, stride, offset)
1788 }
1789 pub fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) {
1790 self.get().vertex_attrib_divisor(index, divisor)
1791 }
1792 pub fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1793 self.get().viewport(x, y, width, height)
1794 }
1795 pub fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1796 self.get().scissor(x, y, width, height)
1797 }
1798 pub fn line_width(&self, width: GLfloat) {
1799 self.get().line_width(width)
1800 }
1801 pub fn use_program(&self, program: GLuint) {
1802 self.get().use_program(program)
1803 }
1804 pub fn validate_program(&self, program: GLuint) {
1805 self.get().validate_program(program)
1806 }
1807 pub fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) {
1808 self.get().draw_arrays(mode, first, count)
1809 }
1810 pub fn draw_arrays_instanced(
1811 &self,
1812 mode: GLenum,
1813 first: GLint,
1814 count: GLsizei,
1815 primcount: GLsizei,
1816 ) {
1817 self.get()
1818 .draw_arrays_instanced(mode, first, count, primcount)
1819 }
1820 pub fn draw_elements(
1821 &self,
1822 mode: GLenum,
1823 count: GLsizei,
1824 element_type: GLenum,
1825 indices_offset: GLuint,
1826 ) {
1827 self.get()
1828 .draw_elements(mode, count, element_type, indices_offset)
1829 }
1830 pub fn draw_elements_instanced(
1831 &self,
1832 mode: GLenum,
1833 count: GLsizei,
1834 element_type: GLenum,
1835 indices_offset: GLuint,
1836 primcount: GLsizei,
1837 ) {
1838 self.get()
1839 .draw_elements_instanced(mode, count, element_type, indices_offset, primcount)
1840 }
1841 pub fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) {
1842 self.get().blend_color(r, g, b, a)
1843 }
1844 pub fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) {
1845 self.get().blend_func(sfactor, dfactor)
1846 }
1847 pub fn blend_func_separate(
1848 &self,
1849 src_rgb: GLenum,
1850 dest_rgb: GLenum,
1851 src_alpha: GLenum,
1852 dest_alpha: GLenum,
1853 ) {
1854 self.get()
1855 .blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha)
1856 }
1857 pub fn blend_equation(&self, mode: GLenum) {
1858 self.get().blend_equation(mode)
1859 }
1860 pub fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) {
1861 self.get().blend_equation_separate(mode_rgb, mode_alpha)
1862 }
1863 pub fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) {
1864 self.get().color_mask(r, g, b, a)
1865 }
1866 pub fn cull_face(&self, mode: GLenum) {
1867 self.get().cull_face(mode)
1868 }
1869 pub fn front_face(&self, mode: GLenum) {
1870 self.get().front_face(mode)
1871 }
1872 pub fn enable(&self, cap: GLenum) {
1873 self.get().enable(cap)
1874 }
1875 pub fn disable(&self, cap: GLenum) {
1876 self.get().disable(cap)
1877 }
1878 pub fn hint(&self, param_name: GLenum, param_val: GLenum) {
1879 self.get().hint(param_name, param_val)
1880 }
1881 pub fn is_enabled(&self, cap: GLenum) -> GLboolean {
1882 self.get().is_enabled(cap)
1883 }
1884 pub fn is_shader(&self, shader: GLuint) -> GLboolean {
1885 self.get().is_shader(shader)
1886 }
1887 pub fn is_texture(&self, texture: GLenum) -> GLboolean {
1888 self.get().is_texture(texture)
1889 }
1890 pub fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean {
1891 self.get().is_framebuffer(framebuffer)
1892 }
1893 pub fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean {
1894 self.get().is_renderbuffer(renderbuffer)
1895 }
1896 pub fn check_frame_buffer_status(&self, target: GLenum) -> GLenum {
1897 self.get().check_frame_buffer_status(target)
1898 }
1899 pub fn enable_vertex_attrib_array(&self, index: GLuint) {
1900 self.get().enable_vertex_attrib_array(index)
1901 }
1902 pub fn disable_vertex_attrib_array(&self, index: GLuint) {
1903 self.get().disable_vertex_attrib_array(index)
1904 }
1905 pub fn uniform_1f(&self, location: GLint, v0: GLfloat) {
1906 self.get().uniform_1f(location, v0)
1907 }
1908 pub fn uniform_1fv(&self, location: GLint, values: F32VecRef) {
1909 self.get().uniform_1fv(location, values.as_slice())
1910 }
1911 pub fn uniform_1i(&self, location: GLint, v0: GLint) {
1912 self.get().uniform_1i(location, v0)
1913 }
1914 pub fn uniform_1iv(&self, location: GLint, values: I32VecRef) {
1915 self.get().uniform_1iv(location, values.as_slice())
1916 }
1917 pub fn uniform_1ui(&self, location: GLint, v0: GLuint) {
1918 self.get().uniform_1ui(location, v0)
1919 }
1920 pub fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) {
1921 self.get().uniform_2f(location, v0, v1)
1922 }
1923 pub fn uniform_2fv(&self, location: GLint, values: F32VecRef) {
1924 self.get().uniform_2fv(location, values.as_slice())
1925 }
1926 pub fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) {
1927 self.get().uniform_2i(location, v0, v1)
1928 }
1929 pub fn uniform_2iv(&self, location: GLint, values: I32VecRef) {
1930 self.get().uniform_2iv(location, values.as_slice())
1931 }
1932 pub fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) {
1933 self.get().uniform_2ui(location, v0, v1)
1934 }
1935 pub fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) {
1936 self.get().uniform_3f(location, v0, v1, v2)
1937 }
1938 pub fn uniform_3fv(&self, location: GLint, values: F32VecRef) {
1939 self.get().uniform_3fv(location, values.as_slice())
1940 }
1941 pub fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) {
1942 self.get().uniform_3i(location, v0, v1, v2)
1943 }
1944 pub fn uniform_3iv(&self, location: GLint, values: I32VecRef) {
1945 self.get().uniform_3iv(location, values.as_slice())
1946 }
1947 pub fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) {
1948 self.get().uniform_3ui(location, v0, v1, v2)
1949 }
1950 pub fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1951 self.get().uniform_4f(location, x, y, z, w)
1952 }
1953 pub fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) {
1954 self.get().uniform_4i(location, x, y, z, w)
1955 }
1956 pub fn uniform_4iv(&self, location: GLint, values: I32VecRef) {
1957 self.get().uniform_4iv(location, values.as_slice())
1958 }
1959 pub fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) {
1960 self.get().uniform_4ui(location, x, y, z, w)
1961 }
1962 pub fn uniform_4fv(&self, location: GLint, values: F32VecRef) {
1963 self.get().uniform_4fv(location, values.as_slice())
1964 }
1965 pub fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: F32VecRef) {
1966 self.get()
1967 .uniform_matrix_2fv(location, transpose, value.as_slice())
1968 }
1969 pub fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: F32VecRef) {
1970 self.get()
1971 .uniform_matrix_3fv(location, transpose, value.as_slice())
1972 }
1973 pub fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: F32VecRef) {
1974 self.get()
1975 .uniform_matrix_4fv(location, transpose, value.as_slice())
1976 }
1977 pub fn depth_mask(&self, flag: bool) {
1978 self.get().depth_mask(flag)
1979 }
1980 pub fn depth_range(&self, near: f64, far: f64) {
1981 self.get().depth_range(near, far)
1982 }
1983 pub fn get_active_attrib(&self, program: GLuint, index: GLuint) -> GetActiveAttribReturn {
1984 let r = self.get().get_active_attrib(program, index);
1985 GetActiveAttribReturn {
1986 _0: r.0,
1987 _1: r.1,
1988 _2: r.2.into(),
1989 }
1990 }
1991 pub fn get_active_uniform(&self, program: GLuint, index: GLuint) -> GetActiveUniformReturn {
1992 let r = self.get().get_active_uniform(program, index);
1993 GetActiveUniformReturn {
1994 _0: r.0,
1995 _1: r.1,
1996 _2: r.2.into(),
1997 }
1998 }
1999 pub fn get_active_uniforms_iv(
2000 &self,
2001 program: GLuint,
2002 indices: GLuintVec,
2003 pname: GLenum,
2004 ) -> GLintVec {
2005 self.get()
2006 .get_active_uniforms_iv(program, indices.into_library_owned_vec(), pname)
2007 .into()
2008 }
2009 pub fn get_active_uniform_block_i(
2010 &self,
2011 program: GLuint,
2012 index: GLuint,
2013 pname: GLenum,
2014 ) -> GLint {
2015 self.get().get_active_uniform_block_i(program, index, pname)
2016 }
2017 pub fn get_active_uniform_block_iv(
2018 &self,
2019 program: GLuint,
2020 index: GLuint,
2021 pname: GLenum,
2022 ) -> GLintVec {
2023 self.get()
2024 .get_active_uniform_block_iv(program, index, pname)
2025 .into()
2026 }
2027 pub fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> AzString {
2028 self.get()
2029 .get_active_uniform_block_name(program, index)
2030 .into()
2031 }
2032 pub fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int {
2033 self.get().get_attrib_location(program, name)
2034 }
2035 pub fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int {
2036 self.get().get_frag_data_location(program, name)
2037 }
2038 pub fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int {
2039 self.get().get_uniform_location(program, name)
2040 }
2041 pub fn get_program_info_log(&self, program: GLuint) -> AzString {
2042 self.get().get_program_info_log(program).into()
2043 }
2044 pub fn get_program_iv(&self, program: GLuint, pname: GLenum, mut result: GLintVecRefMut) {
2045 unsafe {
2046 self.get()
2047 .get_program_iv(program, pname, result.as_mut_slice())
2048 }
2049 }
2050 pub fn get_program_binary(&self, program: GLuint) -> GetProgramBinaryReturn {
2051 let r = self.get().get_program_binary(program);
2052 GetProgramBinaryReturn {
2053 _0: r.0.into(),
2054 _1: r.1,
2055 }
2056 }
2057 pub fn program_binary(&self, program: GLuint, format: GLenum, binary: U8VecRef) {
2058 self.get()
2059 .program_binary(program, format, binary.as_slice())
2060 }
2061 pub fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint) {
2062 self.get().program_parameter_i(program, pname, value)
2063 }
2064 pub fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, mut result: GLintVecRefMut) {
2065 unsafe {
2066 self.get()
2067 .get_vertex_attrib_iv(index, pname, result.as_mut_slice())
2068 }
2069 }
2070 pub fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, mut result: GLfloatVecRefMut) {
2071 unsafe {
2072 self.get()
2073 .get_vertex_attrib_fv(index, pname, result.as_mut_slice())
2074 }
2075 }
2076 pub fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr {
2077 self.get().get_vertex_attrib_pointer_v(index, pname)
2078 }
2079 pub fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint {
2080 self.get().get_buffer_parameter_iv(target, pname)
2081 }
2082 pub fn get_shader_info_log(&self, shader: GLuint) -> AzString {
2083 self.get().get_shader_info_log(shader).into()
2084 }
2085 pub fn get_string(&self, which: GLenum) -> AzString {
2086 self.get().get_string(which).into()
2087 }
2088 pub fn get_string_i(&self, which: GLenum, index: GLuint) -> AzString {
2089 self.get().get_string_i(which, index).into()
2090 }
2091 pub fn get_shader_iv(&self, shader: GLuint, pname: GLenum, mut result: GLintVecRefMut) {
2092 unsafe {
2093 self.get()
2094 .get_shader_iv(shader, pname, result.as_mut_slice())
2095 }
2096 }
2097 pub fn get_shader_precision_format(
2098 &self,
2099 shader_type: GLuint,
2100 precision_type: GLuint,
2101 ) -> GlShaderPrecisionFormatReturn {
2102 let r = self
2103 .get()
2104 .get_shader_precision_format(shader_type, precision_type);
2105 GlShaderPrecisionFormatReturn {
2106 _0: r.0,
2107 _1: r.1,
2108 _2: r.2,
2109 }
2110 }
2111 pub fn compile_shader(&self, shader: GLuint) {
2112 self.get().compile_shader(shader)
2113 }
2114 pub fn create_program(&self) -> GLuint {
2115 self.get().create_program()
2116 }
2117 pub fn delete_program(&self, program: GLuint) {
2118 self.get().delete_program(program)
2119 }
2120 pub fn create_shader(&self, shader_type: GLenum) -> GLuint {
2121 self.get().create_shader(shader_type)
2122 }
2123 pub fn delete_shader(&self, shader: GLuint) {
2124 self.get().delete_shader(shader)
2125 }
2126 pub fn detach_shader(&self, program: GLuint, shader: GLuint) {
2127 self.get().detach_shader(program, shader)
2128 }
2129 pub fn link_program(&self, program: GLuint) {
2130 self.get().link_program(program)
2131 }
2132 pub fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) {
2133 self.get().clear_color(r, g, b, a)
2134 }
2135 pub fn clear(&self, buffer_mask: GLbitfield) {
2136 self.get().clear(buffer_mask)
2137 }
2138 pub fn clear_depth(&self, depth: f64) {
2139 self.get().clear_depth(depth)
2140 }
2141 pub fn clear_stencil(&self, s: GLint) {
2142 self.get().clear_stencil(s)
2143 }
2144 pub fn flush(&self) {
2145 self.get().flush()
2146 }
2147 pub fn finish(&self) {
2148 self.get().finish()
2149 }
2150 pub fn get_error(&self) -> GLenum {
2151 self.get().get_error()
2152 }
2153 pub fn stencil_mask(&self, mask: GLuint) {
2154 self.get().stencil_mask(mask)
2155 }
2156 pub fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) {
2157 self.get().stencil_mask_separate(face, mask)
2158 }
2159 pub fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) {
2160 self.get().stencil_func(func, ref_, mask)
2161 }
2162 pub fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) {
2163 self.get().stencil_func_separate(face, func, ref_, mask)
2164 }
2165 pub fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
2166 self.get().stencil_op(sfail, dpfail, dppass)
2167 }
2168 pub fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
2169 self.get().stencil_op_separate(face, sfail, dpfail, dppass)
2170 }
2171 pub fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GlVoidPtrConst) {
2172 self.get()
2173 .egl_image_target_texture2d_oes(target, image.ptr as *const gl_context_loader::c_void)
2174 }
2175 pub fn generate_mipmap(&self, target: GLenum) {
2176 self.get().generate_mipmap(target)
2177 }
2178 pub fn insert_event_marker_ext(&self, message: &str) {
2179 self.get().insert_event_marker_ext(message)
2180 }
2181 pub fn push_group_marker_ext(&self, message: &str) {
2182 self.get().push_group_marker_ext(message)
2183 }
2184 pub fn pop_group_marker_ext(&self) {
2185 self.get().pop_group_marker_ext()
2186 }
2187 pub fn debug_message_insert_khr(
2188 &self,
2189 source: GLenum,
2190 type_: GLenum,
2191 id: GLuint,
2192 severity: GLenum,
2193 message: &str,
2194 ) {
2195 self.get()
2196 .debug_message_insert_khr(source, type_, id, severity, message)
2197 }
2198 pub fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) {
2199 self.get()
2200 .push_debug_group_khr(source, id, message)
2201 }
2202 pub fn pop_debug_group_khr(&self) {
2203 self.get().pop_debug_group_khr()
2204 }
2205 pub fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsyncPtr {
2206 GLsyncPtr::new(self.get().fence_sync(condition, flags))
2207 }
2208 pub fn client_wait_sync(&self, sync: GLsyncPtr, flags: GLbitfield, timeout: GLuint64) -> u32 {
2209 self.get().client_wait_sync(sync.get(), flags, timeout)
2210 }
2211 pub fn wait_sync(&self, sync: GLsyncPtr, flags: GLbitfield, timeout: GLuint64) {
2212 self.get().wait_sync(sync.get(), flags, timeout)
2213 }
2214 pub fn delete_sync(&self, sync: GLsyncPtr) {
2215 self.get().delete_sync(sync.get())
2216 }
2217 pub fn texture_range_apple(&self, target: GLenum, data: U8VecRef) {
2218 self.get().texture_range_apple(target, data.as_slice())
2219 }
2220 pub fn gen_fences_apple(&self, n: GLsizei) -> GLuintVec {
2221 self.get().gen_fences_apple(n).into()
2222 }
2223 pub fn delete_fences_apple(&self, fences: GLuintVecRef) {
2224 self.get().delete_fences_apple(fences.as_slice())
2225 }
2226 pub fn set_fence_apple(&self, fence: GLuint) {
2227 self.get().set_fence_apple(fence)
2228 }
2229 pub fn finish_fence_apple(&self, fence: GLuint) {
2230 self.get().finish_fence_apple(fence)
2231 }
2232 pub fn test_fence_apple(&self, fence: GLuint) {
2233 self.get().test_fence_apple(fence)
2234 }
2235 pub fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean {
2236 self.get().test_object_apple(object, name)
2237 }
2238 pub fn finish_object_apple(&self, object: GLenum, name: GLuint) {
2239 self.get().finish_object_apple(object, name)
2240 }
2241 pub fn get_frag_data_index(&self, program: GLuint, name: &str) -> GLint {
2242 self.get().get_frag_data_index(program, name)
2243 }
2244 pub fn blend_barrier_khr(&self) {
2245 self.get().blend_barrier_khr()
2246 }
2247 pub fn bind_frag_data_location_indexed(
2248 &self,
2249 program: GLuint,
2250 color_number: GLuint,
2251 index: GLuint,
2252 name: &str,
2253 ) {
2254 self.get()
2255 .bind_frag_data_location_indexed(program, color_number, index, name)
2256 }
2257 pub fn get_debug_messages(&self) -> DebugMessageVec {
2258 let dmv: Vec<DebugMessage> = self
2259 .get()
2260 .get_debug_messages()
2261 .into_iter()
2262 .map(|d| DebugMessage {
2263 message: d.message.into(),
2264 source: d.source,
2265 ty: d.ty,
2266 id: d.ty,
2267 severity: d.severity,
2268 })
2269 .collect();
2270 dmv.into()
2271 }
2272 pub fn provoking_vertex_angle(&self, mode: GLenum) {
2273 self.get().provoking_vertex_angle(mode)
2274 }
2275 pub fn gen_vertex_arrays_apple(&self, n: GLsizei) -> GLuintVec {
2276 self.get().gen_vertex_arrays_apple(n).into()
2277 }
2278 pub fn bind_vertex_array_apple(&self, vao: GLuint) {
2279 self.get().bind_vertex_array_apple(vao)
2280 }
2281 pub fn delete_vertex_arrays_apple(&self, vertex_arrays: GLuintVecRef) {
2282 self.get()
2283 .delete_vertex_arrays_apple(vertex_arrays.as_slice())
2284 }
2285 pub fn copy_texture_chromium(
2286 &self,
2287 source_id: GLuint,
2288 source_level: GLint,
2289 dest_target: GLenum,
2290 dest_id: GLuint,
2291 dest_level: GLint,
2292 internal_format: GLint,
2293 dest_type: GLenum,
2294 unpack_flip_y: GLboolean,
2295 unpack_premultiply_alpha: GLboolean,
2296 unpack_unmultiply_alpha: GLboolean,
2297 ) {
2298 self.get().copy_texture_chromium(
2299 source_id,
2300 source_level,
2301 dest_target,
2302 dest_id,
2303 dest_level,
2304 internal_format,
2305 dest_type,
2306 unpack_flip_y,
2307 unpack_premultiply_alpha,
2308 unpack_unmultiply_alpha,
2309 )
2310 }
2311 pub fn copy_sub_texture_chromium(
2312 &self,
2313 source_id: GLuint,
2314 source_level: GLint,
2315 dest_target: GLenum,
2316 dest_id: GLuint,
2317 dest_level: GLint,
2318 x_offset: GLint,
2319 y_offset: GLint,
2320 x: GLint,
2321 y: GLint,
2322 width: GLsizei,
2323 height: GLsizei,
2324 unpack_flip_y: GLboolean,
2325 unpack_premultiply_alpha: GLboolean,
2326 unpack_unmultiply_alpha: GLboolean,
2327 ) {
2328 self.get().copy_sub_texture_chromium(
2329 source_id,
2330 source_level,
2331 dest_target,
2332 dest_id,
2333 dest_level,
2334 x_offset,
2335 y_offset,
2336 x,
2337 y,
2338 width,
2339 height,
2340 unpack_flip_y,
2341 unpack_premultiply_alpha,
2342 unpack_unmultiply_alpha,
2343 )
2344 }
2345 pub fn egl_image_target_renderbuffer_storage_oes(&self, target: u32, image: GlVoidPtrConst) {
2346 self.get().egl_image_target_renderbuffer_storage_oes(
2347 target,
2348 image.ptr as *const gl_context_loader::c_void,
2349 )
2350 }
2351 pub fn copy_texture_3d_angle(
2352 &self,
2353 source_id: GLuint,
2354 source_level: GLint,
2355 dest_target: GLenum,
2356 dest_id: GLuint,
2357 dest_level: GLint,
2358 internal_format: GLint,
2359 dest_type: GLenum,
2360 unpack_flip_y: GLboolean,
2361 unpack_premultiply_alpha: GLboolean,
2362 unpack_unmultiply_alpha: GLboolean,
2363 ) {
2364 self.get().copy_texture_3d_angle(
2365 source_id,
2366 source_level,
2367 dest_target,
2368 dest_id,
2369 dest_level,
2370 internal_format,
2371 dest_type,
2372 unpack_flip_y,
2373 unpack_premultiply_alpha,
2374 unpack_unmultiply_alpha,
2375 )
2376 }
2377 pub fn copy_sub_texture_3d_angle(
2378 &self,
2379 source_id: GLuint,
2380 source_level: GLint,
2381 dest_target: GLenum,
2382 dest_id: GLuint,
2383 dest_level: GLint,
2384 x_offset: GLint,
2385 y_offset: GLint,
2386 z_offset: GLint,
2387 x: GLint,
2388 y: GLint,
2389 z: GLint,
2390 width: GLsizei,
2391 height: GLsizei,
2392 depth: GLsizei,
2393 unpack_flip_y: GLboolean,
2394 unpack_premultiply_alpha: GLboolean,
2395 unpack_unmultiply_alpha: GLboolean,
2396 ) {
2397 self.get().copy_sub_texture_3d_angle(
2398 source_id,
2399 source_level,
2400 dest_target,
2401 dest_id,
2402 dest_level,
2403 x_offset,
2404 y_offset,
2405 z_offset,
2406 x,
2407 y,
2408 z,
2409 width,
2410 height,
2411 depth,
2412 unpack_flip_y,
2413 unpack_premultiply_alpha,
2414 unpack_unmultiply_alpha,
2415 )
2416 }
2417 pub fn buffer_storage(
2418 &self,
2419 target: GLenum,
2420 size: GLsizeiptr,
2421 data: GlVoidPtrConst,
2422 flags: GLbitfield,
2423 ) {
2424 self.get().buffer_storage(target, size, data.ptr, flags)
2425 }
2426 pub fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr) {
2427 self.get().flush_mapped_buffer_range(target, offset, length)
2428 }
2429}
2430
2431impl PartialEq for GlContextPtr {
2432 fn eq(&self, rhs: &Self) -> bool {
2433 self.as_usize().eq(&rhs.as_usize())
2434 }
2435}
2436
2437impl Eq for GlContextPtr {}
2438
2439impl PartialOrd for GlContextPtr {
2440 fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
2441 self.as_usize().partial_cmp(&rhs.as_usize())
2442 }
2443}
2444
2445impl Ord for GlContextPtr {
2446 fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
2447 self.as_usize().cmp(&rhs.as_usize())
2448 }
2449}
2450
2451#[repr(C)]
2453pub struct Texture {
2454 pub texture_id: GLuint,
2456 pub flags: TextureFlags,
2458 pub size: PhysicalSizeU32,
2460 pub background_color: ColorU,
2462 pub gl_context: GlContextPtr,
2465 pub format: RawImageFormat,
2467 pub refcount: *const AtomicUsize,
2469 pub run_destructor: bool,
2470}
2471
2472impl Clone for Texture {
2473 fn clone(&self) -> Self {
2474 unsafe {
2475 (*self.refcount).fetch_add(1, AtomicOrdering::SeqCst);
2476 }
2477 Self {
2478 texture_id: self.texture_id.clone(),
2479 flags: self.flags.clone(),
2480 size: self.size.clone(),
2481 background_color: self.background_color.clone(),
2482 gl_context: self.gl_context.clone(),
2483 format: self.format.clone(),
2484 refcount: self.refcount,
2485 run_destructor: true,
2486 }
2487 }
2488}
2489
2490impl_option!(
2491 Texture,
2492 OptionTexture,
2493 copy = false,
2494 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2495);
2496
2497impl Texture {
2498 pub fn create(
2499 texture_id: GLuint,
2500 flags: TextureFlags,
2501 size: PhysicalSizeU32,
2502 background_color: ColorU,
2503 gl_context: GlContextPtr,
2504 format: RawImageFormat,
2505 ) -> Self {
2506 Self {
2507 texture_id,
2508 flags,
2509 size,
2510 background_color,
2511 gl_context,
2512 format,
2513 refcount: Box::into_raw(Box::new(AtomicUsize::new(1))),
2514 run_destructor: true,
2515 }
2516 }
2517
2518 pub fn allocate_rgba8(
2519 gl_context: GlContextPtr,
2520 size: PhysicalSizeU32,
2521 background: ColorU,
2522 ) -> Self {
2523 let textures = gl_context.gen_textures(1);
2524 let texture_id = textures.as_ref()[0];
2525
2526 let mut current_texture_2d = [0_i32];
2527 gl_context.get_integer_v(gl::TEXTURE_2D, (&mut current_texture_2d[..]).into());
2528
2529 gl_context.bind_texture(gl::TEXTURE_2D, texture_id);
2530 gl_context.tex_image_2d(
2531 gl::TEXTURE_2D,
2532 0,
2533 gl::RGBA as i32,
2534 size.width as i32,
2535 size.height as i32,
2536 0,
2537 gl::RGBA,
2538 gl::UNSIGNED_BYTE,
2539 None.into(),
2540 );
2541 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
2542 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
2543 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32);
2544 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);
2545 gl_context.bind_texture(gl::TEXTURE_2D, current_texture_2d[0] as u32);
2546
2547 Self::create(
2548 texture_id,
2549 TextureFlags {
2550 is_opaque: false,
2551 is_video_texture: false,
2552 },
2553 size,
2554 background,
2555 gl_context,
2556 RawImageFormat::BGRA8,
2557 )
2558 }
2559
2560 pub fn clear(&mut self) {
2561 let mut current_multisample = [0_u8];
2563 let mut current_index_buffer = [0_i32];
2564 let mut current_vertex_buffer = [0_i32];
2565 let mut current_vertex_array_object = [0_i32];
2566 let mut current_program = [0_i32];
2567 let mut current_framebuffers = [0_i32];
2568 let mut current_renderbuffers = [0_i32];
2569 let mut current_texture_2d = [0_i32];
2570
2571 self.gl_context
2572 .get_boolean_v(gl::MULTISAMPLE, (&mut current_multisample[..]).into());
2573 self.gl_context.get_integer_v(
2574 gl::ARRAY_BUFFER_BINDING,
2575 (&mut current_vertex_buffer[..]).into(),
2576 );
2577 self.gl_context.get_integer_v(
2578 gl::ELEMENT_ARRAY_BUFFER_BINDING,
2579 (&mut current_index_buffer[..]).into(),
2580 );
2581 self.gl_context
2582 .get_integer_v(gl::CURRENT_PROGRAM, (&mut current_program[..]).into());
2583 self.gl_context.get_integer_v(
2584 gl::VERTEX_ARRAY_BINDING,
2585 (&mut current_vertex_array_object[..]).into(),
2586 );
2587 self.gl_context
2588 .get_integer_v(gl::RENDERBUFFER, (&mut current_renderbuffers[..]).into());
2589 self.gl_context
2590 .get_integer_v(gl::FRAMEBUFFER, (&mut current_framebuffers[..]).into());
2591 self.gl_context
2592 .get_integer_v(gl::TEXTURE_2D, (&mut current_texture_2d[..]).into());
2593
2594 let framebuffers = self.gl_context.gen_framebuffers(1);
2595 let framebuffer_id = framebuffers.get(0).unwrap();
2596 self.gl_context
2597 .bind_framebuffer(gl::FRAMEBUFFER, *framebuffer_id);
2598
2599 let depthbuffers = self.gl_context.gen_renderbuffers(1);
2600 let depthbuffer_id = depthbuffers.get(0).unwrap();
2601
2602 self.gl_context
2603 .bind_texture(gl::TEXTURE_2D, self.texture_id);
2604 self.gl_context.tex_image_2d(
2605 gl::TEXTURE_2D,
2606 0,
2607 gl::RGBA as i32, self.size.width as i32,
2609 self.size.height as i32,
2610 0,
2611 gl::RGBA, gl::UNSIGNED_BYTE,
2613 None.into(),
2614 );
2615 self.gl_context
2616 .tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
2617 self.gl_context
2618 .tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
2619 self.gl_context.tex_parameter_i(
2620 gl::TEXTURE_2D,
2621 gl::TEXTURE_WRAP_S,
2622 gl::CLAMP_TO_EDGE as i32,
2623 );
2624 self.gl_context.tex_parameter_i(
2625 gl::TEXTURE_2D,
2626 gl::TEXTURE_WRAP_T,
2627 gl::CLAMP_TO_EDGE as i32,
2628 );
2629
2630 self.gl_context
2631 .bind_renderbuffer(gl::RENDERBUFFER, *depthbuffer_id);
2632 self.gl_context.renderbuffer_storage(
2633 gl::RENDERBUFFER,
2634 gl::DEPTH_COMPONENT,
2635 self.size.width as i32,
2636 self.size.height as i32,
2637 );
2638 self.gl_context.framebuffer_renderbuffer(
2639 gl::FRAMEBUFFER,
2640 gl::DEPTH_ATTACHMENT,
2641 gl::RENDERBUFFER,
2642 *depthbuffer_id,
2643 );
2644
2645 self.gl_context.framebuffer_texture_2d(
2646 gl::FRAMEBUFFER,
2647 gl::COLOR_ATTACHMENT0,
2648 gl::TEXTURE_2D,
2649 self.texture_id,
2650 0,
2651 );
2652 self.gl_context
2653 .draw_buffers([gl::COLOR_ATTACHMENT0][..].into());
2654
2655 let clear_color: ColorF = self.background_color.into();
2656 self.gl_context
2657 .clear_color(clear_color.r, clear_color.g, clear_color.b, clear_color.a);
2658 self.gl_context.clear_depth(0.0);
2659 self.gl_context
2660 .clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
2661
2662 if u32::from(current_multisample[0]) == gl::TRUE {
2664 self.gl_context.enable(gl::MULTISAMPLE);
2665 }
2666 self.gl_context
2667 .bind_framebuffer(gl::FRAMEBUFFER, current_framebuffers[0] as u32);
2668 self.gl_context
2669 .bind_texture(gl::TEXTURE_2D, current_texture_2d[0] as u32);
2670 self.gl_context
2671 .bind_buffer(gl::RENDERBUFFER, current_renderbuffers[0] as u32);
2672 self.gl_context
2673 .bind_vertex_array(current_vertex_array_object[0] as u32);
2674 self.gl_context
2675 .bind_buffer(gl::ELEMENT_ARRAY_BUFFER, current_index_buffer[0] as u32);
2676 self.gl_context
2677 .bind_buffer(gl::ARRAY_BUFFER, current_vertex_buffer[0] as u32);
2678 self.gl_context.use_program(current_program[0] as u32);
2679
2680 self.gl_context
2681 .delete_framebuffers((&[*framebuffer_id])[..].into());
2682 self.gl_context
2683 .delete_renderbuffers((&[*depthbuffer_id])[..].into());
2684
2685 self.gl_context
2686 .bind_texture(gl::TEXTURE_2D, current_texture_2d[0] as u32);
2687 }
2688
2689 pub fn get_descriptor(&self) -> ImageDescriptor {
2690 ImageDescriptor {
2691 format: self.format,
2692 width: self.size.width as usize,
2693 height: self.size.height as usize,
2694 stride: None.into(),
2695 offset: 0,
2696 flags: ImageDescriptorFlags {
2697 is_opaque: self.flags.is_opaque,
2698 allow_mipmaps: false,
2700 },
2701 }
2702 }
2703
2704 pub fn draw_tesselated_svg_gpu_node(
2706 &mut self,
2707 node: &TessellatedGPUSvgNode,
2708 size: PhysicalSizeU32,
2709 color: ColorU,
2710 transforms: StyleTransformVec,
2711 ) -> bool {
2712 node.draw(self, size, color, transforms)
2713 }
2714
2715 pub fn draw_tesselated_colored_svg_gpu_node(
2717 &mut self,
2718 node: &crate::svg::TessellatedColoredGPUSvgNode,
2719 size: PhysicalSizeU32,
2720 transforms: StyleTransformVec,
2721 ) -> bool {
2722 node.draw(self, size, transforms)
2723 }
2724}
2725
2726#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2727#[repr(C)]
2728pub struct TextureFlags {
2729 pub is_opaque: bool,
2731 pub is_video_texture: bool,
2733}
2734
2735impl ::core::fmt::Display for Texture {
2736 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
2737 write!(
2738 f,
2739 "Texture {{ id: {}, {}x{} }}",
2740 self.texture_id, self.size.width, self.size.height
2741 )
2742 }
2743}
2744
2745macro_rules! impl_traits_for_gl_object {
2746 ($struct_name:ident, $gl_id_field:ident) => {
2747 impl ::core::fmt::Debug for $struct_name {
2748 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
2749 write!(f, "{}", self)
2750 }
2751 }
2752
2753 impl Hash for $struct_name {
2754 fn hash<H: Hasher>(&self, state: &mut H) {
2755 self.$gl_id_field.hash(state);
2756 }
2757 }
2758
2759 impl PartialEq for $struct_name {
2760 fn eq(&self, other: &$struct_name) -> bool {
2761 self.$gl_id_field == other.$gl_id_field
2762 }
2763 }
2764
2765 impl Eq for $struct_name {}
2766
2767 impl PartialOrd for $struct_name {
2768 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
2769 Some((self.$gl_id_field).cmp(&(other.$gl_id_field)))
2770 }
2771 }
2772
2773 impl Ord for $struct_name {
2774 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
2775 (self.$gl_id_field).cmp(&(other.$gl_id_field))
2776 }
2777 }
2778 };
2779 ($struct_name:ident < $lt:lifetime > , $gl_id_field:ident) => {
2780 impl<$lt> ::core::fmt::Debug for $struct_name<$lt> {
2781 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
2782 write!(f, "{}", self)
2783 }
2784 }
2785
2786 impl<$lt> Hash for $struct_name<$lt> {
2787 fn hash<H: Hasher>(&self, state: &mut H) {
2788 self.$gl_id_field.hash(state);
2789 }
2790 }
2791
2792 impl<$lt> PartialEq for $struct_name<$lt> {
2793 fn eq(&self, other: &$struct_name) -> bool {
2794 self.$gl_id_field == other.$gl_id_field
2795 }
2796 }
2797
2798 impl<$lt> Eq for $struct_name<$lt> {}
2799
2800 impl<$lt> PartialOrd for $struct_name<$lt> {
2801 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
2802 Some((self.$gl_id_field).cmp(&(other.$gl_id_field)))
2803 }
2804 }
2805
2806 impl<$lt> Ord for $struct_name<$lt> {
2807 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
2808 (self.$gl_id_field).cmp(&(other.$gl_id_field))
2809 }
2810 }
2811 };
2812 ($struct_name:ident < $t:ident : $constraint:ident > , $gl_id_field:ident) => {
2813 impl<$t: $constraint> ::core::fmt::Debug for $struct_name<$t> {
2814 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
2815 write!(f, "{}", self)
2816 }
2817 }
2818
2819 impl<$t: $constraint> Hash for $struct_name<$t> {
2820 fn hash<H: Hasher>(&self, state: &mut H) {
2821 self.$gl_id_field.hash(state);
2822 }
2823 }
2824
2825 impl<$t: $constraint> PartialEq for $struct_name<$t> {
2826 fn eq(&self, other: &$struct_name<$t>) -> bool {
2827 self.$gl_id_field == other.$gl_id_field
2828 }
2829 }
2830
2831 impl<$t: $constraint> Eq for $struct_name<$t> {}
2832
2833 impl<$t: $constraint> PartialOrd for $struct_name<$t> {
2834 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
2835 Some((self.$gl_id_field).cmp(&(other.$gl_id_field)))
2836 }
2837 }
2838
2839 impl<$t: $constraint> Ord for $struct_name<$t> {
2840 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
2841 (self.$gl_id_field).cmp(&(other.$gl_id_field))
2842 }
2843 }
2844 };
2845}
2846
2847impl_traits_for_gl_object!(Texture, texture_id);
2848
2849impl Drop for Texture {
2850 fn drop(&mut self) {
2851 self.run_destructor = false;
2852 let copies = unsafe { (*self.refcount).fetch_sub(1, AtomicOrdering::SeqCst) };
2853 if copies == 1 {
2854 let _ = unsafe { Box::from_raw(self.refcount as *mut AtomicUsize) };
2855 self.gl_context
2856 .delete_textures((&[self.texture_id])[..].into());
2857 }
2858 }
2859}
2860
2861#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2863#[repr(C)]
2864pub struct VertexLayout {
2865 pub fields: VertexAttributeVec,
2866}
2867
2868impl_vec!(
2869 VertexAttribute,
2870 VertexAttributeVec,
2871 VertexAttributeVecDestructor,
2872 VertexAttributeVecDestructorType
2873);
2874impl_vec_debug!(VertexAttribute, VertexAttributeVec);
2875impl_vec_partialord!(VertexAttribute, VertexAttributeVec);
2876impl_vec_ord!(VertexAttribute, VertexAttributeVec);
2877impl_vec_clone!(
2878 VertexAttribute,
2879 VertexAttributeVec,
2880 VertexAttributeVecDestructor
2881);
2882impl_vec_partialeq!(VertexAttribute, VertexAttributeVec);
2883impl_vec_eq!(VertexAttribute, VertexAttributeVec);
2884impl_vec_hash!(VertexAttribute, VertexAttributeVec);
2885
2886impl VertexLayout {
2887 pub fn bind(&self, gl_context: &Rc<GenericGlContext>, program_id: GLuint) {
2889 const VERTICES_ARE_NORMALIZED: bool = false;
2890
2891 let mut offset = 0;
2892
2893 let stride_between_vertices: usize =
2894 self.fields.iter().map(VertexAttribute::get_stride).sum();
2895
2896 for vertex_attribute in self.fields.iter() {
2897 let attribute_location = vertex_attribute
2898 .layout_location
2899 .as_option()
2900 .map(|ll| *ll as i32)
2901 .unwrap_or_else(|| {
2902 gl_context
2903 .get_attrib_location(program_id, vertex_attribute.va_name.as_str().into())
2904 });
2905
2906 gl_context.vertex_attrib_pointer(
2907 attribute_location as u32,
2908 vertex_attribute.item_count as i32,
2909 vertex_attribute.attribute_type.get_gl_id(),
2910 VERTICES_ARE_NORMALIZED,
2911 stride_between_vertices as i32,
2912 offset as u32,
2913 );
2914 gl_context.enable_vertex_attrib_array(attribute_location as u32);
2915 offset += vertex_attribute.get_stride();
2916 }
2917 }
2918
2919 pub fn unbind(&self, gl_context: &Rc<GenericGlContext>, program_id: GLuint) {
2921 for vertex_attribute in self.fields.iter() {
2922 let attribute_location = vertex_attribute
2923 .layout_location
2924 .as_option()
2925 .map(|ll| *ll as i32)
2926 .unwrap_or_else(|| {
2927 gl_context
2928 .get_attrib_location(program_id, vertex_attribute.va_name.as_str().into())
2929 });
2930 gl_context.disable_vertex_attrib_array(attribute_location as u32);
2931 }
2932 }
2933}
2934
2935#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2936#[repr(C)]
2937pub struct VertexAttribute {
2938 pub va_name: AzString,
2940 pub layout_location: OptionUsize,
2943 pub attribute_type: VertexAttributeType,
2946 pub item_count: usize,
2949}
2950
2951impl VertexAttribute {
2952 pub fn get_stride(&self) -> usize {
2953 self.attribute_type.get_mem_size() * self.item_count
2954 }
2955}
2956
2957#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2958#[repr(C)]
2959pub enum VertexAttributeType {
2960 Float,
2962 Double,
2964 UnsignedByte,
2966 UnsignedShort,
2968 UnsignedInt,
2970}
2971
2972impl VertexAttributeType {
2973 pub fn get_gl_id(&self) -> GLuint {
2976 use self::VertexAttributeType::*;
2977 match self {
2978 Float => gl::FLOAT,
2979 Double => gl::DOUBLE,
2980 UnsignedByte => gl::UNSIGNED_BYTE,
2981 UnsignedShort => gl::UNSIGNED_SHORT,
2982 UnsignedInt => gl::UNSIGNED_INT,
2983 }
2984 }
2985
2986 pub fn get_mem_size(&self) -> usize {
2987 use core::mem;
2988
2989 use self::VertexAttributeType::*;
2990 match self {
2991 Float => mem::size_of::<f32>(),
2992 Double => mem::size_of::<f64>(),
2993 UnsignedByte => mem::size_of::<u8>(),
2994 UnsignedShort => mem::size_of::<u16>(),
2995 UnsignedInt => mem::size_of::<u32>(),
2996 }
2997 }
2998}
2999
3000pub trait VertexLayoutDescription {
3001 fn get_description() -> VertexLayout;
3002}
3003
3004#[derive(Debug, PartialEq, PartialOrd)]
3005#[repr(C)]
3006pub struct VertexArrayObject {
3007 pub vertex_layout: VertexLayout,
3008 pub vao_id: GLuint,
3009 pub gl_context: GlContextPtr,
3010 pub refcount: *const AtomicUsize,
3011 pub run_destructor: bool,
3012}
3013
3014impl VertexArrayObject {
3015 pub fn new(vertex_layout: VertexLayout, vao_id: GLuint, gl_context: GlContextPtr) -> Self {
3016 Self {
3017 vertex_layout,
3018 vao_id,
3019 gl_context,
3020 refcount: Box::into_raw(Box::new(AtomicUsize::new(1))),
3021 run_destructor: true,
3022 }
3023 }
3024}
3025
3026impl Clone for VertexArrayObject {
3027 fn clone(&self) -> Self {
3028 unsafe { (*self.refcount).fetch_add(1, AtomicOrdering::SeqCst) };
3029 Self {
3030 vertex_layout: self.vertex_layout.clone(),
3031 vao_id: self.vao_id,
3032 gl_context: self.gl_context.clone(),
3033 refcount: self.refcount,
3034 run_destructor: true,
3035 }
3036 }
3037}
3038
3039impl Drop for VertexArrayObject {
3040 fn drop(&mut self) {
3041 self.run_destructor = false;
3042 let copies = unsafe { (*self.refcount).fetch_sub(1, AtomicOrdering::SeqCst) };
3043 if copies == 1 {
3044 let _ = unsafe { Box::from_raw(self.refcount as *mut AtomicUsize) };
3045 self.gl_context
3046 .delete_vertex_arrays((&[self.vao_id])[..].into());
3047 }
3048 }
3049}
3050
3051#[repr(C)]
3052pub struct VertexBuffer {
3053 pub vertex_buffer_id: GLuint,
3054 pub vertex_buffer_len: usize,
3055 pub vao: VertexArrayObject,
3056 pub index_buffer_id: GLuint,
3057 pub index_buffer_len: usize,
3058 pub index_buffer_format: IndexBufferFormat,
3059 pub refcount: *const AtomicUsize,
3060 pub run_destructor: bool,
3061}
3062
3063impl core::fmt::Display for VertexBuffer {
3064 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3065 write!(
3066 f,
3067 "VertexBuffer {{ buffer: {} (length: {}) }})",
3068 self.vertex_buffer_id, self.vertex_buffer_len
3069 )
3070 }
3071}
3072
3073impl_traits_for_gl_object!(VertexBuffer, vertex_buffer_id);
3074
3075impl Clone for VertexBuffer {
3076 fn clone(&self) -> Self {
3077 unsafe { (*self.refcount).fetch_add(1, AtomicOrdering::SeqCst) };
3078 Self {
3079 vertex_buffer_id: self.vertex_buffer_id.clone(),
3080 vertex_buffer_len: self.vertex_buffer_len.clone(),
3081 vao: self.vao.clone(),
3082 index_buffer_id: self.index_buffer_id.clone(),
3083 index_buffer_len: self.index_buffer_len.clone(),
3084 index_buffer_format: self.index_buffer_format.clone(),
3085 refcount: self.refcount,
3086 run_destructor: true,
3087 }
3088 }
3089}
3090
3091impl Drop for VertexBuffer {
3092 fn drop(&mut self) {
3093 self.run_destructor = false;
3094 let copies = unsafe { (*self.refcount).fetch_sub(1, AtomicOrdering::SeqCst) };
3095 if copies == 1 {
3096 self.vao.vertex_layout = VertexLayout {
3097 fields: VertexAttributeVec::from_const_slice(&[]),
3098 };
3099 let _ = unsafe { Box::from_raw(self.refcount as *mut AtomicUsize) };
3100 self.vao
3101 .gl_context
3102 .delete_buffers((&[self.vertex_buffer_id, self.index_buffer_id])[..].into());
3103 }
3104 }
3105}
3106
3107impl VertexBuffer {
3108 pub fn new<T: VertexLayoutDescription>(
3109 gl_context: GlContextPtr,
3110 shader_program_id: GLuint,
3111 vertices: &[T],
3112 indices: &[u32],
3113 index_buffer_format: IndexBufferFormat,
3114 ) -> Self {
3115 use core::mem;
3116
3117 let mut current_vertex_array = [0_i32];
3119 gl_context.get_integer_v(gl::VERTEX_ARRAY, (&mut current_vertex_array[..]).into());
3123 let vertex_array_object = gl_context.gen_vertex_arrays(1);
3128 let vertex_array_object = vertex_array_object.get(0).unwrap();
3129
3130 let vertex_buffer_id = gl_context.gen_buffers(1);
3131 let vertex_buffer_id = vertex_buffer_id.get(0).unwrap();
3132
3133 let index_buffer_id = gl_context.gen_buffers(1);
3134 let index_buffer_id = index_buffer_id.get(0).unwrap();
3135
3136 gl_context.bind_vertex_array(*vertex_array_object);
3137
3138 gl_context.bind_buffer(gl::ARRAY_BUFFER, *vertex_buffer_id);
3140 gl_context.buffer_data_untyped(
3141 gl::ARRAY_BUFFER,
3142 (mem::size_of::<T>() * vertices.len()) as isize,
3143 GlVoidPtrConst {
3144 ptr: vertices.as_ptr() as *const core::ffi::c_void,
3145 run_destructor: true,
3146 },
3147 gl::STATIC_DRAW,
3148 );
3149
3150 gl_context.bind_buffer(gl::ELEMENT_ARRAY_BUFFER, *index_buffer_id);
3152 gl_context.buffer_data_untyped(
3153 gl::ELEMENT_ARRAY_BUFFER,
3154 (mem::size_of::<u32>() * indices.len()) as isize,
3155 GlVoidPtrConst {
3156 ptr: indices.as_ptr() as *const core::ffi::c_void,
3157 run_destructor: true,
3158 },
3159 gl::STATIC_DRAW,
3160 );
3161
3162 let vertex_description = T::get_description();
3163 vertex_description.bind(&gl_context.ptr.ptr, shader_program_id);
3164
3165 gl_context.bind_vertex_array(current_vertex_array[0] as u32);
3169
3170 Self::new_raw(
3171 *vertex_buffer_id,
3172 vertices.len(),
3173 VertexArrayObject::new(vertex_description, *vertex_array_object, gl_context),
3174 *index_buffer_id,
3175 indices.len(),
3176 index_buffer_format,
3177 )
3178 }
3179
3180 pub fn new_raw(
3181 vertex_buffer_id: GLuint,
3182 vertex_buffer_len: usize,
3183 vao: VertexArrayObject,
3184 index_buffer_id: GLuint,
3185 index_buffer_len: usize,
3186 index_buffer_format: IndexBufferFormat,
3187 ) -> Self {
3188 Self {
3189 vertex_buffer_id,
3190 vertex_buffer_len,
3191 vao,
3192 index_buffer_id,
3193 index_buffer_len,
3194 index_buffer_format,
3195 refcount: Box::into_raw(Box::new(AtomicUsize::new(1))),
3196 run_destructor: true,
3197 }
3198 }
3199}
3200
3201#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3202pub enum GlApiVersion {
3203 Gl { major: usize, minor: usize },
3204 GlEs { major: usize, minor: usize },
3205}
3206
3207impl GlApiVersion {
3208 pub fn get(gl_context: &GlContextPtr) -> Self {
3210 let mut major = [0];
3211 gl_context.get_integer_v(gl::MAJOR_VERSION, (&mut major[..]).into());
3212 let mut minor = [0];
3213 gl_context.get_integer_v(gl::MINOR_VERSION, (&mut minor[..]).into());
3214
3215 GlApiVersion::Gl {
3216 major: major[0] as usize,
3217 minor: minor[0] as usize,
3218 }
3219 }
3220}
3221
3222#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3223#[repr(C)]
3224pub enum IndexBufferFormat {
3225 Points,
3226 Lines,
3227 LineStrip,
3228 Triangles,
3229 TriangleStrip,
3230 TriangleFan,
3231}
3232
3233impl IndexBufferFormat {
3234 pub fn get_gl_id(&self) -> GLuint {
3236 use self::IndexBufferFormat::*;
3237 match self {
3238 Points => gl::POINTS,
3239 Lines => gl::LINES,
3240 LineStrip => gl::LINE_STRIP,
3241 Triangles => gl::TRIANGLES,
3242 TriangleStrip => gl::TRIANGLE_STRIP,
3243 TriangleFan => gl::TRIANGLE_FAN,
3244 }
3245 }
3246}
3247
3248#[derive(Debug, Clone, PartialEq, PartialOrd)]
3249#[repr(C)]
3250pub struct Uniform {
3251 pub uniform_name: AzString,
3252 pub uniform_type: UniformType,
3253}
3254
3255impl Uniform {
3256 pub fn create<S: Into<AzString>>(name: S, uniform_type: UniformType) -> Self {
3257 Self {
3258 uniform_name: name.into(),
3259 uniform_type,
3260 }
3261 }
3262}
3263
3264#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
3265#[repr(C, u8)]
3266pub enum UniformType {
3267 Float(f32),
3268 FloatVec2([f32; 2]),
3269 FloatVec3([f32; 3]),
3270 FloatVec4([f32; 4]),
3271 Int(i32),
3272 IntVec2([i32; 2]),
3273 IntVec3([i32; 3]),
3274 IntVec4([i32; 4]),
3275 UnsignedInt(u32),
3276 UnsignedIntVec2([u32; 2]),
3277 UnsignedIntVec3([u32; 3]),
3278 UnsignedIntVec4([u32; 4]),
3279 Matrix2 {
3280 transpose: bool,
3281 matrix: [f32; 2 * 2],
3282 },
3283 Matrix3 {
3284 transpose: bool,
3285 matrix: [f32; 3 * 3],
3286 },
3287 Matrix4 {
3288 transpose: bool,
3289 matrix: [f32; 4 * 4],
3290 },
3291}
3292
3293impl UniformType {
3294 pub fn set(self, gl_context: &Rc<GenericGlContext>, location: GLint) {
3296 use self::UniformType::*;
3297 match self {
3298 Float(r) => gl_context.uniform_1f(location, r),
3299 FloatVec2([r, g]) => gl_context.uniform_2f(location, r, g),
3300 FloatVec3([r, g, b]) => gl_context.uniform_3f(location, r, g, b),
3301 FloatVec4([r, g, b, a]) => gl_context.uniform_4f(location, r, g, b, a),
3302 Int(r) => gl_context.uniform_1i(location, r),
3303 IntVec2([r, g]) => gl_context.uniform_2i(location, r, g),
3304 IntVec3([r, g, b]) => gl_context.uniform_3i(location, r, g, b),
3305 IntVec4([r, g, b, a]) => gl_context.uniform_4i(location, r, g, b, a),
3306 UnsignedInt(r) => gl_context.uniform_1ui(location, r),
3307 UnsignedIntVec2([r, g]) => gl_context.uniform_2ui(location, r, g),
3308 UnsignedIntVec3([r, g, b]) => gl_context.uniform_3ui(location, r, g, b),
3309 UnsignedIntVec4([r, g, b, a]) => gl_context.uniform_4ui(location, r, g, b, a),
3310 Matrix2 { transpose, matrix } => {
3311 gl_context.uniform_matrix_2fv(location, transpose, &matrix[..])
3312 }
3313 Matrix3 { transpose, matrix } => {
3314 gl_context.uniform_matrix_3fv(location, transpose, &matrix[..])
3315 }
3316 Matrix4 { transpose, matrix } => {
3317 gl_context.uniform_matrix_4fv(location, transpose, &matrix[..])
3318 }
3319 }
3320 }
3321}
3322
3323#[repr(C)]
3324pub struct GlShader {
3325 pub program_id: GLuint,
3326 pub gl_context: GlContextPtr,
3327}
3328
3329impl ::core::fmt::Display for GlShader {
3330 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3331 write!(f, "GlShader {{ program_id: {} }}", self.program_id)
3332 }
3333}
3334
3335impl_traits_for_gl_object!(GlShader, program_id);
3336
3337impl Drop for GlShader {
3338 fn drop(&mut self) {
3339 self.gl_context.delete_program(self.program_id);
3340 }
3341}
3342
3343#[repr(C)]
3344#[derive(Clone)]
3345pub struct VertexShaderCompileError {
3346 pub error_id: i32,
3347 pub info_log: AzString,
3348}
3349
3350impl_traits_for_gl_object!(VertexShaderCompileError, error_id);
3351
3352impl ::core::fmt::Display for VertexShaderCompileError {
3353 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3354 write!(f, "E{}: {}", self.error_id, self.info_log)
3355 }
3356}
3357
3358#[repr(C)]
3359#[derive(Clone)]
3360pub struct FragmentShaderCompileError {
3361 pub error_id: i32,
3362 pub info_log: AzString,
3363}
3364
3365impl_traits_for_gl_object!(FragmentShaderCompileError, error_id);
3366
3367impl ::core::fmt::Display for FragmentShaderCompileError {
3368 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3369 write!(f, "E{}: {}", self.error_id, self.info_log)
3370 }
3371}
3372
3373#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
3374pub enum GlShaderCompileError {
3375 Vertex(VertexShaderCompileError),
3376 Fragment(FragmentShaderCompileError),
3377}
3378
3379impl ::core::fmt::Display for GlShaderCompileError {
3380 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3381 use self::GlShaderCompileError::*;
3382 match self {
3383 Vertex(vert_err) => write!(f, "Failed to compile vertex shader: {}", vert_err),
3384 Fragment(frag_err) => write!(f, "Failed to compile fragment shader: {}", frag_err),
3385 }
3386 }
3387}
3388
3389impl ::core::fmt::Debug for GlShaderCompileError {
3390 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3391 write!(f, "{}", self)
3392 }
3393}
3394
3395#[repr(C)]
3396#[derive(Clone)]
3397pub struct GlShaderLinkError {
3398 pub error_id: i32,
3399 pub info_log: AzString,
3400}
3401
3402impl_traits_for_gl_object!(GlShaderLinkError, error_id);
3403
3404impl ::core::fmt::Display for GlShaderLinkError {
3405 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3406 write!(f, "E{}: {}", self.error_id, self.info_log)
3407 }
3408}
3409
3410#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
3411pub enum GlShaderCreateError {
3412 Compile(GlShaderCompileError),
3413 Link(GlShaderLinkError),
3414 NoShaderCompiler,
3415}
3416
3417impl ::core::fmt::Display for GlShaderCreateError {
3418 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3419 use self::GlShaderCreateError::*;
3420 match self {
3421 Compile(compile_err) => write!(f, "Shader compile error: {}", compile_err),
3422 Link(link_err) => write!(f, "Shader linking error: {}", link_err),
3423 NoShaderCompiler => {
3424 write!(f, "OpenGL implementation doesn't include a shader compiler")
3425 }
3426 }
3427 }
3428}
3429
3430impl ::core::fmt::Debug for GlShaderCreateError {
3431 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3432 write!(f, "{}", self)
3433 }
3434}
3435
3436impl GlShader {
3437 pub fn new(
3443 gl_context: &GlContextPtr,
3444 vertex_shader: &str,
3445 fragment_shader: &str,
3446 ) -> Result<Self, GlShaderCreateError> {
3447 let mut shader_compiler_supported = [gl::FALSE as u8];
3449 gl_context.get_boolean_v(
3450 gl::SHADER_COMPILER,
3451 (&mut shader_compiler_supported[..]).into(),
3452 );
3453 if u32::from(shader_compiler_supported[0]) == gl::FALSE {
3454 return Err(GlShaderCreateError::NoShaderCompiler);
3456 }
3457
3458 let vertex_shader_object = gl_context.create_shader(gl::VERTEX_SHADER);
3461 gl_context.shader_source(
3462 vertex_shader_object,
3463 vec![AzString::from(vertex_shader.to_string())].into(),
3464 );
3465 gl_context.compile_shader(vertex_shader_object);
3466
3467 if let Some(error_id) = get_gl_shader_error(&gl_context, vertex_shader_object) {
3468 let info_log = gl_context.get_shader_info_log(vertex_shader_object);
3469 gl_context.delete_shader(vertex_shader_object);
3470 return Err(GlShaderCreateError::Compile(GlShaderCompileError::Vertex(
3471 VertexShaderCompileError {
3472 error_id,
3473 info_log: info_log.into(),
3474 },
3475 )));
3476 }
3477
3478 let fragment_shader_object = gl_context.create_shader(gl::FRAGMENT_SHADER);
3481 gl_context.shader_source(
3482 fragment_shader_object,
3483 vec![AzString::from(fragment_shader.to_string())].into(),
3484 );
3485 gl_context.compile_shader(fragment_shader_object);
3486
3487 if let Some(error_id) = get_gl_shader_error(&gl_context, fragment_shader_object) {
3488 let info_log = gl_context.get_shader_info_log(fragment_shader_object);
3489 gl_context.delete_shader(vertex_shader_object);
3490 gl_context.delete_shader(fragment_shader_object);
3491 return Err(GlShaderCreateError::Compile(
3492 GlShaderCompileError::Fragment(FragmentShaderCompileError {
3493 error_id,
3494 info_log: info_log.into(),
3495 }),
3496 ));
3497 }
3498
3499 let program_id = gl_context.create_program();
3502 gl_context.attach_shader(program_id, vertex_shader_object);
3503 gl_context.attach_shader(program_id, fragment_shader_object);
3504 gl_context.link_program(program_id);
3505
3506 if let Some(error_id) = get_gl_program_error(&gl_context, program_id) {
3507 let info_log = gl_context.get_program_info_log(program_id);
3508 gl_context.delete_shader(vertex_shader_object);
3509 gl_context.delete_shader(fragment_shader_object);
3510 gl_context.delete_program(program_id);
3511 return Err(GlShaderCreateError::Link(GlShaderLinkError {
3512 error_id,
3513 info_log: info_log.into(),
3514 }));
3515 }
3516
3517 gl_context.delete_shader(vertex_shader_object);
3518 gl_context.delete_shader(fragment_shader_object);
3519
3520 Ok(GlShader {
3521 program_id,
3522 gl_context: gl_context.clone(),
3523 })
3524 }
3525
3526 pub fn draw(
3528 shader_program_id: GLuint,
3530 texture: &mut Texture,
3532 buffers: &[(&VertexBuffer, &[Uniform])],
3534 ) {
3535 use alloc::collections::btree_map::BTreeMap;
3536
3537 const INDEX_TYPE: GLuint = gl::UNSIGNED_INT;
3538
3539 let texture_size = texture.size;
3540
3541 let gl_context = &texture.gl_context;
3542
3543 let mut current_multisample = [0_u8];
3545 let mut current_index_buffer = [0_i32];
3546 let mut current_vertex_buffer = [0_i32];
3547 let mut current_vertex_array_object = [0_i32];
3548 let mut current_program = [0_i32];
3549 let mut current_framebuffers = [0_i32];
3550 let mut current_renderbuffers = [0_i32];
3551 let mut current_texture_2d = [0_i32];
3552 let mut current_blend_enabled = [0_u8];
3553 let mut current_primitive_restart_fixed_index_enabled = [0_u8];
3554
3555 gl_context.get_boolean_v(gl::MULTISAMPLE, (&mut current_multisample[..]).into());
3556 gl_context.get_integer_v(
3557 gl::ARRAY_BUFFER_BINDING,
3558 (&mut current_vertex_buffer[..]).into(),
3559 );
3560 gl_context.get_integer_v(
3561 gl::ELEMENT_ARRAY_BUFFER_BINDING,
3562 (&mut current_index_buffer[..]).into(),
3563 );
3564 gl_context.get_integer_v(gl::CURRENT_PROGRAM, (&mut current_program[..]).into());
3565 gl_context.get_integer_v(
3566 gl::VERTEX_ARRAY_BINDING,
3567 (&mut current_vertex_array_object[..]).into(),
3568 );
3569 gl_context.get_integer_v(gl::RENDERBUFFER, (&mut current_renderbuffers[..]).into());
3570 gl_context.get_integer_v(gl::FRAMEBUFFER, (&mut current_framebuffers[..]).into());
3571 gl_context.get_integer_v(gl::TEXTURE_2D, (&mut current_texture_2d[..]).into());
3572 gl_context.get_boolean_v(gl::BLEND, (&mut current_blend_enabled[..]).into());
3573 gl_context.get_boolean_v(
3574 gl::PRIMITIVE_RESTART_FIXED_INDEX,
3575 (&mut current_primitive_restart_fixed_index_enabled[..]).into(),
3576 );
3577
3578 let framebuffers = gl_context.gen_framebuffers(1);
3580 let framebuffer_id = framebuffers.get(0).unwrap();
3581 gl_context.bind_framebuffer(gl::FRAMEBUFFER, *framebuffer_id);
3582
3583 let depthbuffers = gl_context.gen_renderbuffers(1);
3584 let depthbuffer_id = depthbuffers.get(0).unwrap();
3585
3586 gl_context.bind_texture(gl::TEXTURE_2D, texture.texture_id);
3587 gl_context.tex_image_2d(
3588 gl::TEXTURE_2D,
3589 0,
3590 gl::RGBA as i32, texture_size.width as i32,
3592 texture_size.height as i32,
3593 0,
3594 gl::RGBA, gl::UNSIGNED_BYTE,
3596 None.into(),
3597 );
3598 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
3599 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
3600 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32);
3601 gl_context.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);
3602
3603 gl_context.bind_renderbuffer(gl::RENDERBUFFER, *depthbuffer_id);
3604 gl_context.renderbuffer_storage(
3605 gl::RENDERBUFFER,
3606 gl::DEPTH_COMPONENT,
3607 texture_size.width as i32,
3608 texture_size.height as i32,
3609 );
3610 gl_context.framebuffer_renderbuffer(
3611 gl::FRAMEBUFFER,
3612 gl::DEPTH_ATTACHMENT,
3613 gl::RENDERBUFFER,
3614 *depthbuffer_id,
3615 );
3616
3617 gl_context.framebuffer_texture_2d(
3618 gl::FRAMEBUFFER,
3619 gl::COLOR_ATTACHMENT0,
3620 gl::TEXTURE_2D,
3621 texture.texture_id,
3622 0,
3623 );
3624 gl_context.draw_buffers([gl::COLOR_ATTACHMENT0][..].into());
3625
3626 #[cfg(feature = "std")]
3627 {
3628 let fb_check = gl_context.check_frame_buffer_status(gl::FRAMEBUFFER);
3629 match fb_check {
3630 gl::FRAMEBUFFER_COMPLETE => {}
3631 gl::FRAMEBUFFER_UNDEFINED => {
3632 println!("GL_FRAMEBUFFER_UNDEFINED");
3633 }
3634 gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => {
3635 println!("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
3636 }
3637 gl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT => {
3638 println!("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
3639 }
3640 gl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER => {
3641 println!("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER");
3642 }
3643 gl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER => {
3644 println!("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER");
3645 }
3646 gl::FRAMEBUFFER_UNSUPPORTED => {
3647 println!("GL_FRAMEBUFFER_UNSUPPORTED");
3648 }
3649 gl::FRAMEBUFFER_INCOMPLETE_MULTISAMPLE => {
3650 println!("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE");
3651 }
3652 gl::FRAMEBUFFER_INCOMPLETE_MULTISAMPLE => {
3653 println!("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE");
3654 }
3655 gl::FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS => {
3656 println!("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS");
3657 }
3658 o => {
3659 println!("glFramebufferStatus returned unknown return code: {}", o);
3660 }
3661 }
3662 }
3663
3664 gl_context.viewport(0, 0, texture_size.width as i32, texture_size.height as i32);
3665 gl_context.enable(gl::BLEND);
3666 gl_context.enable(gl::PRIMITIVE_RESTART_FIXED_INDEX);
3667 gl_context.disable(gl::MULTISAMPLE);
3668 gl_context.blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); gl_context.use_program(shader_program_id);
3670
3671 let mut uniform_locations: BTreeMap<AzString, i32> = BTreeMap::new();
3673 let mut max_uniform_len = 0;
3674 for (_, uniforms) in buffers {
3675 for uniform in uniforms.iter() {
3676 if !uniform_locations.contains_key(&uniform.uniform_name) {
3677 uniform_locations.insert(
3678 uniform.uniform_name.clone(),
3679 gl_context.get_uniform_location(
3680 shader_program_id,
3681 uniform.uniform_name.as_str().into(),
3682 ),
3683 );
3684 }
3685 }
3686 max_uniform_len = max_uniform_len.max(uniforms.len());
3687 }
3688 let mut current_uniforms = vec![None; max_uniform_len];
3689
3690 for (vertex_index_buffer, uniforms) in buffers {
3695 gl_context.bind_vertex_array(vertex_index_buffer.vao.vao_id);
3696 gl_context.bind_buffer(gl::ARRAY_BUFFER, vertex_index_buffer.vertex_buffer_id);
3697 gl_context.bind_buffer(
3698 gl::ELEMENT_ARRAY_BUFFER,
3699 vertex_index_buffer.index_buffer_id,
3700 );
3701
3702 for (uniform_index, uniform) in uniforms.iter().enumerate() {
3704 if current_uniforms[uniform_index] != Some(uniform.uniform_type) {
3705 let uniform_location = uniform_locations[&uniform.uniform_name];
3706 uniform.uniform_type.set(gl_context.get(), uniform_location);
3707 current_uniforms[uniform_index] = Some(uniform.uniform_type);
3708 }
3709 }
3710
3711 gl_context.draw_elements(
3712 vertex_index_buffer.index_buffer_format.get_gl_id(),
3713 vertex_index_buffer.index_buffer_len as i32,
3714 INDEX_TYPE,
3715 0,
3716 );
3717 }
3718
3719 if u32::from(current_multisample[0]) == gl::TRUE {
3721 gl_context.enable(gl::MULTISAMPLE);
3722 }
3723 if u32::from(current_blend_enabled[0]) == gl::FALSE {
3724 gl_context.disable(gl::BLEND);
3725 }
3726 if u32::from(current_primitive_restart_fixed_index_enabled[0]) == gl::FALSE {
3727 gl_context.disable(gl::PRIMITIVE_RESTART_FIXED_INDEX);
3728 }
3729 gl_context.bind_framebuffer(gl::FRAMEBUFFER, current_framebuffers[0] as u32);
3730 gl_context.bind_texture(gl::TEXTURE_2D, current_texture_2d[0] as u32);
3731 gl_context.bind_buffer(gl::RENDERBUFFER, current_renderbuffers[0] as u32);
3732 gl_context.bind_vertex_array(current_vertex_array_object[0] as u32);
3733 gl_context.bind_buffer(gl::ELEMENT_ARRAY_BUFFER, current_index_buffer[0] as u32);
3734 gl_context.bind_buffer(gl::ARRAY_BUFFER, current_vertex_buffer[0] as u32);
3735 gl_context.use_program(current_program[0] as u32);
3736
3737 gl_context.delete_framebuffers((&[*framebuffer_id])[..].into());
3738 gl_context.delete_renderbuffers((&[*depthbuffer_id])[..].into());
3739
3740 texture.format = RawImageFormat::RGBA8;
3741 texture.flags = TextureFlags {
3742 is_opaque: false,
3743 is_video_texture: false,
3744 };
3745 }
3746}
3747
3748fn get_gl_shader_error(context: &GlContextPtr, shader_object: GLuint) -> Option<i32> {
3749 let mut err = [0];
3750 context.get_shader_iv(shader_object, gl::COMPILE_STATUS, (&mut err[..]).into());
3751 let err_code = err[0];
3752 if err_code == gl::TRUE as i32 {
3753 None
3754 } else {
3755 Some(err_code)
3756 }
3757}
3758
3759fn get_gl_program_error(context: &GlContextPtr, shader_object: GLuint) -> Option<i32> {
3760 let mut err = [0];
3761 context.get_program_iv(shader_object, gl::LINK_STATUS, (&mut err[..]).into());
3762 let err_code = err[0];
3763 if err_code == gl::TRUE as i32 {
3764 None
3765 } else {
3766 Some(err_code)
3767 }
3768}