Bit of a snag that Rust doesn't use nul-terminated strings. This is
necessary for Rust's slices to be internally consistent, but it means a slight FFI hitch when working with C. I have to say I take Rust's side - Strings without a size have been considered a security smell for a while now.main
parent
dfecbdd4fb
commit
bfeb111b14
79
src/main.rs
79
src/main.rs
|
@ -2,6 +2,7 @@ use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
use std::ffi::{CStr, CString};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const VERT_SHADER_SRC: &str =
|
const VERT_SHADER_SRC: &str =
|
||||||
|
@ -111,6 +112,68 @@ impl Drop for ShaderObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ShaderProgram {
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShaderProgram {
|
||||||
|
pub fn new (vert: &ShaderObject, frag: &ShaderObject)
|
||||||
|
-> Result <ShaderProgram, String>
|
||||||
|
{
|
||||||
|
let id = unsafe {
|
||||||
|
gl::CreateProgram ()
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::AttachShader (id, vert.id ());
|
||||||
|
gl::AttachShader (id, frag.id ());
|
||||||
|
|
||||||
|
gl::LinkProgram (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
let mut success = 0;
|
||||||
|
gl::GetProgramiv (id, gl::LINK_STATUS, &mut success);
|
||||||
|
success == 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if success {
|
||||||
|
Ok (ShaderProgram {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let mut info_log = vec! [0u8; 4096];
|
||||||
|
let mut log_length = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::GetProgramInfoLog (id, (info_log.len () - 1).try_into ().unwrap (), &mut log_length, info_log.as_mut_ptr () as *mut i8);
|
||||||
|
}
|
||||||
|
|
||||||
|
info_log.truncate (log_length.try_into ().unwrap ());
|
||||||
|
|
||||||
|
let info = String::from_utf8 (info_log).unwrap ();
|
||||||
|
|
||||||
|
Err (info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_uniform_location (&self, name: &CStr) -> i32 {
|
||||||
|
unsafe {
|
||||||
|
gl::UseProgram (self.id);
|
||||||
|
gl::GetUniformLocation (self.id, name.as_ptr ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for ShaderProgram {
|
||||||
|
fn drop (&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteProgram (self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main () {
|
fn main () {
|
||||||
let sdl_context = sdl2::init ().unwrap ();
|
let sdl_context = sdl2::init ().unwrap ();
|
||||||
let video_subsystem = sdl_context.video ().unwrap ();
|
let video_subsystem = sdl_context.video ().unwrap ();
|
||||||
|
@ -134,9 +197,25 @@ fn main () {
|
||||||
|
|
||||||
window.gl_make_current (&gl_ctx).unwrap ();
|
window.gl_make_current (&gl_ctx).unwrap ();
|
||||||
|
|
||||||
|
// I love how with Rust I can throw unwrap ()s everywhere
|
||||||
|
// It's safer than C / C++'s default behavior of unchecked errors
|
||||||
|
// It's more programmer-friendly and explicit than C#'s unchecked
|
||||||
|
// exceptions that can appear almost anywhere at runtime with no
|
||||||
|
// compile-time warning
|
||||||
|
// And I'm still not actually checking errors - Just checkmarking
|
||||||
|
// that I know where they are.
|
||||||
|
|
||||||
let vert_shader = ShaderObject::new (gl::VERTEX_SHADER, VERT_SHADER_SRC).unwrap ();
|
let vert_shader = ShaderObject::new (gl::VERTEX_SHADER, VERT_SHADER_SRC).unwrap ();
|
||||||
let frag_shader = ShaderObject::new (gl::FRAGMENT_SHADER, FRAG_SHADER_SRC).unwrap ();
|
let frag_shader = ShaderObject::new (gl::FRAGMENT_SHADER, FRAG_SHADER_SRC).unwrap ();
|
||||||
|
|
||||||
|
let shader_program = ShaderProgram::new (&vert_shader, &frag_shader).unwrap ();
|
||||||
|
|
||||||
|
let uni_model = shader_program.get_uniform_location (&CString::new ("uni_model").unwrap ());
|
||||||
|
let uni_viewproj = shader_program.get_uniform_location (CStr::from_bytes_with_nul (b"uni_viewproj\0").unwrap ());
|
||||||
|
|
||||||
|
println! ("uni_model: {}", uni_model);
|
||||||
|
println! ("uni_viewproj: {}", uni_viewproj);
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump ().unwrap ();
|
let mut event_pump = sdl_context.event_pump ().unwrap ();
|
||||||
'running: loop {
|
'running: loop {
|
||||||
let _mouse = event_pump.mouse_state ();
|
let _mouse = event_pump.mouse_state ();
|
||||||
|
|
Loading…
Reference in New Issue