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