1use std::ffi::c_void;
2
3#[derive(Clone, Copy)]
4pub enum VertexAttribType {
5 Float,
6 Float2,
7 Float3,
8 Float4,
9 Mat3,
10 Mat4,
11 Int,
12 Int2,
13 Int3,
14 Int4,
15 Uint,
16 Byte,
17}
18
19pub fn vertex_attrib_type_gl(vtype: &VertexAttribType) -> u32 {
20 match vtype {
21 VertexAttribType::Float => gl::FLOAT,
22 VertexAttribType::Float2 => gl::FLOAT,
23 VertexAttribType::Float3 => gl::FLOAT,
24 VertexAttribType::Float4 => gl::FLOAT,
25 VertexAttribType::Mat3 => gl::FLOAT,
26 VertexAttribType::Mat4 => gl::FLOAT,
27 VertexAttribType::Int => gl::INT,
28 VertexAttribType::Int2 => gl::INT,
29 VertexAttribType::Int3 => gl::INT,
30 VertexAttribType::Int4 => gl::INT,
31 VertexAttribType::Uint => gl::UNSIGNED_INT,
32 VertexAttribType::Byte => gl::BYTE,
33 }
34}
35
36pub fn vertex_attrib_type_size(vtype: &VertexAttribType) -> u32 {
37 match vtype {
38 VertexAttribType::Float => 4,
39 VertexAttribType::Float2 => 4 * 2,
40 VertexAttribType::Float3 => 4 * 3,
41 VertexAttribType::Float4 => 4 * 4,
42 VertexAttribType::Mat3 => 4 * 3 * 3,
43 VertexAttribType::Mat4 => 4 * 4 * 4,
44 VertexAttribType::Int => 4,
45 VertexAttribType::Int2 => 4 * 2,
46 VertexAttribType::Int3 => 4 * 3,
47 VertexAttribType::Int4 => 4 * 4,
48 VertexAttribType::Uint => 4,
49 VertexAttribType::Byte => 1,
50 }
51}
52
53pub fn vertex_attrib_type_count(vtype: &VertexAttribType) -> u32 {
54 match vtype {
55 VertexAttribType::Float => 1,
56 VertexAttribType::Float2 => 2,
57 VertexAttribType::Float3 => 3,
58 VertexAttribType::Float4 => 4,
59 VertexAttribType::Mat3 => 3 * 3,
60 VertexAttribType::Mat4 => 4 * 4,
61 VertexAttribType::Int => 1,
62 VertexAttribType::Int2 => 2,
63 VertexAttribType::Int3 => 3,
64 VertexAttribType::Int4 => 4,
65 VertexAttribType::Uint => 1,
66 VertexAttribType::Byte => 1,
67 }
68}
69
70pub struct VertexAttrib {
82 pub size: u32,
83 pub offset: u32,
84 pub vtype: VertexAttribType,
85 pub normalize: bool,
86 pub name: String,
87}
88
89impl VertexAttrib {
90 pub fn new(vtype: VertexAttribType, normalize: bool, name: String) -> Self {
91 Self {
92 size: vertex_attrib_type_size(&vtype),
93 offset: 0,
94 vtype,
95 normalize,
96 name,
97 }
98 }
99}
100
101pub fn submit_vertex_attribs(vertex_attribs: &mut Vec<VertexAttrib>) {
120 let mut stride = 0;
121 let mut offset = 0;
122 for attrib in vertex_attribs.iter_mut() {
123 attrib.offset += offset;
124 offset += attrib.size;
125 stride += attrib.size;
126 }
127
128 let mut i = 0;
129 for attrib in vertex_attribs {
130 if vertex_attrib_type_gl(&attrib.vtype) == gl::FLOAT {
131 unsafe {
132 gl::VertexAttribPointer(
133 i,
134 vertex_attrib_type_count(&attrib.vtype) as i32,
135 vertex_attrib_type_gl(&attrib.vtype),
136 attrib.normalize as u8,
137 stride as i32,
138 attrib.offset as *const std::ffi::c_void,
139 );
140 }
141 } else {
142 unsafe {
143 gl::VertexAttribIPointer(
144 i,
145 vertex_attrib_type_count(&attrib.vtype) as i32,
146 vertex_attrib_type_gl(&attrib.vtype),
147 stride as i32,
148 attrib.offset as *const std::ffi::c_void,
149 );
150 }
151 }
152
153 unsafe {
154 gl::EnableVertexAttribArray(i);
155 }
156
157 i += 1;
158 }
159}
160
161fn gen_vao() -> u32 {
162 let mut vao: u32 = 0;
163 unsafe { gl::GenVertexArrays(1, &mut vao) }
164 vao
165}
166
167fn gen_buffer() -> u32 {
168 let mut buffer: u32 = 0;
169 unsafe { gl::GenBuffers(1, &mut buffer) }
170 buffer
171}
172
173pub fn calc_bytes_size<T>(v: &Vec<T>) -> usize {
174 v.len() * std::mem::size_of::<T>()
175}
176
177pub struct VertexArray {
205 pub id: u32,
206}
207
208impl VertexArray {
209 pub fn new() -> Self {
212 Self { id: gen_vao() }
213 }
214
215 pub fn bind(&self) {
216 unsafe {
217 gl::BindVertexArray(self.id);
218 }
219 }
220
221 pub fn unbind(&self) {
222 unsafe {
223 gl::BindVertexArray(0);
224 }
225 }
226}
227
228pub struct VertexBuffer {
248 pub id: u32,
249}
250
251impl VertexBuffer {
252 pub fn new<T>(size: isize, vertices: Option<&Vec<T>>) -> Self {
259 let _self = Self { id: gen_buffer() };
260 _self.bind();
261
262 if let Some(vertices) = vertices {
263 unsafe {
264 gl::BufferData(
265 gl::ARRAY_BUFFER,
266 size,
267 vertices.as_ptr() as *const std::ffi::c_void,
268 gl::STATIC_DRAW,
269 );
270 }
271 } else {
272 unsafe {
273 gl::BufferData(gl::ARRAY_BUFFER, size, std::ptr::null(), gl::DYNAMIC_DRAW);
274 }
275 }
276
277 _self
278 }
279
280 pub fn send_data<T>(&self, size: isize, offset: isize, vertices: &Vec<T>) {
287 unsafe {
288 self.bind();
289 gl::BufferSubData(
290 gl::ARRAY_BUFFER,
291 offset,
292 size,
293 vertices.as_ptr() as *const std::ffi::c_void,
294 );
295 }
296 }
297
298 pub fn bind(&self) {
299 unsafe {
300 gl::BindBuffer(gl::ARRAY_BUFFER, self.id);
301 }
302 }
303
304 pub fn unbind(&self) {
305 unsafe {
306 gl::BindBuffer(gl::ARRAY_BUFFER, 0);
307 }
308 }
309}
310
311pub struct IndexBuffer {
329 pub id: u32,
330}
331
332impl IndexBuffer {
333 pub fn new(size: isize, indices: Option<&Vec<i32>>) -> Self {
340 let _self = Self { id: gen_buffer() };
341 _self.bind();
342
343 if let Some(indices) = indices {
344 unsafe {
345 gl::BufferData(
346 gl::ELEMENT_ARRAY_BUFFER,
347 size,
348 indices.as_ptr() as *const std::ffi::c_void,
349 gl::STATIC_DRAW,
350 );
351 }
352 } else {
353 unsafe {
354 gl::BufferData(
355 gl::ELEMENT_ARRAY_BUFFER,
356 size,
357 std::ptr::null(),
358 gl::DYNAMIC_DRAW,
359 );
360 }
361 }
362 _self
363 }
364
365 pub fn send_data(&self, size: isize, offset: isize, indices: &Vec<i32>) {
372 unsafe {
373 self.bind();
374 gl::BufferSubData(
375 gl::ELEMENT_ARRAY_BUFFER,
376 offset,
377 size,
378 indices.as_ptr() as *const std::ffi::c_void,
379 );
380 }
381 }
382
383 pub fn bind(&self) {
384 unsafe {
385 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.id);
386 }
387 }
388
389 pub fn unbind(&self) {
390 unsafe {
391 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, 0);
392 }
393 }
394}
395
396pub struct UniforBuffer {
398 pub id: u32,
399 pub slot: u32,
400}
401
402impl UniforBuffer {
403 pub fn new(size: isize, binding: u32) -> Self {
407 let _self = Self {
408 id: gen_buffer(),
409 slot: binding,
410 };
411 unsafe {
412 gl::BufferData(gl::UNIFORM_BUFFER, size, std::ptr::null(), gl::DYNAMIC_DRAW);
413 gl::BindBufferBase(gl::UNIFORM_BUFFER, _self.slot, _self.id);
414 }
415
416 _self
417 }
418
419 pub fn send_data(&self, data: *const c_void, size: isize, offset: isize) {
424 unsafe {
425 gl::BindBufferBase(gl::UNIFORM_BUFFER, self.slot, self.id);
426 gl::BufferSubData(gl::UNIFORM_BUFFER, offset, size, data);
427 }
428 }
429}
430
431impl Drop for VertexArray {
432 fn drop(&mut self) {
433 unsafe { gl::DeleteVertexArrays(1, &self.id) }
434 }
435}
436
437impl Drop for VertexBuffer {
438 fn drop(&mut self) {
439 unsafe { gl::DeleteBuffers(1, &self.id) }
440 }
441}
442
443impl Drop for IndexBuffer {
444 fn drop(&mut self) {
445 unsafe { gl::DeleteBuffers(1, &self.id) }
446 }
447}
448
449impl Drop for UniforBuffer {
450 fn drop(&mut self) {
451 unsafe { gl::DeleteBuffers(1, &self.id) }
452 }
453}