Skip to main content

gust_render/
vertex.rs

1//! This is a module for vertex
2//! # Vertex
3//!
4//! A vertex is a point in space giving information to opengl.
5//! x vertex form x point that can be drawed.
6//!
7//! ```Rust
8//! use gust::Vector;
9//!
10//! let position = Vector::new(100.0, 100.0);
11//! let texture_coord = Vector::new(0.0, 0.0);
12//! let color = Color::new(1.0, 0.3, 0.5);
13//!
14//! Vertex::new(position, texture_coord, color);
15//! ````
16//! # VertexArray
17//!
18//! A vertex array is a Vec of Vertex that can be drawn. It's the littlest
19//! object that can be printed.
20//!
21//! ```Rust
22//! let pos_vec vec![
23//!     Vector::new(0.0, 0.0);
24//!     Vector::new(10.0, 0.0);
25//!     Vector::new(10.0, 10.0);
26//!     Vector::new(0.0, 10.0);
27//! ];
28//!
29//! let coord_vec = vec![
30//!     Vector2::new(0.0, 0.0),
31//!     Vector2::new(1.0, 0.0),
32//!     Vector2::new(1.0, 1.0),
33//!     Vector2::new(0.0, 1.0),
34//! ];
35//!
36//! let vertice = vec![
37//!     Vertex::new(pos_vec[0], coord_vec[0], Color::white()),
38//!     Vertex::new(pos_vec[1], coord_vec[1], Color::white()),
39//!     Vertex::new(pos_vec[2], coord_vec[2], Color::white()),
40//!     Vertex::new(pos_vec[3], coord_vec[3], Color::white()),
41//! ];
42//!
43//! VertexArray::new(vertice);
44//! ```
45
46use color::Color;
47use gl;
48use gl::types::*;
49use nalgebra::Vector2;
50use std::mem;
51use std::ops::{Index, IndexMut};
52use std::ptr;
53
54/// Vertex structure defined by texture coord, space coors and color
55#[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    /// Create a vertex containing position, texCoord and Color
64    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    /// create a vertex with just a position in 2D space
71    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    /// datas.0 = pos
82    /// datas.1 = color
83    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    /// datas.0 = position
94    /// datas.1 = texCoord
95    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    /// Default vertex
106    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/// VertexArray is a vertex data structure that is drawable and it's the basic system
116#[derive(Clone, Debug, PartialEq, Default)]
117pub struct VertexArray {
118    array: Vec<Vertex>,
119    id: u32,
120}
121
122impl VertexArray {
123    /// Create a empty vertex array
124    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            // Position (Of each vertex)
154            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            // Texture Coord (Of each vertex)
164            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            // Color (of each vertex)
174            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}