use color::Color;
use gl;
use gl::types::*;
use nalgebra::Vector2;
use std::mem;
use std::ops::{Index, IndexMut};
use std::ptr;
#[derive(Debug, Clone, PartialEq, Copy)]
pub struct Vertex {
pub pos: Vector2<f32>,
pub tex: Vector2<f32>,
pub color: Color,
}
impl Vertex {
pub fn new(pos: Vector2<f32>, tex: Vector2<f32>, color: Color) -> Vertex {
Vertex { pos, tex, color }
}
}
impl From<Vector2<f32>> for Vertex {
fn from(pos: Vector2<f32>) -> Vertex {
Vertex {
pos,
tex: pos,
color: Color::new(1.0, 1.0, 1.0),
}
}
}
impl From<(Vector2<f32>, Color)> for Vertex {
fn from(datas: (Vector2<f32>, Color)) -> Vertex {
Vertex {
pos: datas.0,
tex: Vector2::new(0.0, 0.0),
color: datas.1,
}
}
}
impl From<(Vector2<f32>, Vector2<f32>)> for Vertex {
fn from(datas: (Vector2<f32>, Vector2<f32>)) -> Vertex {
Vertex {
pos: datas.0,
tex: datas.1,
color: Color::new(1.0, 1.0, 1.0),
}
}
}
impl Default for Vertex {
fn default() -> Vertex {
Vertex {
pos: Vector2::new(0.0, 0.0),
tex: Vector2::new(0.0, 0.0),
color: Color::white(),
}
}
}
#[derive(Clone, Debug, PartialEq, Default)]
pub struct VertexArray {
array: Vec<Vertex>,
id: u32,
}
impl VertexArray {
pub fn new() -> VertexArray {
let mut id = 0;
unsafe {
gl::GenVertexArrays(1, &mut id);
}
VertexArray {
array: Vec::new(),
id,
}
}
pub fn array(&self) -> &Vec<Vertex> {
&self.array
}
pub fn clear(&mut self) {
self.array.clear();
}
pub fn array_mut(&mut self) -> &mut Vec<Vertex> {
&mut self.array
}
pub fn active(&self) {
unsafe {
gl::BindVertexArray(self.id);
gl::VertexAttribPointer(
0,
2,
gl::FLOAT,
gl::FALSE,
(8 * mem::size_of::<GLfloat>()) as GLsizei,
ptr::null(),
);
gl::EnableVertexAttribArray(0);
gl::VertexAttribPointer(
1,
2,
gl::FLOAT,
gl::FALSE,
(8 * mem::size_of::<GLfloat>()) as GLsizei,
(2 * mem::size_of::<GLfloat>()) as *const _,
);
gl::EnableVertexAttribArray(1);
gl::VertexAttribPointer(
2,
3,
gl::FLOAT,
gl::FALSE,
(8 * mem::size_of::<GLfloat>()) as GLsizei,
(4 * mem::size_of::<GLfloat>()) as *const _,
);
gl::EnableVertexAttribArray(2);
}
}
pub fn len(&self) -> usize {
self.array.len()
}
pub fn is_empty(&self) -> bool {
self.array.len() == 0
}
pub fn bind(&self) {
unsafe {
gl::BindVertexArray(self.id);
}
}
pub fn unbind(&self) {
unsafe {
gl::BindVertexArray(0);
}
}
pub unsafe fn get_ptr(&self) -> *const GLvoid {
self.array.as_ptr() as *const GLvoid
}
}
impl<'a> From<&'a [Vertex]> for VertexArray {
fn from(array: &[Vertex]) -> VertexArray {
if array.is_empty() {
VertexArray::new()
} else {
let mut id = 0;
unsafe { gl::GenVertexArrays(1, &mut id) };
VertexArray {
array: Vec::from(array),
id,
}
}
}
}
impl<'a> From<&'a [f32]> for VertexArray {
fn from(array: &[f32]) -> VertexArray {
if array.is_empty() {
VertexArray::new()
} else {
let mut arr = Vec::new();
for elem in array.windows(8) {
arr.push(Vertex::new(
Vector2::new(elem[0], elem[1]),
Vector2::new(elem[2], elem[3]),
Color::new(elem[4], elem[5], elem[6]),
));
}
let mut id = 0;
unsafe { gl::GenVertexArrays(1, &mut id) };
VertexArray { array: arr, id }
}
}
}
impl Index<usize> for VertexArray {
type Output = Vertex;
fn index(&self, vertex_index: usize) -> &Vertex {
&self.array[vertex_index]
}
}
impl IndexMut<usize> for VertexArray {
fn index_mut(&mut self, vertex_index: usize) -> &mut Vertex {
&mut self.array[vertex_index]
}
}
impl Drop for VertexArray {
fn drop(&mut self) {
unsafe {
gl::DeleteVertexArrays(1, &[self.id] as *const _);
}
println!("VertexArray {} delete.", self.id);
}
}