set up VAO

This commit is contained in:
2025-08-25 19:44:28 +02:00
parent 4f41150b4c
commit 949d6722f0

View File

@@ -8,19 +8,28 @@
#![allow(unused_variables)]
*/
extern crate nalgebra_glm as glm;
use std::{ mem, ptr, os::raw::c_void };
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use std::sync::{Mutex, Arc, RwLock};
use std::{mem, os::raw::c_void, ptr};
mod shader;
mod util;
use glutin::event::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState::{Pressed, Released}, VirtualKeyCode::{self, *}};
use glutin::event::{
DeviceEvent,
ElementState::{Pressed, Released},
Event, KeyboardInput,
VirtualKeyCode::{self, *},
WindowEvent,
};
use glutin::event_loop::ControlFlow;
// initial window size
const INITIAL_SCREEN_W: u32 = 800;
const INITIAL_SCREEN_H: u32 = 600;
// TODO: I used the funny number.
const VERTEX_ATTRIBUTE_INDEX: u32 = 3;
const DIMENSIONS: i32 = 2;
// == // Helper functions to make interacting with OpenGL a little bit prettier. You *WILL* need these! // == //
@@ -51,7 +60,6 @@ fn offset<T>(n: u32) -> *const c_void {
// Get a null pointer (equivalent to an offset of 0)
// ptr::null()
// == // Generate your VAO here
unsafe fn create_vao(vertices: &Vec<f32>, indices: &Vec<u32>) -> u32 {
// Implement me!
@@ -66,20 +74,58 @@ unsafe fn create_vao(vertices: &Vec<f32>, indices: &Vec<u32>) -> u32 {
// * Generate a IBO and bind it
// * Fill it with data
// * Return the ID of the VAO
let mut vao_id = 0;
gl::GenVertexArrays(1, &mut vao_id);
gl::BindVertexArray(vao_id);
let mut vbo_id = 0;
gl::GenBuffers(1, &mut vbo_id);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo_id);
gl::BufferData(
gl::ARRAY_BUFFER,
byte_size_of_array(&vertices),
vertices.as_ptr() as *const c_void,
gl::STATIC_DRAW,
);
let mut max_vertex_attribs = 0;
gl::GetIntegerv(gl::MAX_VERTEX_ATTRIBS, &mut max_vertex_attribs);
println!("max vertex attributes: {max_vertex_attribs}");
gl::VertexAttribPointer(
VERTEX_ATTRIBUTE_INDEX,
DIMENSIONS,
gl::FLOAT,
gl::FALSE,
0,
std::ptr::null(),
);
gl::EnableVertexAttribArray(VERTEX_ATTRIBUTE_INDEX);
0
let mut index_buf_id = 0;
gl::GenBuffers(1, &mut index_buf_id);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, index_buf_id);
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
byte_size_of_array(&indices),
indices.as_ptr() as *const c_void,
gl::STATIC_DRAW,
);
gl::DrawElements(gl::TRIANGLES, indices.len() as i32, gl::UNSIGNED_INT, std::ptr::null());
vao_id
}
fn main() {
// Set up the necessary objects to deal with windows and event handling
let el = glutin::event_loop::EventLoop::new();
let wb = glutin::window::WindowBuilder::new()
.with_title("Gloom-rs")
.with_resizable(true)
.with_inner_size(glutin::dpi::LogicalSize::new(INITIAL_SCREEN_W, INITIAL_SCREEN_H));
let cb = glutin::ContextBuilder::new()
.with_vsync(true);
.with_inner_size(glutin::dpi::LogicalSize::new(
INITIAL_SCREEN_W,
INITIAL_SCREEN_H,
));
let cb = glutin::ContextBuilder::new().with_vsync(true);
let windowed_context = cb.build_windowed(wb, &el).unwrap();
// Uncomment these if you want to use the mouse for controls, but want it to be confined to the screen and/or invisible.
// windowed_context.window().set_cursor_grab(true).expect("failed to grab cursor");
@@ -125,15 +171,27 @@ fn main() {
gl::DebugMessageCallback(Some(util::debug_callback), ptr::null());
// Print some diagnostics
println!("{}: {}", util::get_gl_string(gl::VENDOR), util::get_gl_string(gl::RENDERER));
println!(
"{}: {}",
util::get_gl_string(gl::VENDOR),
util::get_gl_string(gl::RENDERER)
);
println!("OpenGL\t: {}", util::get_gl_string(gl::VERSION));
println!("GLSL\t: {}", util::get_gl_string(gl::SHADING_LANGUAGE_VERSION));
println!(
"GLSL\t: {}",
util::get_gl_string(gl::SHADING_LANGUAGE_VERSION)
);
}
// == // Set up your VAO around here
let my_vao = unsafe { 1337 };
let vertices = vec![-1., 0., 1., 0.5];
let indices = vec![0, 1, 2, 1, 1, 3];
let my_vao = unsafe {
create_vao(&vertices, &indices);
};
println!("created vao!");
// let my_vao = unsafe { 1337 };
// == // Set up your shaders here
@@ -144,19 +202,21 @@ fn main() {
// This snippet is not enough to do the exercise, and will need to be modified (outside
// of just using the correct path), but it only needs to be called once
/*
// TODO: Find out what to do with vertex and fragment shader.
let simple_shader = unsafe {
shader::ShaderBuilder::new()
.attach_file("./path/to/simple/shader.file")
.attach_file("./shaders/simple.vert")
.link()
};
let simple_shader = unsafe {
shader::ShaderBuilder::new()
.attach_file("./shaders/simple.frag")
.link()
};
*/
// Used to demonstrate keyboard handling for exercise 2.
let mut _arbitrary_number = 0.0; // feel free to remove
// The main rendering loop
let first_frame_time = std::time::Instant::now();
let mut previous_frame_time = first_frame_time;
@@ -174,7 +234,9 @@ fn main() {
window_aspect_ratio = new_size.0 as f32 / new_size.1 as f32;
(*new_size).2 = false;
println!("Window was resized to {}x{}", new_size.0, new_size.1);
unsafe { gl::Viewport(0, 0, new_size.0 as i32, new_size.1 as i32); }
unsafe {
gl::Viewport(0, 0, new_size.0 as i32, new_size.1 as i32);
}
}
}
@@ -184,7 +246,6 @@ fn main() {
match key {
// The `VirtualKeyCode` enum is defined here:
// https://docs.rs/winit/0.25.0/winit/event/enum.VirtualKeyCode.html
VirtualKeyCode::A => {
_arbitrary_number += delta_time;
}
@@ -192,15 +253,13 @@ fn main() {
_arbitrary_number -= delta_time;
}
// default handler:
_ => { }
_ => {}
}
}
}
// Handle mouse movement. delta contains the x and y movement of the mouse since last frame in pixels
if let Ok(mut delta) = mouse_delta.lock() {
// == // Optionally access the accumulated mouse movement between
// == // frames here with `delta.0` and `delta.1`
@@ -209,17 +268,12 @@ fn main() {
// == // Please compute camera transforms here (exercise 2 & 3)
unsafe {
// Clear the color and depth buffers
gl::ClearColor(0.035, 0.046, 0.078, 1.0); // night sky
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
// == // Issue the necessary gl:: commands to draw your scene here
}
// Display the new color buffer on the display
@@ -227,12 +281,10 @@ fn main() {
}
});
// == //
// == // From here on down there are only internals.
// == //
// Keep track of the health of the rendering thread
let render_thread_healthy = Arc::new(RwLock::new(true));
let render_thread_watchdog = Arc::clone(&render_thread_healthy);
@@ -257,19 +309,38 @@ fn main() {
}
match event {
Event::WindowEvent { event: WindowEvent::Resized(physical_size), .. } => {
println!("New window size received: {}x{}", physical_size.width, physical_size.height);
Event::WindowEvent {
event: WindowEvent::Resized(physical_size),
..
} => {
println!(
"New window size received: {}x{}",
physical_size.width, physical_size.height
);
if let Ok(mut new_size) = arc_window_size.lock() {
*new_size = (physical_size.width, physical_size.height, true);
}
}
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
*control_flow = ControlFlow::Exit;
}
// Keep track of currently pressed keys to send to the rendering thread
Event::WindowEvent { event: WindowEvent::KeyboardInput {
input: KeyboardInput { state: key_state, virtual_keycode: Some(keycode), .. }, .. }, .. } => {
Event::WindowEvent {
event:
WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: key_state,
virtual_keycode: Some(keycode),
..
},
..
},
..
} => {
if let Ok(mut keys) = arc_pressed_keys.lock() {
match key_state {
Released => {
@@ -277,7 +348,7 @@ fn main() {
let i = keys.iter().position(|&k| k == keycode).unwrap();
keys.remove(i);
}
},
}
Pressed => {
if !keys.contains(&keycode) {
keys.push(keycode);
@@ -288,18 +359,25 @@ fn main() {
// Handle Escape and Q keys separately
match keycode {
Escape => { *control_flow = ControlFlow::Exit; }
Q => { *control_flow = ControlFlow::Exit; }
_ => { }
Escape => {
*control_flow = ControlFlow::Exit;
}
Q => {
*control_flow = ControlFlow::Exit;
}
_ => {}
}
}
Event::DeviceEvent { event: DeviceEvent::MouseMotion { delta }, .. } => {
Event::DeviceEvent {
event: DeviceEvent::MouseMotion { delta },
..
} => {
// Accumulate mouse movement
if let Ok(mut position) = arc_mouse_delta.lock() {
*position = (position.0 + delta.0 as f32, position.1 + delta.1 as f32);
}
}
_ => { }
_ => {}
}
});
}