From d4f590b177d6330f3a58e65fef17ec956eb7d62e Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Thu, 2 Oct 2025 11:30:47 +0200 Subject: [PATCH] move create_vao to mesh and utils to util --- gloom-rs/src/draw.rs | 128 +++---------------------------------------- gloom-rs/src/main.rs | 1 - gloom-rs/src/mesh.rs | 81 ++++++++++++++++++++++++++- gloom-rs/src/util.rs | 29 ++++++++++ 4 files changed, 115 insertions(+), 124 deletions(-) diff --git a/gloom-rs/src/draw.rs b/gloom-rs/src/draw.rs index 239870d..b73c666 100644 --- a/gloom-rs/src/draw.rs +++ b/gloom-rs/src/draw.rs @@ -2,39 +2,13 @@ use crate::shader::Shader; use crate::scene_graph::SceneNode; use std::collections::HashMap; -use std::{ mem, ptr, os::raw::c_void }; +use std::ptr; use std::mem::ManuallyDrop; use std::pin::Pin; use crate::mesh::{ Mesh, Terrain, Helicopter }; use crate::toolbox; -// Get the size of an arbitrary array of numbers measured in bytes -// Example usage: byte_size_of_array(my_array) -fn byte_size_of_array(val: &[T]) -> isize { - std::mem::size_of_val(&val[..]) as isize -} - -// Get the OpenGL-compatible pointer to an arbitrary array of numbers -// Example usage: pointer_to_array(my_array) -fn pointer_to_array(val: &[T]) -> *const c_void { - &val[0] as *const T as *const c_void -} - -// Get the size of the given type in bytes -// Example usage: size_of::() -fn size_of() -> i32 { - mem::size_of::() as i32 -} - -// Get an offset in bytes for n units of type T, represented as a relative pointer -// Example usage: offset::(4) -// Get an offset in bytes for n units of type T, represented as a relative pointer -// Example usage: offset::(4) -fn offset(n: u32) -> *const c_void { - (n * mem::size_of::() as u32) as *const c_void -} -// ptr::null() unsafe fn draw_scene(node: &SceneNode, view_projection_matrix: &glm::Mat4, @@ -70,78 +44,7 @@ unsafe fn draw_scene(node: &SceneNode, } } -// draw.rs - Replace create_vao function -unsafe fn create_vao(vertices: &Vec, indices: &Vec, colors: &Vec, normals: &Vec) -> u32 { - // Let OpenGL generate the VAO ID - let mut vao_id: u32 = 0; - gl::GenVertexArrays(1, &mut vao_id); - gl::BindVertexArray(vao_id); - - // -- vertex buffer -- - let mut vertices_vbo_id: u32 = 0; - gl::GenBuffers(1, &mut vertices_vbo_id); - gl::BindBuffer(gl::ARRAY_BUFFER, vertices_vbo_id); - - gl::BufferData( - gl::ARRAY_BUFFER, - byte_size_of_array(vertices), - pointer_to_array(vertices), - gl::STATIC_DRAW - ); - - let vertices_index = 0; - gl::VertexAttribPointer(vertices_index, 3, gl::FLOAT, gl::FALSE, size_of::()*3, ptr::null()); - gl::EnableVertexAttribArray(vertices_index); - - // -- color buffer -- - let mut colors_vbo_id: u32 = 0; - gl::GenBuffers(1, &mut colors_vbo_id); - gl::BindBuffer(gl::ARRAY_BUFFER, colors_vbo_id); - - gl::BufferData( - gl::ARRAY_BUFFER, - byte_size_of_array(colors), - pointer_to_array(colors), - gl::STATIC_DRAW - ); - - let colors_index = 1; - gl::VertexAttribPointer(colors_index, 4, gl::FLOAT, gl::FALSE, size_of::()*4, ptr::null()); - gl::EnableVertexAttribArray(colors_index); - - // -- normal buffer -- - let mut normals_vbo_id: u32 = 0; - gl::GenBuffers(1, &mut normals_vbo_id); - gl::BindBuffer(gl::ARRAY_BUFFER, normals_vbo_id); - - gl::BufferData( - gl::ARRAY_BUFFER, - byte_size_of_array(normals), - pointer_to_array(normals), - gl::STATIC_DRAW - ); - - let normals_index = 2; - gl::VertexAttribPointer(normals_index, 3, gl::FLOAT, gl::FALSE, size_of::()*3, ptr::null()); - gl::EnableVertexAttribArray(normals_index); - - // -- index buffer -- - let mut ibo_id: u32 = 0; - gl::GenBuffers(1, &mut ibo_id); - gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ibo_id); - - gl::BufferData( - gl::ELEMENT_ARRAY_BUFFER, - byte_size_of_array(indices), - pointer_to_array(indices), - gl::STATIC_DRAW - ); - - return vao_id; -} - pub struct World { - pub meshes: HashMap, pub nodes: HashMap>>>, } @@ -157,31 +60,16 @@ pub enum Nodes { } pub fn load_models() -> HashMap { - let mut lunarsurface = Terrain::load(&"resources/lunarsurface.obj"); let helicopter = Helicopter::load(&"resources/helicopter.obj"); - let mut heli_body = helicopter.body; - let mut heli_door = helicopter.door; - let mut heli_main_rotor = helicopter.main_rotor; - let mut heli_tail_rotor = helicopter.tail_rotor; - - unsafe { - lunarsurface.vao_id = create_vao(&lunarsurface.vertices, &lunarsurface.indices, &lunarsurface.colors, &lunarsurface.normals); - heli_body.vao_id = create_vao(&heli_body.vertices, &heli_body.indices, &heli_body.colors, &heli_body.normals); - heli_door.vao_id = create_vao(&heli_door.vertices, &heli_door.indices, &heli_door.colors, &heli_door.normals); - heli_main_rotor.vao_id = create_vao(&heli_main_rotor.vertices, &heli_main_rotor.indices, &heli_main_rotor.colors, &heli_main_rotor.normals); - heli_tail_rotor.vao_id = create_vao(&heli_tail_rotor.vertices, &heli_tail_rotor.indices, &heli_tail_rotor.colors, &heli_tail_rotor.normals); - } - - return HashMap::from([ - (Nodes::LunarSurface, lunarsurface), - (Nodes::HeliBody, heli_body), - (Nodes::HeliDoor, heli_door), - (Nodes::HeliMainRotor, heli_main_rotor), - (Nodes::HeliTailRotor, heli_tail_rotor), - ]); + HashMap::from([ + (Nodes::LunarSurface, Terrain::load(&"resources/lunarsurface.obj")), + (Nodes::HeliBody, helicopter.body), + (Nodes::HeliDoor, helicopter.door), + (Nodes::HeliMainRotor, helicopter.main_rotor), + (Nodes::HeliTailRotor, helicopter.tail_rotor), + ]) } - pub fn setup_scene_graph(meshes: &HashMap) -> HashMap>>> { let mut nodes = HashMap::new(); diff --git a/gloom-rs/src/main.rs b/gloom-rs/src/main.rs index 171b677..e37b1f0 100644 --- a/gloom-rs/src/main.rs +++ b/gloom-rs/src/main.rs @@ -97,7 +97,6 @@ fn main() { let meshes = draw::load_models(); let nodes = draw::setup_scene_graph(&meshes); let mut world = draw::World { - meshes: meshes, nodes: nodes }; diff --git a/gloom-rs/src/mesh.rs b/gloom-rs/src/mesh.rs index ded9bf6..3326d2f 100644 --- a/gloom-rs/src/mesh.rs +++ b/gloom-rs/src/mesh.rs @@ -1,5 +1,8 @@ use tobj; +use crate::util; +use std::ptr; + // internal helper fn generate_color_vec(color: [f32; 4], num: usize) -> Vec { color.iter().cloned().cycle().take(num*4).collect() @@ -20,17 +23,89 @@ impl Mesh { pub fn from(mesh: tobj::Mesh, color: [f32; 4]) -> Self { let num_verts = mesh.positions.len() / 3; let index_count = mesh.indices.len() as i32; - Mesh { + let mut m = Mesh { vertices: mesh.positions, normals: mesh.normals, indices: mesh.indices, colors: generate_color_vec(color, num_verts), index_count, - vao_id: 0 - } + vao_id: 0, + }; + unsafe { m.vao_id = m.create_vao(); } + m + } + + unsafe fn create_vao(&self) -> u32 { + // Let OpenGL generate the VAO ID + let mut vao_id: u32 = 0; + gl::GenVertexArrays(1, &mut vao_id); + gl::BindVertexArray(vao_id); + + // -- vertex buffer -- + let mut vertices_vbo_id: u32 = 0; + gl::GenBuffers(1, &mut vertices_vbo_id); + gl::BindBuffer(gl::ARRAY_BUFFER, vertices_vbo_id); + + gl::BufferData( + gl::ARRAY_BUFFER, + util::byte_size_of_array(&self.vertices), + util::pointer_to_array(&self.vertices), + gl::STATIC_DRAW + ); + + let vertices_index = 0; + gl::VertexAttribPointer(vertices_index, 3, gl::FLOAT, gl::FALSE, util::size_of::()*3, ptr::null()); + gl::EnableVertexAttribArray(vertices_index); + + // -- color buffer -- + let mut colors_vbo_id: u32 = 0; + gl::GenBuffers(1, &mut colors_vbo_id); + gl::BindBuffer(gl::ARRAY_BUFFER, colors_vbo_id); + + gl::BufferData( + gl::ARRAY_BUFFER, + util::byte_size_of_array(&self.colors), + util::pointer_to_array(&self.colors), + gl::STATIC_DRAW + ); + + let colors_index = 1; + gl::VertexAttribPointer(colors_index, 4, gl::FLOAT, gl::FALSE, util::size_of::()*4, ptr::null()); + gl::EnableVertexAttribArray(colors_index); + + // -- normal buffer -- + let mut normals_vbo_id: u32 = 0; + gl::GenBuffers(1, &mut normals_vbo_id); + gl::BindBuffer(gl::ARRAY_BUFFER, normals_vbo_id); + + gl::BufferData( + gl::ARRAY_BUFFER, + util::byte_size_of_array(&self.normals), + util::pointer_to_array(&self.normals), + gl::STATIC_DRAW + ); + + let normals_index = 2; + gl::VertexAttribPointer(normals_index, 3, gl::FLOAT, gl::FALSE, util::size_of::()*3, ptr::null()); + gl::EnableVertexAttribArray(normals_index); + + // -- index buffer -- + let mut ibo_id: u32 = 0; + gl::GenBuffers(1, &mut ibo_id); + gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ibo_id); + + gl::BufferData( + gl::ELEMENT_ARRAY_BUFFER, + util::byte_size_of_array(&self.indices), + util::pointer_to_array(&self.indices), + gl::STATIC_DRAW + ); + + return vao_id; } } + // Lunar terrain pub struct Terrain; diff --git a/gloom-rs/src/util.rs b/gloom-rs/src/util.rs index 83938c1..d165a0a 100644 --- a/gloom-rs/src/util.rs +++ b/gloom-rs/src/util.rs @@ -1,6 +1,8 @@ use std::ffi::CString; use libc; +use std::{ mem, os::raw::c_void }; + pub unsafe fn get_gl_string(name: gl::types::GLenum) -> String { std::ffi::CStr::from_ptr(gl::GetString(name) as *mut libc::c_char).to_string_lossy().to_string() } @@ -30,3 +32,30 @@ pub extern "system" fn debug_callback( } } } + +// Get the size of an arbitrary array of numbers measured in bytes +// Example usage: byte_size_of_array(my_array) +pub fn byte_size_of_array(val: &[T]) -> isize { + std::mem::size_of_val(&val[..]) as isize +} + +// Get the OpenGL-compatible pointer to an arbitrary array of numbers +// Example usage: pointer_to_array(my_array) +pub fn pointer_to_array(val: &[T]) -> *const c_void { + &val[0] as *const T as *const c_void +} + +// Get the size of the given type in bytes +// Example usage: size_of::() +pub fn size_of() -> i32 { + mem::size_of::() as i32 +} + +// Get an offset in bytes for n units of type T, represented as a relative pointer +// Example usage: offset::(4) +// Get an offset in bytes for n units of type T, represented as a relative pointer +// Example usage: offset::(4) +pub fn offset(n: u32) -> *const c_void { + (n * mem::size_of::() as u32) as *const c_void +} +// ptr::null()