Diagnostics, mouse input support, uniform location retrieval support for Shader
This commit is contained in:
54
src/main.rs
54
src/main.rs
@@ -1,24 +1,18 @@
|
||||
extern crate nalgebra_glm as glm;
|
||||
use gl::types::*;
|
||||
use std::{
|
||||
mem,
|
||||
ptr,
|
||||
str,
|
||||
os::raw::c_void,
|
||||
};
|
||||
use std::{ mem, ptr, os::raw::c_void };
|
||||
use std::thread;
|
||||
use std::sync::{Mutex, Arc, RwLock};
|
||||
|
||||
mod shader;
|
||||
mod util;
|
||||
|
||||
use glutin::event::{Event, WindowEvent, KeyboardInput, ElementState::{Pressed, Released}, VirtualKeyCode::{self, *}};
|
||||
use glutin::event::{Event, WindowEvent, DeviceEvent, KeyboardInput, ElementState::{Pressed, Released}, VirtualKeyCode::{self, *}};
|
||||
use glutin::event_loop::ControlFlow;
|
||||
|
||||
const SCREEN_W: u32 = 800;
|
||||
const SCREEN_H: u32 = 600;
|
||||
|
||||
// Helper functions to make interacting with OpenGL a little bit prettier. You will need these!
|
||||
// == // Helper functions to make interacting with OpenGL a little bit prettier. You *WILL* need these! // == //
|
||||
// The names should be pretty self explanatory
|
||||
fn byte_size_of_array<T>(val: &[T]) -> isize {
|
||||
std::mem::size_of_val(&val[..]) as isize
|
||||
@@ -39,6 +33,11 @@ fn offset<T>(n: u32) -> *const c_void {
|
||||
(n * mem::size_of::<T>() as u32) as *const T as *const c_void
|
||||
}
|
||||
|
||||
// Get a null pointer (equivalent to an offset of 0)
|
||||
// ptr::null()
|
||||
|
||||
|
||||
|
||||
// == // Modify and complete the function below for the first task
|
||||
// unsafe fn FUNCTION_NAME(ARGUMENT_NAME: &Vec<f32>, ARGUMENT_NAME: &Vec<u32>) -> u32 { }
|
||||
|
||||
@@ -52,15 +51,23 @@ fn main() {
|
||||
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");
|
||||
// windowed_context.window().set_cursor_visible(false);
|
||||
|
||||
// Set up a shared vector for keeping track of currently pressed keys
|
||||
let arc_pressed_keys = Arc::new(Mutex::new(Vec::<VirtualKeyCode>::with_capacity(10)));
|
||||
// Send a copy of this vector to send to the render thread
|
||||
// Make a reference of this vector to send to the render thread
|
||||
let pressed_keys = Arc::clone(&arc_pressed_keys);
|
||||
|
||||
// Set up shared tuple for tracking mouse movement between frames
|
||||
let arc_mouse_delta = Arc::new(Mutex::new((0f32, 0f32)));
|
||||
// Make a reference of this tuple to send to the render thread
|
||||
let mouse_delta = Arc::clone(&arc_mouse_delta);
|
||||
|
||||
// Spawn a separate thread for rendering, so event handling doesn't block rendering
|
||||
let render_thread = thread::spawn(move || {
|
||||
// Acquire the OpenGL Context and load the function pointers. This has to be done inside of the renderin thread, because
|
||||
// Acquire the OpenGL Context and load the function pointers. This has to be done inside of the rendering thread, because
|
||||
// an active OpenGL context cannot safely traverse a thread boundary
|
||||
let context = unsafe {
|
||||
let c = windowed_context.make_current().unwrap();
|
||||
@@ -76,6 +83,11 @@ fn main() {
|
||||
gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
|
||||
gl::Enable(gl::DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
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!("OpenGL\t: {}", util::get_gl_string(gl::VERSION));
|
||||
println!("GLSL\t: {}", util::get_gl_string(gl::SHADING_LANGUAGE_VERSION));
|
||||
}
|
||||
|
||||
// == // Set up your VAO here
|
||||
@@ -85,8 +97,11 @@ fn main() {
|
||||
|
||||
// Basic usage of shader helper
|
||||
// The code below returns a shader object, which contains the field .program_id
|
||||
// The snippet is not enough to do the assignment, and will need to be modified (outside of just using the correct path)
|
||||
// shader::Shaderbuilder::new().attach_file("./path/to/shader").link();
|
||||
// The snippet is not enough to do the assignment, and will need to be modified (outside of just using the correct path), but it only needs to be called once
|
||||
// shader::ShaderBuilder::new().attach_file("./path/to/shader").link();
|
||||
unsafe {
|
||||
|
||||
}
|
||||
|
||||
// Used to demonstrate keyboard handling -- feel free to remove
|
||||
let mut _arbitrary_number = 0.0;
|
||||
@@ -116,6 +131,13 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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() {
|
||||
|
||||
|
||||
|
||||
*delta = (0.0, 0.0);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gl::ClearColor(0.163, 0.163, 0.163, 1.0);
|
||||
@@ -189,6 +211,12 @@ fn main() {
|
||||
_ => { }
|
||||
}
|
||||
},
|
||||
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);
|
||||
}
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -24,6 +24,17 @@ pub enum ShaderType {
|
||||
Geometry,
|
||||
}
|
||||
|
||||
impl Shader {
|
||||
// Make sure the shader is active before calling this
|
||||
pub unsafe fn get_uniform_location(&self, name: &str) -> i32 {
|
||||
gl::GetUniformLocation(self.program_id, CString::new(name).expect("CString::new failed").as_ptr())
|
||||
}
|
||||
|
||||
pub unsafe fn activate(&self) {
|
||||
gl::UseProgram(self.program_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<gl::types::GLenum> for ShaderType {
|
||||
fn into(self) -> gl::types::GLenum {
|
||||
match self {
|
||||
@@ -121,6 +132,7 @@ impl ShaderBuilder {
|
||||
true
|
||||
}
|
||||
|
||||
#[must_use = "The shader program is useless if not stored in a variable."]
|
||||
pub unsafe fn link(self) -> Shader {
|
||||
for &shader in &self.shaders {
|
||||
gl::AttachShader(self.program_id, shader);
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use std::ffi::CString;
|
||||
|
||||
pub unsafe fn get_gl_string(name: gl::types::GLenum) -> String {
|
||||
std::ffi::CStr::from_ptr(gl::GetString(name) as *mut i8).to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
// Debug callback to panic upon enountering any OpenGL error
|
||||
pub extern "system" fn debug_callback(
|
||||
source: u32, e_type: u32, id: u32,
|
||||
|
||||
Reference in New Issue
Block a user