1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
use alloc::vec::Vec; use core::ops::{Drop, Deref, DerefMut}; use gl; use gl::types::*; use super::{GLAttribute, GLBuffer, GLVertex, gl_major}; #[derive(Debug, Clone, Hash)] pub struct GLVertexArray { id: GLuint, array: Vec<GLVertex>, } impl GLVertexArray { #[inline(always)] pub fn new() -> Self { GLVertexArray { id: { let mut id = 0; if gl_major() > 2 { unsafe { gl::GenVertexArrays(1, &mut id); } } id }, array: Vec::new(), } } #[inline] pub fn bind(&self) -> &Self { let gl_major = gl_major(); if gl_major > 2 { unsafe { gl::BindVertexArray(self.id()); } } self.enable_attributes(); if gl_major < 3 { for gl_vertex in &self.array { gl_vertex.bind(); } } self } #[inline] pub fn unbind(&self) -> &Self { if gl_major() > 2 { unsafe { gl::BindVertexArray(0); } } self.disable_attributes(); self } #[inline] pub fn enable_attributes(&self) -> &Self { for gl_vertex in &self.array { gl_vertex.enable(); } self } #[inline] pub fn disable_attributes(&self) -> &Self { for gl_vertex in &self.array { gl_vertex.disable(); } self } #[inline] pub fn add_attribute( &mut self, gl_buffer: &GLBuffer, gl_attribute: &GLAttribute, offset: usize ) -> &mut Self { let location = gl_attribute.location(); let item_count = gl_attribute.item_count(); let item_kind = gl_attribute.item_kind(); let offset = offset * gl_buffer.kind_size(); let gl_vertex = GLVertex::new(location, item_count, item_kind, gl_buffer.stride(), offset); gl_vertex.enable(); gl_vertex.bind(); self.array.push(gl_vertex); self } #[inline(always)] pub fn id(&self) -> GLuint { self.id } #[inline(always)] pub fn array(&self) -> &[GLVertex] { &*self.array } #[inline(always)] pub fn array_mut(&mut self) -> &mut [GLVertex] { &mut *self.array } } impl Deref for GLVertexArray { type Target = [GLVertex]; #[inline(always)] fn deref(&self) -> &Self::Target { self.array() } } impl DerefMut for GLVertexArray { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.array_mut() } } impl Drop for GLVertexArray { #[inline] fn drop(&mut self) { if self.id != 0 { unsafe { gl::DeleteVertexArrays(1, &self.id); } } } }