1use color::Color;
47use gl;
48use gl::types::*;
49use nalgebra::Vector2;
50use std::mem;
51use std::ops::{Index, IndexMut};
52use std::ptr;
53
54#[derive(Debug, Clone, PartialEq, Copy)]
56pub struct Vertex {
57 pub pos: Vector2<f32>,
58 pub tex: Vector2<f32>,
59 pub color: Color,
60}
61
62impl Vertex {
63 pub fn new(pos: Vector2<f32>, tex: Vector2<f32>, color: Color) -> Vertex {
65 Vertex { pos, tex, color }
66 }
67}
68
69impl From<Vector2<f32>> for Vertex {
70 fn from(pos: Vector2<f32>) -> Vertex {
72 Vertex {
73 pos,
74 tex: pos,
75 color: Color::new(1.0, 1.0, 1.0),
76 }
77 }
78}
79
80impl From<(Vector2<f32>, Color)> for Vertex {
81 fn from(datas: (Vector2<f32>, Color)) -> Vertex {
84 Vertex {
85 pos: datas.0,
86 tex: Vector2::new(0.0, 0.0),
87 color: datas.1,
88 }
89 }
90}
91
92impl From<(Vector2<f32>, Vector2<f32>)> for Vertex {
93 fn from(datas: (Vector2<f32>, Vector2<f32>)) -> Vertex {
96 Vertex {
97 pos: datas.0,
98 tex: datas.1,
99 color: Color::new(1.0, 1.0, 1.0),
100 }
101 }
102}
103
104impl Default for Vertex {
105 fn default() -> Vertex {
107 Vertex {
108 pos: Vector2::new(0.0, 0.0),
109 tex: Vector2::new(0.0, 0.0),
110 color: Color::white(),
111 }
112 }
113}
114
115#[derive(Clone, Debug, PartialEq, Default)]
117pub struct VertexArray {
118 array: Vec<Vertex>,
119 id: u32,
120}
121
122impl VertexArray {
123 pub fn new() -> VertexArray {
125 let mut id = 0;
126
127 unsafe {
128 gl::GenVertexArrays(1, &mut id);
129 }
130
131 VertexArray {
132 array: Vec::new(),
133 id,
134 }
135 }
136
137 pub fn array(&self) -> &Vec<Vertex> {
138 &self.array
139 }
140
141 pub fn clear(&mut self) {
142 self.array.clear();
143 }
144
145 pub fn array_mut(&mut self) -> &mut Vec<Vertex> {
146 &mut self.array
147 }
148
149 pub fn active(&self) {
150 unsafe {
151 gl::BindVertexArray(self.id);
152
153 gl::VertexAttribPointer(
155 0,
156 2,
157 gl::FLOAT,
158 gl::FALSE,
159 (8 * mem::size_of::<GLfloat>()) as GLsizei,
160 ptr::null(),
161 );
162 gl::EnableVertexAttribArray(0);
163 gl::VertexAttribPointer(
165 1,
166 2,
167 gl::FLOAT,
168 gl::FALSE,
169 (8 * mem::size_of::<GLfloat>()) as GLsizei,
170 (2 * mem::size_of::<GLfloat>()) as *const _,
171 );
172 gl::EnableVertexAttribArray(1);
173 gl::VertexAttribPointer(
175 2,
176 3,
177 gl::FLOAT,
178 gl::FALSE,
179 (8 * mem::size_of::<GLfloat>()) as GLsizei,
180 (4 * mem::size_of::<GLfloat>()) as *const _,
181 );
182 gl::EnableVertexAttribArray(2);
183 }
184 }
185
186 pub fn len(&self) -> usize {
187 self.array.len()
188 }
189
190 pub fn is_empty(&self) -> bool {
191 self.array.len() == 0
192 }
193
194 pub fn bind(&self) {
195 unsafe {
196 gl::BindVertexArray(self.id);
197 }
198 }
199
200 pub fn unbind(&self) {
201 unsafe {
202 gl::BindVertexArray(0);
203 }
204 }
205
206 pub unsafe fn get_ptr(&self) -> *const GLvoid {
207 self.array.as_ptr() as *const GLvoid
208 }
209}
210
211impl<'a> From<&'a [Vertex]> for VertexArray {
212 fn from(array: &[Vertex]) -> VertexArray {
213 if array.is_empty() {
214 VertexArray::new()
215 } else {
216 let mut id = 0;
217 unsafe { gl::GenVertexArrays(1, &mut id) };
218 VertexArray {
219 array: Vec::from(array),
220 id,
221 }
222 }
223 }
224}
225
226impl<'a> From<&'a [f32]> for VertexArray {
227 fn from(array: &[f32]) -> VertexArray {
228 if array.is_empty() {
229 VertexArray::new()
230 } else {
231 let mut arr = Vec::new();
232 for elem in array.windows(8) {
233 arr.push(Vertex::new(
234 Vector2::new(elem[0], elem[1]),
235 Vector2::new(elem[2], elem[3]),
236 Color::new(elem[4], elem[5], elem[6]),
237 ));
238 }
239 let mut id = 0;
240 unsafe { gl::GenVertexArrays(1, &mut id) };
241 VertexArray { array: arr, id }
242 }
243 }
244}
245
246impl Index<usize> for VertexArray {
247 type Output = Vertex;
248
249 fn index(&self, vertex_index: usize) -> &Vertex {
250 &self.array[vertex_index]
251 }
252}
253
254impl IndexMut<usize> for VertexArray {
255 fn index_mut(&mut self, vertex_index: usize) -> &mut Vertex {
256 &mut self.array[vertex_index]
257 }
258}
259
260impl Drop for VertexArray {
261 fn drop(&mut self) {
262 unsafe {
263 gl::DeleteVertexArrays(1, &[self.id] as *const _);
264 }
265 println!("VertexArray {} delete.", self.id);
266 }
267}