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
138
139
140
141
142
143
144
145
146
use gl;
use log::{debug, info};
use serde_derive::{Deserialize, Serialize};
use std::mem::size_of;
use std::os::raw::c_void;
use std::ptr;
macro_rules! offset_of {
($ty:ty, $field:ident) => {
&(*(ptr::null() as *const $ty)).$field as *const _ as usize
};
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[repr(C)]
pub struct Vertex {
pub position: [f32; 3],
pub normal: [f32; 3],
pub uv: [f32; 2],
}
impl Default for Vertex {
fn default() -> Vertex {
Vertex {
position: [0., 0., 0.],
normal: [0., 0., 0.],
uv: [0., 0.],
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Mesh {
pub(crate) vertices: Vec<Vertex>,
pub(crate) indices: Vec<u32>,
pub(super) vao: u32,
pub(super) vbo: u32,
pub(super) ibo: u32,
}
impl Mesh {
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>) -> Mesh {
info!(
"Mesh::new( vertices.len() == {}, indices.len() == {}",
vertices.len(),
indices.len()
);
let mut mesh: Mesh = Default::default();
mesh.vertices = vertices;
mesh.indices = indices;
unsafe {
mesh.init();
}
mesh
}
pub unsafe fn draw(&self) {
gl::BindVertexArray(self.vao);
gl::DrawElements(gl::TRIANGLES, self.indices.len() as i32, gl::UNSIGNED_INT, ptr::null());
gl::BindVertexArray(0);
}
unsafe fn init(&mut self) {
gl::GenVertexArrays(1, &mut self.vao);
gl::BindVertexArray(self.vao);
gl::GenBuffers(1, &mut self.vbo);
gl::BindBuffer(gl::ARRAY_BUFFER, self.vbo);
let size = (self.vertices.len() * size_of::<Vertex>()) as isize;
let data = &self.vertices[0] as *const Vertex as *const c_void;
gl::BufferData(gl::ARRAY_BUFFER, size, data, gl::STATIC_DRAW);
gl::GenBuffers(1, &mut self.ibo);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.ibo);
let size = (self.indices.len() * size_of::<u32>()) as isize;
let data = &self.indices[0] as *const u32 as *const c_void;
gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, size, data, gl::STATIC_DRAW);
let size = size_of::<Vertex>() as i32;
gl::EnableVertexAttribArray(0);
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex, position) as *const c_void);
gl::EnableVertexAttribArray(1);
gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex, normal) as *const c_void);
gl::EnableVertexAttribArray(2);
gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex, uv) as *const c_void);
gl::BindVertexArray(0);
debug!("Mesh::init() : vao == {}, vbo == {}, ibo == {}", self.vao, self.vbo, self.ibo);
}
}
impl Default for Mesh {
fn default() -> Mesh {
Mesh {
vertices: Vec::new(),
indices: Vec::new(),
vao: 0,
vbo: 0,
ibo: 0,
}
}
}
impl Drop for Mesh {
fn drop(&mut self) {
unsafe {
gl::DeleteBuffers(1, self.ibo as *const u32);
gl::DeleteBuffers(1, self.vbo as *const u32);
gl::DeleteVertexArrays(1, self.vao as *const u32);
}
}
}