127 lines
2.1 KiB
Rust
127 lines
2.1 KiB
Rust
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||
|
|
||
|
use std::cmp;
|
||
|
use std::convert::TryInto;
|
||
|
use std::ffi::c_void;
|
||
|
use std::io::Cursor;
|
||
|
|
||
|
// Only contains f32 floats
|
||
|
|
||
|
pub struct VertexBuffer {
|
||
|
id: u32,
|
||
|
// Not bytes.
|
||
|
len: usize,
|
||
|
}
|
||
|
|
||
|
impl VertexBuffer {
|
||
|
pub fn from_slice (slice: &[f32]) -> Self {
|
||
|
const FLOAT_SIZE: usize = 4;
|
||
|
|
||
|
let id = {
|
||
|
let mut id = 0;
|
||
|
unsafe {
|
||
|
gl::GenBuffers (1, &mut id);
|
||
|
gl::BindBuffer (gl::ARRAY_BUFFER, id);
|
||
|
|
||
|
gl::BufferData (gl::ARRAY_BUFFER, (slice.len () * FLOAT_SIZE).try_into ().unwrap (), &slice [0] as *const f32 as *const c_void, gl::STATIC_DRAW);
|
||
|
}
|
||
|
assert! (id != 0);
|
||
|
id
|
||
|
};
|
||
|
|
||
|
Self {
|
||
|
id,
|
||
|
len: slice.len (),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn bind (&self) {
|
||
|
unsafe {
|
||
|
gl::BindBuffer (gl::ARRAY_BUFFER, self.id);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
impl Drop for VertexBuffer {
|
||
|
fn drop (&mut self) {
|
||
|
if self.id == 0 {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
unsafe {
|
||
|
gl::DeleteBuffers (1, &self.id);
|
||
|
}
|
||
|
|
||
|
self.id = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct IndexBuffer {
|
||
|
id: u32,
|
||
|
// Not bytes. Number of indexes.
|
||
|
len: usize,
|
||
|
max: u32,
|
||
|
}
|
||
|
|
||
|
impl IndexBuffer {
|
||
|
pub fn from_slice (slice: &[u8]) -> Self {
|
||
|
let mut rdr = Cursor::new (slice);
|
||
|
|
||
|
let mut max = None;
|
||
|
|
||
|
const IDX_SIZE: usize = 4;
|
||
|
|
||
|
assert_eq! (slice.len () % IDX_SIZE, 0);
|
||
|
|
||
|
for _ in 0..slice.len () / IDX_SIZE {
|
||
|
let idx = rdr.read_u32::<LittleEndian> ().unwrap ();
|
||
|
|
||
|
max = match max {
|
||
|
None => Some (idx),
|
||
|
Some (max) => Some (cmp::max (max, idx)),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
let id = {
|
||
|
let mut id = 0;
|
||
|
unsafe {
|
||
|
gl::GenBuffers (1, &mut id);
|
||
|
gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, id);
|
||
|
|
||
|
gl::BufferData (gl::ELEMENT_ARRAY_BUFFER, slice.len ().try_into ().unwrap (), &slice [0] as *const u8 as *const c_void, gl::STATIC_DRAW);
|
||
|
}
|
||
|
assert! (id != 0);
|
||
|
id
|
||
|
};
|
||
|
|
||
|
Self {
|
||
|
id,
|
||
|
len: slice.len () / IDX_SIZE,
|
||
|
max: max.unwrap (),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn bind (&self) {
|
||
|
unsafe {
|
||
|
gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, self.id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn max (&self) -> u32 {
|
||
|
self.max
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Drop for IndexBuffer {
|
||
|
fn drop (&mut self) {
|
||
|
if self.id == 0 {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
unsafe {
|
||
|
gl::DeleteBuffers (1, &self.id);
|
||
|
}
|
||
|
|
||
|
self.id = 0;
|
||
|
}
|
||
|
}
|