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