2021-32-bit-holiday-jam/src/gpu_buffers.rs

127 lines
2.1 KiB
Rust
Raw Normal View History

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;
}
}