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 125 126 127 128 129 130 131 132 133 134 135 136 137
use std::ops::{Deref, DerefMut}; use gl; use gl::types::*; use super::{gl_major, GLAttribute, GLBuffer, GLVertex}; #[derive(Debug, 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); } } } }