gllite/
geometry.rs

1use super::gli;
2use super::program::Attribute;
3
4pub struct AttributeInfo {
5  normalize: bool,
6  location: u32,
7  offset: i32,
8  size: i32,
9  stride: i32,
10  gl_type: u32,
11}
12
13pub struct Geometry {
14  attributes: Vec<AttributeInfo>,
15  buffer: VertexBuffer,
16  data_length: i32,
17  index: Option<u32>,
18  index_count: i32,
19  total_byte_length: i32,
20  vao: u32,
21  bound: bool,
22}
23
24impl Geometry {
25  pub fn new() -> Geometry {
26    Geometry {
27      attributes: Vec::new(),
28      buffer: VertexBuffer::new(),
29      data_length: 0,
30      index: None,
31      index_count: 0,
32      total_byte_length: 0,
33      vao: gli::create_vertex_array(),
34      bound: false,
35    }
36  }
37
38  fn add_attr(&mut self, attr: &Attribute, normalize: bool) {
39    let (size, gl_type) = gli::get_attribute_size_and_type(attr.gl_type, normalize);
40    let length = gli::size_of_type(gl_type);
41    let info = AttributeInfo {
42      normalize: normalize,
43      location: attr.location,
44      size: size,
45      gl_type: gl_type,
46      offset: self.total_byte_length,
47      stride: length * size,
48    };
49    self.attributes.push(info);
50    self.total_byte_length += length * size;
51  }
52
53  pub fn add_attribute(&mut self, attr: &Attribute) {
54    self.add_attr(attr, false);
55  }
56
57  pub fn add_normalized_attribute(&mut self, attr: &Attribute) {
58    self.add_attr(attr, true);
59  }
60
61  pub fn buffer_data(&mut self, data: &[f32]) {
62    self.data_length = data.len() as i32 * 4;
63    self.buffer.buffer_data(data);
64  }
65
66  fn bind_to_attributes(&self) {
67    for attr in self.attributes.iter() {
68      self.buffer.bind_to_attribute(
69        attr.location,
70        attr.size,
71        attr.gl_type,
72        attr.normalize,
73        self.total_byte_length,
74        attr.offset,
75      );
76    }
77  }
78
79  pub fn draw(&mut self) {
80    gli::bind_vertex_array(self.vao);
81    if !self.bound {
82      self.bind_to_attributes();
83      self.bound = true;
84    }
85    if let Some(index) = self.index {
86      gli::draw_elements_triangles(self.index_count);
87    } else {
88      let count = self.data_length / self.total_byte_length;
89      gli::draw_arrays_triangles(count);
90    }
91    gli::bind_vertex_array(0);
92  }
93}
94
95pub struct VertexBuffer {
96  buffer: u32,
97}
98
99impl VertexBuffer {
100  pub fn new() -> VertexBuffer {
101    let vbo = gli::create_buffer();
102    VertexBuffer {
103      buffer: vbo,
104    }
105  }
106
107  pub fn buffer_data(&self, data: &[f32]) {
108    gli::bind_array_buffer(self.buffer);
109    gli::buffer_array_data(data);
110  }
111
112  pub fn bind_to_attribute(&self, location: u32, size: i32, gl_type: u32, normalized: bool, stride: i32, offset: i32) {
113    gli::bind_array_buffer(self.buffer);
114    gli::vertex_attrib_pointer(location, size, gl_type, normalized, stride, offset);
115    gli::enable_vertex_attrib_array(location);
116  }
117}