RenderableModel is now using VBOs.
And I made the sky model use RenderableModel, so there are no unsafe blocks in the main file now.main
parent
0e0e3f833a
commit
af4ef579c1
|
@ -82,24 +82,6 @@ void main (void) {
|
|||
}
|
||||
";
|
||||
|
||||
unsafe fn vertex_attrib_pointer (id: Option <u32>, num_coords: i32, slice: &[u8]) {
|
||||
const FALSE_U8: u8 = 0;
|
||||
const FLOAT_SIZE: i32 = 4;
|
||||
|
||||
if let Some (id) = id {
|
||||
gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, &slice [0] as *const u8 as *const c_void);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn point_to_model (
|
||||
attrs: &HashMap <String, Option <u32>>,
|
||||
model: &Model
|
||||
) {
|
||||
vertex_attrib_pointer (attrs ["pos"], 3, model.get_vertex_slice (0));
|
||||
vertex_attrib_pointer (attrs ["uv"], 2, model.get_vertex_slice (1));
|
||||
vertex_attrib_pointer (attrs ["normal"], 3, model.get_vertex_slice (2));
|
||||
}
|
||||
|
||||
const KEY_LEFT: usize = 0;
|
||||
const KEY_RIGHT: usize = KEY_LEFT + 1;
|
||||
const KEY_UP: usize = KEY_RIGHT + 1;
|
||||
|
@ -232,6 +214,8 @@ fn main () {
|
|||
let sky_data = load_small_file ("sky-sphere.iqm", 1024 * 1024);
|
||||
let sky_model = Model::from_slice (&sky_data [..]);
|
||||
|
||||
let renderable_sky = glezz::RenderableModel::from_iqm (&sky_model);
|
||||
|
||||
const FALSE_U8: u8 = 0;
|
||||
|
||||
glezz::enable_vertex_attrib_array (attrs ["pos"]);
|
||||
|
@ -239,7 +223,7 @@ fn main () {
|
|||
glezz::enable_vertex_attrib_array (attrs ["normal"]);
|
||||
|
||||
glezz::enable (gl::DEPTH_TEST);
|
||||
glezz::enable (gl::TEXTURE);
|
||||
glezz::enable (gl::TEXTURE_2D);
|
||||
|
||||
let mut time_step = TimeStep::new (60, 1000);
|
||||
let mut state = WorldState::new ();
|
||||
|
@ -317,22 +301,13 @@ fn main () {
|
|||
|
||||
let draw_sky = true;
|
||||
if draw_sky {
|
||||
unsafe {
|
||||
gl::BindBuffer (gl::ARRAY_BUFFER, 0);
|
||||
gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
glezz::uniform_matrix_4fv (unis ["mvp"], &sky_mvp_mat);
|
||||
glezz::uniform_3fv (unis ["albedo"], &white);
|
||||
glezz::uniform_3fv (unis ["min_bright"], &white);
|
||||
glezz::uniform_3fv (unis ["min_albedo"], &black);
|
||||
glezz::uniform_1i (unis ["texture"], 0);
|
||||
|
||||
unsafe {
|
||||
point_to_model (&attrs, &sky_model);
|
||||
|
||||
gl::DrawElements (gl::TRIANGLES, (sky_model.meshes [0].num_triangles * 3) as i32, gl::UNSIGNED_INT, &sky_model.get_index_slice (0) [0] as *const u8 as *const c_void);
|
||||
}
|
||||
renderable_sky.draw (&attrs, 0);
|
||||
}
|
||||
|
||||
window.gl_swap_window ();
|
||||
|
|
74
src/glezz.rs
74
src/glezz.rs
|
@ -77,24 +77,19 @@ pub struct VertexBuffer {
|
|||
id: u32,
|
||||
// Not bytes.
|
||||
len: usize,
|
||||
// Assuming arrays are packed, not interleaved
|
||||
// Typically 3, or 2 for UV.
|
||||
num_coords: i32,
|
||||
}
|
||||
|
||||
impl VertexBuffer {
|
||||
pub fn from_slice (slice: &[u8], num_coords: i32) -> Self {
|
||||
pub fn from_slice (slice: &[f32]) -> Self {
|
||||
const FLOAT_SIZE: usize = 4;
|
||||
|
||||
assert_eq! (slice.len () % (FLOAT_SIZE * (num_coords as usize)), 0);
|
||||
|
||||
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 ().try_into ().unwrap (), &slice [0] as *const u8 as *const c_void, gl::STATIC_DRAW);
|
||||
gl::BufferData (gl::ARRAY_BUFFER, (slice.len () * 4).try_into ().unwrap (), &slice [0] as *const f32 as *const c_void, gl::STATIC_DRAW);
|
||||
}
|
||||
assert! (id != 0);
|
||||
id
|
||||
|
@ -103,7 +98,6 @@ impl VertexBuffer {
|
|||
Self {
|
||||
id,
|
||||
len: slice.len (),
|
||||
num_coords,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +125,6 @@ struct IndexBuffer {
|
|||
id: u32,
|
||||
// Not bytes. Number of indexes.
|
||||
len: usize,
|
||||
min: u32,
|
||||
max: u32,
|
||||
}
|
||||
|
||||
|
@ -139,7 +132,6 @@ impl IndexBuffer {
|
|||
pub fn from_slice (slice: &[u8]) -> Self {
|
||||
let mut rdr = Cursor::new (slice);
|
||||
|
||||
let mut min = None;
|
||||
let mut max = None;
|
||||
|
||||
const IDX_SIZE: usize = 4;
|
||||
|
@ -149,11 +141,6 @@ impl IndexBuffer {
|
|||
for _ in 0..slice.len () / IDX_SIZE {
|
||||
let idx = rdr.read_u32::<LittleEndian> ().unwrap ();
|
||||
|
||||
min = match min {
|
||||
None => Some (idx),
|
||||
Some (min) => Some (cmp::min (min, idx)),
|
||||
};
|
||||
|
||||
max = match max {
|
||||
None => Some (idx),
|
||||
Some (max) => Some (cmp::max (max, idx)),
|
||||
|
@ -175,7 +162,6 @@ impl IndexBuffer {
|
|||
Self {
|
||||
id,
|
||||
len: slice.len () / IDX_SIZE,
|
||||
min: min.unwrap (),
|
||||
max: max.unwrap (),
|
||||
}
|
||||
}
|
||||
|
@ -211,46 +197,51 @@ struct RenderableMesh {
|
|||
}
|
||||
|
||||
pub struct RenderableModel {
|
||||
pos: Vec <f32>,
|
||||
uv: Vec <f32>,
|
||||
normals: Vec <f32>,
|
||||
num_pos: usize,
|
||||
num_uv: usize,
|
||||
num_normal: usize,
|
||||
|
||||
vertexes: VertexBuffer,
|
||||
indexes: IndexBuffer,
|
||||
|
||||
meshes: Vec <RenderableMesh>,
|
||||
}
|
||||
|
||||
unsafe fn vertex_attrib_pointer (id: Option <u32>, num_coords: i32, slice: &[f32]) {
|
||||
unsafe fn vertex_attrib_pointer (id: Option <u32>, num_coords: i32, float_offset: usize) {
|
||||
const FALSE_U8: u8 = 0;
|
||||
const FLOAT_SIZE: i32 = 4;
|
||||
|
||||
if let Some (id) = id {
|
||||
gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, &slice [0] as *const f32 as *const c_void);
|
||||
gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, (float_offset * 4) as *const u8 as *const c_void);
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderableModel {
|
||||
pub fn from_iqm (model: &iqm::Model) -> RenderableModel {
|
||||
let pos_bytes = model.get_vertex_slice (iqm::types::POSITION);
|
||||
let mut pos_vec = vec! [0.0; pos_bytes.len () / 4];
|
||||
LittleEndian::read_f32_into (pos_bytes, &mut pos_vec [..]);
|
||||
|
||||
let uv_bytes = model.get_vertex_slice (iqm::types::TEXCOORD);
|
||||
let mut uv_vec = vec! [0.0; uv_bytes.len () / 4];
|
||||
LittleEndian::read_f32_into (uv_bytes, &mut uv_vec [..]);
|
||||
|
||||
let normal_bytes = model.get_vertex_slice (iqm::types::NORMAL);
|
||||
let mut normal_vec = vec! [0.0; normal_bytes.len () / 4];
|
||||
LittleEndian::read_f32_into (normal_bytes, &mut normal_vec [..]);
|
||||
|
||||
let num_pos = pos_bytes.len () / 4;
|
||||
let num_uv = uv_bytes.len () / 4;
|
||||
let num_normal = normal_bytes.len () / 4;
|
||||
|
||||
let mut vertex_vec = vec! [0.0; num_pos + num_uv + num_normal];
|
||||
|
||||
LittleEndian::read_f32_into (pos_bytes, &mut vertex_vec [0..num_pos]);
|
||||
LittleEndian::read_f32_into (uv_bytes, &mut vertex_vec [num_pos..num_pos + num_uv]);
|
||||
LittleEndian::read_f32_into (normal_bytes, &mut vertex_vec [num_pos + num_uv..num_pos + num_uv + num_normal]);
|
||||
|
||||
let vertexes = VertexBuffer::from_slice (&vertex_vec);
|
||||
|
||||
let index_slice = model.get_all_indexes ();
|
||||
let indexes = IndexBuffer::from_slice (index_slice);
|
||||
|
||||
let max_index: usize = indexes.max.try_into ().unwrap ();
|
||||
|
||||
assert! (max_index * 3 < pos_vec.len ());
|
||||
assert! (max_index * 2 < uv_vec.len ());
|
||||
assert! (max_index * 3 < normal_vec.len ());
|
||||
assert! (max_index * 3 < num_pos);
|
||||
assert! (max_index * 2 < num_uv);
|
||||
assert! (max_index * 3 < num_normal);
|
||||
|
||||
let meshes = model.meshes.iter ()
|
||||
.map (|mesh| RenderableMesh {
|
||||
|
@ -260,10 +251,11 @@ impl RenderableModel {
|
|||
.collect ();
|
||||
|
||||
Self {
|
||||
pos: pos_vec,
|
||||
uv: uv_vec,
|
||||
normals: normal_vec,
|
||||
num_pos,
|
||||
num_uv,
|
||||
num_normal,
|
||||
|
||||
vertexes,
|
||||
indexes,
|
||||
meshes,
|
||||
}
|
||||
|
@ -273,13 +265,13 @@ impl RenderableModel {
|
|||
{
|
||||
let mesh = &self.meshes [mesh_num];
|
||||
|
||||
self.vertexes.bind ();
|
||||
self.indexes.bind ();
|
||||
|
||||
unsafe {
|
||||
gl::BindBuffer (gl::ARRAY_BUFFER, 0);
|
||||
self.indexes.bind ();
|
||||
|
||||
vertex_attrib_pointer (attrs ["pos"], 3, &self.pos);
|
||||
vertex_attrib_pointer (attrs ["uv"], 2, &self.uv);
|
||||
vertex_attrib_pointer (attrs ["normal"], 3, &self.normals);
|
||||
vertex_attrib_pointer (attrs ["pos"], 3, 0);
|
||||
vertex_attrib_pointer (attrs ["uv"], 2, self.num_pos);
|
||||
vertex_attrib_pointer (attrs ["normal"], 3, self.num_pos + self.num_uv);
|
||||
|
||||
gl::DrawElements (gl::TRIANGLES, mesh.num_triangles * 3, gl::UNSIGNED_INT, (mesh.first_triangle * 3 * 4) as *const u8 as *const c_void);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue