1use web_sys::{WebGlBuffer, WebGlVertexArrayObject};
4
5use crate::{gl, GL};
6
7#[derive(Debug, Clone, Copy)]
10#[repr(C)]
11pub struct Vertex {
12 pub position: [f32; 2],
14 pub uv: [f32; 2],
16 pub color: [f32; 4],
18}
19
20impl Default for Vertex {
21 fn default() -> Self {
22 Self {
23 position: [0.0, 0.0],
24 uv: [0.0, 0.0],
25 color: [1.0, 1.0, 1.0, 1.0],
26 }
27 }
28}
29
30#[derive(Debug)]
32pub struct Mesh {
33 pub vertices: Vec<Vertex>,
37 pub indices: Vec<u32>,
41 vao: WebGlVertexArrayObject,
42 vbo: WebGlBuffer,
43 ibo: WebGlBuffer,
44}
45
46impl Drop for Mesh {
47 fn drop(&mut self) {
48 use gl::Bind;
49 let gl = gl::get_context();
50 self.unbind(&gl);
51
52 gl.delete_buffer(Some(&self.vbo));
53 gl.delete_buffer(Some(&self.ibo));
54 self.vertices.clear();
55 self.indices.clear();
56 gl.delete_vertex_array(Some(&self.vao));
57 }
58}
59
60impl gl::Bind for Mesh {
61 fn bind(&self, gl: &GL) {
63 gl.bind_vertex_array(Some(&self.vao));
64 }
65 fn unbind(&self, gl: &GL) {
66 gl.bind_vertex_array(None);
67 }
68}
69
70impl Mesh {
71 pub fn new(gl: &GL, vertices: Vec<Vertex>, indices: Vec<u32>) -> Self {
73 Self {
74 vertices,
75 indices,
76 vao: {
77 let vao = gl
78 .create_vertex_array()
79 .expect("Could not create Vertex Array Object.");
80 gl.bind_vertex_array(Some(&vao));
81 vao
82 },
83 vbo: gl.create_buffer().expect("Could not create Buffer."),
84 ibo: gl.create_buffer().expect("Could not create Buffer."),
85 }
86 }
87 pub fn quad(gl: &GL) -> Self {
89 Self::quad_with_side(gl, 1.0)
90 }
91 pub fn quad_with_side(gl: &GL, side: f32) -> Self {
93 let half = side / 2.0;
94 let vertices = vec![
95 Vertex {
96 position: [-half, half],
97 uv: [0.0, 0.0],
98 ..Default::default()
99 },
100 Vertex {
101 position: [-half, -half],
102 uv: [0.0, 1.0],
103 ..Default::default()
104 },
105 Vertex {
106 position: [half, -half],
107 uv: [1.0, 1.0],
108 ..Default::default()
109 },
110 Vertex {
111 position: [half, half],
112 uv: [1.0, 0.0],
113 ..Default::default()
114 },
115 ];
116 let indices: Vec<u32> = vec![0, 2, 1, 0, 3, 2];
117 Self::new(gl, vertices, indices)
118 }
119
120 pub fn setup(&self, gl: &GL) {
122 use gl::Bind;
123 self.bind(gl);
124
125 gl.bind_buffer(GL::ARRAY_BUFFER, Some(&self.vbo));
126 gl.bind_buffer(GL::ELEMENT_ARRAY_BUFFER, Some(&self.ibo));
127
128 let vertex_slice = unsafe {
129 std::slice::from_raw_parts(
130 self.vertices.as_ptr() as *const u8,
131 self.vertices.len() * std::mem::size_of::<Vertex>(),
132 )
133 };
134 let index_slice = unsafe {
135 std::slice::from_raw_parts(
136 self.indices.as_ptr() as *const u8,
137 self.indices.len() * std::mem::size_of::<u32>(),
138 )
139 };
140
141 gl.buffer_data_with_u8_array(GL::ARRAY_BUFFER, vertex_slice, GL::DYNAMIC_DRAW);
142 gl.buffer_data_with_u8_array(GL::ELEMENT_ARRAY_BUFFER, index_slice, GL::DYNAMIC_DRAW);
143
144 gl.vertex_attrib_pointer_with_i32(0, 2, GL::FLOAT, false, 8 * 4, 0);
145 gl.vertex_attrib_pointer_with_i32(1, 2, GL::FLOAT, false, 8 * 4, 8);
146 gl.vertex_attrib_pointer_with_i32(2, 4, GL::FLOAT, false, 8 * 4, 16);
147
148 gl.enable_vertex_attrib_array(0);
149 gl.enable_vertex_attrib_array(1);
150 gl.enable_vertex_attrib_array(2);
151 }
152}