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