pls force push this
This commit is contained in:
2025-10-01 11:27:35 +02:00
parent a8d83d589a
commit c3b3e3bd98
2 changed files with 243 additions and 222 deletions

241
gloom-rs/src/draw.rs Normal file
View File

@@ -0,0 +1,241 @@
use crate::shader::Shader;
use crate::scene_graph::SceneNode;
use std::collections::HashMap;
use std::{ mem, ptr, os::raw::c_void };
use std::thread;
use std::sync::{Mutex, Arc, RwLock};
use crate::mesh::{ Mesh, Terrain, Helicopter };
// 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<T>(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<T>(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::<u64>()
fn size_of<T>() -> i32 {
mem::size_of::<T>() as i32
}
// Get an offset in bytes for n units of type T, represented as a relative pointer
// Example usage: offset::<u64>(4)
// Get an offset in bytes for n units of type T, represented as a relative pointer
// Example usage: offset::<u64>(4)
fn offset<T>(n: u32) -> *const c_void {
(n * mem::size_of::<T>() as u32) as *const c_void
}
// ptr::null()
pub unsafe fn draw_scene(node: &SceneNode,
view_projection_matrix: &glm::Mat4,
mut transformation_so_far: glm::Mat4,
shader: &Shader,
elapsed: f32
) {
let mut model_matrix = glm::identity();
// then apply nodes actual translation
model_matrix = glm::translate(&model_matrix, &node.position);
// translate to pivot, rotate, translate back
model_matrix = glm::translate(&model_matrix, &node.reference_point);
model_matrix = glm::rotate_z(&model_matrix, node.rotation.z);
model_matrix = glm::rotate_y(&model_matrix, node.rotation.y);
model_matrix = glm::rotate_x(&model_matrix, node.rotation.x);
model_matrix = glm::translate(&model_matrix, &-node.reference_point);
// combine with parent
transformation_so_far = transformation_so_far * model_matrix;
let loc = shader.get_uniform_location("transform");
gl::UniformMatrix4fv(loc, 1, gl::FALSE, (view_projection_matrix * transformation_so_far).as_ptr());
if node.index_count >= 0 {
gl::BindVertexArray(node.vao_id);
gl::DrawElements(gl::TRIANGLES, node.index_count, gl::UNSIGNED_INT, ptr::null());
}
for &child in &node.children {
draw_scene(&*child, view_projection_matrix, transformation_so_far, shader, elapsed);
}
}
// == // Generate your VAO here
unsafe fn create_vao(vertices: &Vec<f32>, indices: &Vec<u32>, colors: &Vec<f32>, normals: &Vec<f32>, id:u32) -> u32 {
// generate a VAO and bind it
let mut vao_id: u32 = id;
gl::GenVertexArrays(1, &mut vao_id);
gl::BindVertexArray(vao_id);
// -- vertex buffer --
// generate a VBO and bind it
let mut vertices_vbo_id: u32 = 0;
gl::GenBuffers(1, &mut vertices_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, vertices_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(vertices),
pointer_to_array(vertices),
gl::STATIC_DRAW
);
// configure a VAP for the data and enable it
let vertices_index = 0;
gl::VertexAttribPointer(vertices_index, 3, gl::FLOAT, gl::FALSE, size_of::<f32>()*3, ptr::null());
gl::EnableVertexAttribArray(vertices_index);
// -- color buffer --
// generate a VBO and bind it
let mut colors_vbo_id: u32 = 1;
gl::GenBuffers(1, &mut colors_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, colors_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(colors),
pointer_to_array(colors),
gl::STATIC_DRAW
);
// configure a VAP for the data and enable it
let colors_index = 1;
gl::VertexAttribPointer(colors_index, 4, gl::FLOAT, gl::FALSE, size_of::<f32>()*4, ptr::null());
gl::EnableVertexAttribArray(colors_index);
// -- normal buffer --
// generate a VBO and bind it
let mut normals_vbo_id: u32 = 2;
gl::GenBuffers(1, &mut normals_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, normals_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(normals),
pointer_to_array(normals),
gl::STATIC_DRAW
);
// configure a VAP for the normal data and enable it
let normals_index = 2;
gl::VertexAttribPointer(normals_index, 3, gl::FLOAT, gl::FALSE, size_of::<f32>()*3, ptr::null());
gl::EnableVertexAttribArray(normals_index);
// -- index buffer --
// generate a IBO and bind it
let mut ibo_id: u32 = 0;
gl::GenBuffers(1, &mut ibo_id);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ibo_id);
// fill it with data
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
byte_size_of_array(indices),
pointer_to_array(indices),
gl::STATIC_DRAW
);
return vao_id;
}
type MeshMap = HashMap<u32, Mesh>;
struct World {
lunar:
}
pub fn load_models() -> World {
let lunarsurface = Terrain::load(&"resources/lunarsurface.obj");
let helicopter = Helicopter::load(&"resources/helicopter.obj");
let heli_body = helicopter.body;
let heli_door = helicopter.door;
let heli_main_rotor = helicopter.main_rotor;
let heli_tail_rotor = helicopter.tail_rotor;
return HashMap::from([
(unsafe {
create_vao(&lunarsurface.vertices, &lunarsurface.indices, &lunarsurface.colors, &lunarsurface.normals, 1)
}, lunarsurface),
(unsafe {
create_vao(&heli_body.vertices, &heli_body.indices, &heli_body.colors, &heli_body.normals, 2)
}, heli_body),
(unsafe {
create_vao(&heli_door.vertices, &heli_door.indices, &heli_door.colors, &heli_door.normals, 2)
}, heli_door),
(unsafe {
create_vao(&heli_main_rotor.vertices, &heli_main_rotor.indices, &heli_main_rotor.colors, &heli_main_rotor.normals, 2)
}, heli_main_rotor),
(unsafe {
create_vao(&heli_tail_rotor.vertices, &heli_tail_rotor.indices, &heli_tail_rotor.colors, &heli_tail_rotor.normals, 2)
}, heli_tail_rotor),
]);
}
pub fn setup_scene_graph(world: World) {
// Define scene nodes
let mut scene_node = SceneNode::new();
let mut lunar_node = SceneNode::from_vao(world.lunar_vao_id, world.lunarsurface.index_count);
let mut heli_root_node = SceneNode::new();
let mut heli_body_node = SceneNode::from_vao(world.heli_body_vao_id, world.heli_body.index_count);
let mut heli_door_node = SceneNode::from_vao(world.heli_door_vao_id, world.heli_door.index_count);
let mut heli_main_rotor_node = SceneNode::from_vao(world.heli_main_rotor_vao_id, world.heli_main_rotor.index_count);
let mut heli_tail_rotor_node = SceneNode::from_vao(world.heli_tail_rotor_vao_id, world.heli_tail_rotor.index_count);
// Set scene graph hierarchy
heli_root_node.add_child(&heli_body_node);
heli_root_node.add_child(&heli_door_node);
heli_root_node.add_child(&heli_main_rotor_node);
heli_root_node.add_child(&heli_tail_rotor_node);
lunar_node.add_child(&heli_root_node);
scene_node.add_child(&lunar_node);
// Set model reference points
scene_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
lunar_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
heli_root_node.reference_point = glm::vec3(0.0f32, 0.0f32, 0.0f32);
heli_body_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
heli_door_node.reference_point = glm::vec3(0.0f32, 0.0f32, 0.0f32);
heli_main_rotor_node.reference_point = glm::vec3(0.0f32, 2.0f32, 0.0f32);
heli_tail_rotor_node.reference_point = glm::vec3(0.35f32, 2.3f32, 10.4f32);
lunar_node.position.y = -10.0f32;
heli_main_rotor_node.rotation = glm::vec3(0.0f32, 2.0f32, 0.0f32);
heli_tail_rotor_node.rotation = glm::vec3(1.0f32, 0.0f32, 0.0f32);
}
pub fn update(elapsed: f32, world: World, perspective: glm::Mat4, transformation: glm::Mat4 ) {
// Apply perspective transformation last
let transform_thus_far = perspective * transformation;
let rotor_speed = 60.0f32;
// let iter_heli_heading = toolbox::simple_heading_animation(elapsed);
// heli_root_node.position.x = iter_heli_heading.x;
// heli_root_node.position.z = iter_heli_heading.z;
// heli_root_node.rotation.z = iter_heli_heading.roll;
// heli_root_node.rotation.y = iter_heli_heading.yaw;
// heli_root_node.rotation.x = iter_heli_heading.pitch;
world.heli_root_node.rotation.y = elapsed;
world.heli_main_rotor_node.rotation.y = elapsed * rotor_speed;
world.heli_tail_rotor_node.rotation.x = elapsed * rotor_speed;
draw::draw_scene(&scene_node, &transform_thus_far, glm::identity(), &simple_shader, elapsed);
}

View File

@@ -8,7 +8,7 @@
#![allow(unused_variables)]
*/
extern crate nalgebra_glm as glm;
use std::{ mem, ptr, os::raw::c_void };
use std::ptr;
use std::thread;
use std::sync::{Mutex, Arc, RwLock};
@@ -17,13 +17,10 @@ mod util;
mod mesh;
mod scene_graph;
mod toolbox;
mod draw;
use glm::{identity, rotation};
use glutin::event::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState::{Pressed, Released}, VirtualKeyCode::{self, *}};
use glutin::event_loop::ControlFlow;
use scene_graph::SceneNode;
use crate::mesh::{Helicopter, Terrain};
// initial window size
const INITIAL_SCREEN_W: u32 = 800;
@@ -31,118 +28,7 @@ const INITIAL_SCREEN_H: u32 = 600;
// == // Helper functions to make interacting with OpenGL a little bit prettier. You *WILL* need these! // == //
// 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<T>(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<T>(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::<u64>()
fn size_of<T>() -> i32 {
mem::size_of::<T>() as i32
}
// Get an offset in bytes for n units of type T, represented as a relative pointer
// Example usage: offset::<u64>(4)
// Get an offset in bytes for n units of type T, represented as a relative pointer
// Example usage: offset::<u64>(4)
fn offset<T>(n: u32) -> *const c_void {
(n * mem::size_of::<T>() as u32) as *const c_void
}
// ptr::null()
// == // Generate your VAO here
unsafe fn create_vao(vertices: &Vec<f32>, indices: &Vec<u32>, colors: &Vec<f32>, normals: &Vec<f32>, id:u32) -> u32 {
// generate a VAO and bind it
let mut vao_id: u32 = id;
gl::GenVertexArrays(1, &mut vao_id);
gl::BindVertexArray(vao_id);
// -- vertex buffer --
// generate a VBO and bind it
let mut vertices_vbo_id: u32 = 0;
gl::GenBuffers(1, &mut vertices_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, vertices_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(vertices),
pointer_to_array(vertices),
gl::STATIC_DRAW
);
// configure a VAP for the data and enable it
let vertices_index = 0;
gl::VertexAttribPointer(vertices_index, 3, gl::FLOAT, gl::FALSE, size_of::<f32>()*3, ptr::null());
gl::EnableVertexAttribArray(vertices_index);
// -- color buffer --
// generate a VBO and bind it
let mut colors_vbo_id: u32 = 1;
gl::GenBuffers(1, &mut colors_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, colors_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(colors),
pointer_to_array(colors),
gl::STATIC_DRAW
);
// configure a VAP for the data and enable it
let colors_index = 1;
gl::VertexAttribPointer(colors_index, 4, gl::FLOAT, gl::FALSE, size_of::<f32>()*4, ptr::null());
gl::EnableVertexAttribArray(colors_index);
// -- normal buffer --
// generate a VBO and bind it
let mut normals_vbo_id: u32 = 2;
gl::GenBuffers(1, &mut normals_vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, normals_vbo_id);
// fill it with data
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(normals),
pointer_to_array(normals),
gl::STATIC_DRAW
);
// configure a VAP for the normal data and enable it
let normals_index = 2;
gl::VertexAttribPointer(normals_index, 3, gl::FLOAT, gl::FALSE, size_of::<f32>()*3, ptr::null());
gl::EnableVertexAttribArray(normals_index);
// -- index buffer --
// generate a IBO and bind it
let mut ibo_id: u32 = 0;
gl::GenBuffers(1, &mut ibo_id);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ibo_id);
// fill it with data
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
byte_size_of_array(indices),
pointer_to_array(indices),
gl::STATIC_DRAW
);
return vao_id;
}
fn main() {
@@ -205,61 +91,6 @@ fn main() {
println!("GLSL\t: {}", util::get_gl_string(gl::SHADING_LANGUAGE_VERSION));
}
// == // Set up your VAO around here
let lunarsurface = Terrain::load(&"resources/lunarsurface.obj");
let helicopter = Helicopter::load(&"resources/helicopter.obj");
let heli_body = helicopter.body;
let heli_door = helicopter.door;
let heli_main_rotor = helicopter.main_rotor;
let heli_tail_rotor = helicopter.tail_rotor;
//
let lunar_vao_id = unsafe {
create_vao(&lunarsurface.vertices, &lunarsurface.indices, &lunarsurface.colors, &lunarsurface.normals, 1)
};
let heli_body_vao_id = unsafe {
create_vao(&heli_body.vertices, &heli_body.indices, &heli_body.colors, &heli_body.normals, 2)
};
let heli_door_vao_id = unsafe {
create_vao(&heli_door.vertices, &heli_door.indices, &heli_door.colors, &heli_door.normals, 2)
};
let heli_main_rotor_vao_id = unsafe {
create_vao(&heli_main_rotor.vertices, &heli_main_rotor.indices, &heli_main_rotor.colors, &heli_main_rotor.normals, 2)
};
let heli_tail_rotor_vao_id = unsafe {
create_vao(&heli_tail_rotor.vertices, &heli_tail_rotor.indices, &heli_tail_rotor.colors, &heli_tail_rotor.normals, 2)
};
// Define scene nodes
let mut scene_node = SceneNode::new();
let mut lunar_node = SceneNode::from_vao(lunar_vao_id, lunarsurface.index_count);
let mut heli_root_node = SceneNode::new();
let mut heli_body_node = SceneNode::from_vao(heli_body_vao_id, heli_body.index_count);
let mut heli_door_node = SceneNode::from_vao(heli_door_vao_id, heli_door.index_count);
let mut heli_main_rotor_node = SceneNode::from_vao(heli_main_rotor_vao_id, heli_main_rotor.index_count);
let mut heli_tail_rotor_node = SceneNode::from_vao(heli_tail_rotor_vao_id, heli_tail_rotor.index_count);
// Set scene graph hierarchy
heli_root_node.add_child(&heli_body_node);
heli_root_node.add_child(&heli_door_node);
heli_root_node.add_child(&heli_main_rotor_node);
heli_root_node.add_child(&heli_tail_rotor_node);
lunar_node.add_child(&heli_root_node);
scene_node.add_child(&lunar_node);
// Set model reference points
scene_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
lunar_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
heli_root_node.reference_point = glm::vec3(0.0f32, 0.0f32, 0.0f32);
heli_body_node.reference_point = glm::vec3(0.0f32,0.0f32, 0.0f32);
heli_door_node.reference_point = glm::vec3(0.0f32, 0.0f32, 0.0f32);
heli_main_rotor_node.reference_point = glm::vec3(0.0f32, 2.0f32, 0.0f32);
heli_tail_rotor_node.reference_point = glm::vec3(0.35f32, 2.3f32, 10.4f32);
lunar_node.position.y = -10.0f32;
heli_main_rotor_node.rotation = glm::vec3(0.0f32, 2.0f32, 0.0f32);
heli_tail_rotor_node.rotation = glm::vec3(1.0f32, 0.0f32, 0.0f32);
let mut transformation: glm::Mat4;
let perspective: glm::Mat4 = glm::perspective(
@@ -395,57 +226,6 @@ fn main() {
gl::ClearColor(0.40, 0.55, 1.0, 1.0); // night sky
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
// Apply perspective transformation last
let transform_thus_far = perspective * transformation;
let rotor_speed = 60.0f32;
// let iter_heli_heading = toolbox::simple_heading_animation(elapsed);
// heli_root_node.position.x = iter_heli_heading.x;
// heli_root_node.position.z = iter_heli_heading.z;
// heli_root_node.rotation.z = iter_heli_heading.roll;
// heli_root_node.rotation.y = iter_heli_heading.yaw;
// heli_root_node.rotation.x = iter_heli_heading.pitch;
heli_root_node.rotation.y = elapsed;
heli_main_rotor_node.rotation.y = elapsed * rotor_speed;
heli_tail_rotor_node.rotation.x = elapsed * rotor_speed;
unsafe fn draw_scene(node: &scene_graph::SceneNode,
view_projection_matrix: &glm::Mat4,
mut transformation_so_far: glm::Mat4,
shader: &shader::Shader,
elapsed: f32
) {
let mut model_matrix = identity();
// then apply nodes actual translation
model_matrix = glm::translate(&model_matrix, &node.position);
// translate to pivot, rotate, translate back
model_matrix = glm::translate(&model_matrix, &node.reference_point);
model_matrix = glm::rotate_z(&model_matrix, node.rotation.z);
model_matrix = glm::rotate_y(&model_matrix, node.rotation.y);
model_matrix = glm::rotate_x(&model_matrix, node.rotation.x);
model_matrix = glm::translate(&model_matrix, &-node.reference_point);
// combine with parent
transformation_so_far = transformation_so_far * model_matrix;
let loc = shader.get_uniform_location("transform");
gl::UniformMatrix4fv(loc, 1, gl::FALSE, (view_projection_matrix * transformation_so_far).as_ptr());
if node.index_count >= 0 {
gl::BindVertexArray(node.vao_id);
gl::DrawElements(gl::TRIANGLES, node.index_count, gl::UNSIGNED_INT, ptr::null());
}
for &child in &node.children {
draw_scene(&*child, view_projection_matrix, transformation_so_far, shader, elapsed);
}
}
draw_scene(&scene_node, &transform_thus_far, identity(), &simple_shader, elapsed);
// Display the new color buffer on the display
context.swap_buffers().unwrap(); // we use "double buffering" to avoid artifacts
}