diff --git a/Cargo.toml b/Cargo.toml index 19ddc96..9742bb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" [dependencies] field-offset = "0.3.4" image = "0.24.5" -gl = "0.14.0" cgmath = "0.18.0" tobj = "2.0.0" +glow = "0.12.1" [dependencies.glfw] version = "*" diff --git a/src/main.rs b/src/main.rs index 5e1e603..1f3ab4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,12 @@ use glfw; use glfw::{Action, Context, Key}; use cgmath::{Matrix4, vec3, Point3, Deg, perspective}; use cgmath::prelude::*; +use std::rc::Rc; const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const TITLE: &str = "GLFWtest"; +use glow::*; use std::sync::mpsc::Receiver; use std::ptr; @@ -25,8 +27,8 @@ fn main() { glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); glfw.window_hint(glfw::WindowHint::Resizable(false)); - glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(true)); - glfw.window_hint(glfw::WindowHint::Decorated(false)); + glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(false)); + glfw.window_hint(glfw::WindowHint::Decorated(true)); let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap(); @@ -54,14 +56,14 @@ fn main() { let mut deltaTime: f32; // time between current frame and last frame let mut lastFrame: f32 = 0.0; - gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - + //gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); + let gl = std::rc::Rc::new(unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)}); let (ourshader, ourModel) = unsafe { - gl::Enable(gl::DEPTH_TEST); + gl.enable(glow::DEPTH_TEST); - let ourShader = shader::shader::new("model"); + let ourShader = shader::shader::new("model", Rc::clone(&gl)); - let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj"); + let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj", Rc::clone(&gl)); (ourShader, ourModel) }; @@ -71,7 +73,6 @@ fn main() { let projection: Matrix4 = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0); println!("entering main loop"); - unsafe {gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE);} while !window.should_close() { let currentFrame = glfw.get_time() as f32; deltaTime = currentFrame - lastFrame; @@ -80,24 +81,23 @@ fn main() { processInput(&mut window, deltaTime, &mut camera); unsafe { - gl::Enable(gl::DEPTH_TEST); - gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); - gl::ClearColor(0.0, 0.0, 0.0, 0.0); + gl.enable(glow::DEPTH_TEST); + gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); // outline ourshader.Use(); let Projection: Matrix4 = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0); let view = camera.GetViewMatrix(); - ourshader.setMat4(&CString::new("projection").unwrap(), &projection); - ourshader.setMat4(&CString::new("view").unwrap(), &view); + ourshader.setMat4("projection", &projection); + ourshader.setMat4("view", &view); //let mut model = Matrix4::::from_translation(vec3(0.0, -0.3, 0.0)); let mut model: Matrix4 = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(), cgmath::Rad(glfw.get_time() as f32)); model = model * Matrix4::from_scale(0.2); - ourshader.setMat4(&CString::new("model").unwrap(), &model); + ourshader.setMat4("model", &model); ourModel.Draw(&ourshader); @@ -131,7 +131,7 @@ fn main() { } */ } - +/* fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>, firstMouse: &mut bool, lastX: &mut f32, @@ -142,7 +142,7 @@ fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>, glfw::WindowEvent::FramebufferSize(width, height) => { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. - unsafe { gl::Viewport(0, 0, width, height) } + unsafe { gl.viewport(0, 0, width, height) } } glfw::WindowEvent::CursorPos(xpos, ypos) => { let (xpos, ypos) = (xpos as f32, ypos as f32); @@ -167,3 +167,4 @@ fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>, } } } +*/ diff --git a/src/model.rs b/src/model.rs index 321b695..d513a4b 100644 --- a/src/model.rs +++ b/src/model.rs @@ -3,10 +3,10 @@ use std::os::raw::c_void; use std::path::Path; - +use std::rc::Rc; use cgmath::{vec2, vec3}; -use gl; use image; +use glow::*; use image::DynamicImage::*; use image::GenericImage; use tobj; @@ -24,20 +24,21 @@ pub struct Model { impl Model { /// constructor, expects a filepath to a 3D model. - pub fn new(path: &str) -> Model { + pub fn new(path: &str, gl: std::rc::Rc) -> Model { let mut model = Model::default(); - model.loadModel(path); + model.loadModel(path, Rc::clone(&gl)); model } pub fn Draw(&self, shader: &shader) { for mesh in &self.meshes { + unsafe { mesh.Draw(shader); } } } // loads a model from file and stores the resulting meshes in the meshes vector. - fn loadModel(&mut self, path: &str) { + fn loadModel(&mut self, path: &str, gl: std::rc::Rc) { let path = Path::new(path); // retrieve the directory path of the filepath @@ -53,9 +54,6 @@ impl Model { let mut vertices: Vec = Vec::with_capacity(num_vertices); let indices: Vec = mesh.indices.clone(); - println!("num vertices = {}", num_vertices); - println!("num normals = {}", &mesh.normals.len()); - println!("num TexCoords = {}", &mesh.texcoords.len()); let (p, n, t) = (&mesh.positions, &mesh.normals, &mesh.texcoords); for i in 0..num_vertices { vertices.push(Vertex { @@ -73,28 +71,28 @@ impl Model { // 1. diffuse map if !material.diffuse_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse"); + let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse", Rc::clone(&gl)); textures.push(texture); } // 2. specular map if !material.specular_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular"); + let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular", Rc::clone(&gl)); textures.push(texture); } // 3. normal map if !material.normal_texture.is_empty() { - let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal"); + let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal", Rc::clone(&gl)); textures.push(texture); } // NOTE: no height maps } - self.meshes.push(Mesh::new(vertices, indices, textures)); + self.meshes.push(Mesh::new(vertices, indices, textures, Rc::clone(&gl))); } } - fn loadMaterialTexture(&mut self, path: &str, typeName: &str) -> Texture { + fn loadMaterialTexture(&mut self, path: &str, typeName: &str, gl: Rc) -> Texture { { let texture = self.textures_loaded.iter().find(|t| t.path == path); if let Some(texture) = texture { @@ -103,7 +101,7 @@ impl Model { } let texture = Texture { - id: unsafe { TextureFromFile(path, &self.directory) }, + id: unsafe { TextureFromFile(path, &self.directory, std::rc::Rc::clone(&gl)) }, type_: typeName.into(), path: path.into() }; @@ -112,33 +110,31 @@ impl Model { } } -unsafe fn TextureFromFile(path: &str, directory: &str) -> u32 { +unsafe fn TextureFromFile(path: &str, directory: &str, gl: Rc) -> glow::NativeTexture { let filename = format!("{}/{}", directory, path); - let mut textureID = 0; - gl::GenTextures(1, &mut textureID); - + let mut textureID = gl.create_texture().unwrap(); let img = image::open(&Path::new(&filename)).expect("Texture failed to load"); let img = img.flipv(); let format = match img { - ImageLuma8(_) => gl::RED, - ImageLumaA8(_) => gl::RG, - ImageRgb8(_) => gl::RGB, - ImageRgba8(_) => gl::RGBA, + ImageLuma8(_) => glow::RED, + ImageLumaA8(_) => glow::RG, + ImageRgb8(_) => glow::RGB, + ImageRgba8(_) => glow::RGBA, _ => panic!("really weird image type"), }; let data = img.as_bytes(); - gl::BindTexture(gl::TEXTURE_2D, textureID); - gl::TexImage2D(gl::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32, - 0, format, gl::UNSIGNED_BYTE, &data[0] as *const u8 as *const c_void); - gl::GenerateMipmap(gl::TEXTURE_2D); + gl.bind_texture(glow::TEXTURE_2D, Some(textureID)); + gl.tex_image_2d(glow::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32, + 0, format, glow::UNSIGNED_BYTE, Some(&data)); + gl.generate_mipmap(glow::TEXTURE_2D); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32); + gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32); + gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32); + gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR_MIPMAP_LINEAR as i32); + gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); textureID } diff --git a/src/model/mesh.rs b/src/model/mesh.rs index a94421c..92bda72 100644 --- a/src/model/mesh.rs +++ b/src/model/mesh.rs @@ -8,7 +8,7 @@ use std::ptr; use cgmath::{ Vector3, Vector2 }; use cgmath::prelude::*; -use gl; +use glow::*; use field_offset::offset_of; use crate::shader::shader; @@ -43,7 +43,7 @@ impl Default for Vertex { #[derive(Clone)] pub struct Texture { - pub id: u32, + pub id: glow::NativeTexture, pub type_: String, pub path: String, } @@ -53,22 +53,27 @@ pub struct Mesh { pub vertices: Vec, pub indices: Vec, pub textures: Vec, - pub VAO: u32, + pub VAO: Option, /* Render data */ - VBO: u32, - EBO: u32, + VBO: Option, + EBO: Option, } impl Mesh { - pub fn new(vertices: Vec, indices: Vec, textures: Vec) -> Mesh { - let mut mesh = Mesh { - vertices, indices, textures, - VAO: 0, VBO: 0, EBO: 0 - }; + pub fn new(vertices: Vec, indices: Vec, textures: Vec,gl: std::rc::Rc) -> Mesh { + let mut mesh = + { + unsafe { + Mesh { + vertices, indices, textures, + VAO: None, VBO: None, EBO: None + } + } + }; // now that we have all the required data, set the vertex buffers and its attribute pointers. - unsafe { mesh.setupMesh() } + unsafe { mesh.setupMesh(gl) } mesh } @@ -80,7 +85,7 @@ impl Mesh { let mut normalNr = 0; let mut heightNr = 0; for (i, texture) in self.textures.iter().enumerate() { - gl::ActiveTexture(gl::TEXTURE0 + i as u32); // active proper texture unit before binding + shader.gl.active_texture(glow::TEXTURE0 + i as u32); // active proper texture unit before binding // retrieve texture number (the N in diffuse_textureN) let name = &texture.type_; let number = match name.as_str() { @@ -103,60 +108,66 @@ impl Mesh { _ => panic!("unknown texture type") }; // now set the sampler to the correct texture unit - let sampler = CString::new(format!("{}{}", name, number)).unwrap(); - gl::Uniform1i(gl::GetUniformLocation(shader.ID, sampler.as_ptr()), i as i32); + let sampler = format!("{}{}", name, number); + shader.setInt(&sampler, i as i32); + //shader.gl.uniform_1_i32(shader.gl.get_uniform_location(shader.ID, &sampler).as_ref(), i as i32); // and finally bind the texture - gl::BindTexture(gl::TEXTURE_2D, texture.id); + shader.gl.bind_texture(glow::TEXTURE_2D, Some(texture.id)); + } // draw mesh - gl::BindVertexArray(self.VAO); - gl::DrawElements(gl::TRIANGLES, self.indices.len() as i32, gl::UNSIGNED_INT, ptr::null()); - gl::BindVertexArray(0); - + shader.gl.bind_vertex_array(self.VAO); + shader.gl.draw_elements(glow::TRIANGLES, self.indices.len() as i32, glow::UNSIGNED_INT, 0); + shader.gl.bind_vertex_array(None); // always good practice to set everything back to defaults once configured. - gl::ActiveTexture(gl::TEXTURE0); + shader.gl.active_texture(glow::TEXTURE0); } - unsafe fn setupMesh(&mut self) { + unsafe fn setupMesh(&mut self, gl: std::rc::Rc) { + + self.VAO = Some(gl.create_vertex_array().unwrap()); + self.VBO = Some(gl.create_buffer().unwrap()); + self.EBO = Some(gl.create_buffer().unwrap()); + + gl.bind_vertex_array(self.VAO); // create buffers/arrays - gl::GenVertexArrays(1, &mut self.VAO); - gl::GenBuffers(1, &mut self.VBO); - gl::GenBuffers(1, &mut self.EBO); + gl.bind_buffer(glow::ARRAY_BUFFER, self.VBO); - gl::BindVertexArray(self.VAO); - // load data into vertex buffers - gl::BindBuffer(gl::ARRAY_BUFFER, self.VBO); - // A great thing about structs with repr(C) is that their memory layout is sequential for all its items. - // The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which - // again translates to 3/2 floats which translates to a byte array. - let size = (self.vertices.len() * size_of::()) as isize; - let data = &self.vertices[0] as *const Vertex as *const c_void; - gl::BufferData(gl::ARRAY_BUFFER, size, data, gl::STATIC_DRAW); + println!("vertices.len is: {}", self.vertices.len()); + let data = core::slice::from_raw_parts( + self.vertices.as_ptr() as *const u8, + self.vertices.len() * core::mem::size_of::(), + ); - gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.EBO); - let size = (self.indices.len() * size_of::()) as isize; - let data = &self.indices[0] as *const u32 as *const c_void; - gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, size, data, gl::STATIC_DRAW); + gl.named_buffer_data_u8_slice(self.VBO.unwrap(), data, glow::STATIC_DRAW); + + + gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, self.EBO); + let data = core::slice::from_raw_parts( + self.indices.as_ptr() as *const u8, + self.indices.len() * core::mem::size_of::(), + ); + gl.named_buffer_data_u8_slice(self.EBO.unwrap(), data, glow::STATIC_DRAW); // set the vertex attribute pointers let size = size_of::() as i32; // vertex Positions - gl::EnableVertexAttribArray(0); - gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Position).get_byte_offset() as *const c_void); + gl.enable_vertex_attrib_array(0); + gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size, 0); // vertex normals - gl::EnableVertexAttribArray(1); - gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Normal).get_byte_offset() as *const c_void); + gl.enable_vertex_attrib_array(1); + gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, size, 3*4); // vertex texture coords - gl::EnableVertexAttribArray(2); - gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => TexCoords).get_byte_offset() as *const c_void); + gl.enable_vertex_attrib_array(2); + gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, size, 6*4); // vertex tangent - gl::EnableVertexAttribArray(3); - gl::VertexAttribPointer(3, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Tangent).get_byte_offset() as *const c_void); + gl.enable_vertex_attrib_array(3); + gl.vertex_attrib_pointer_f32(3, 3, glow::FLOAT, false, size, 8*4); // vertex bitangent - gl::EnableVertexAttribArray(4); - gl::VertexAttribPointer(4, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Bitangent).get_byte_offset() as *const c_void); + gl.enable_vertex_attrib_array(4); + gl.vertex_attrib_pointer_f32(4, 3, glow::FLOAT, false, size, 11*4); - gl::BindVertexArray(0); + gl.bind_vertex_array(None); } } diff --git a/src/shader.rs b/src/shader.rs index 8669e62..9f066bc 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,14 +1,14 @@ -use gl; +use glow::*; use std::fs; -use std::ffi::{CString, CStr}; +use std::rc::Rc; use std::str; -use cgmath::prelude::*; /// Shader Struct for creating and using shaders in the Context of engine /// pub struct shader { - pub ID: gl::types::GLuint, + pub ID: NativeProgram, + pub gl: Rc } @@ -21,122 +21,113 @@ use cgmath::prelude::*; /// `new(String::from("Example"))` /// if the String given was "Example" the Program expects both shaders to be in the directory "resources/shaders/Example/" /// with the vertex shader being called "shader.vert" and fragment "shader.frag" - pub fn new(path: &str) -> shader + pub fn new(path: &str, gl: Rc) -> shader { //read file contents let VERT_SHADER = fs::read_to_string(format!("resources/shaders/{path}/shader.vert")).unwrap(); - let FRAG_SHADER = std::fs::read_to_string(format!("resources/shaders/{path}/shader.frag")).unwrap(); + let FRAG_SHADER = fs::read_to_string(format!("resources/shaders/{path}/shader.frag")).unwrap(); //create vertex shader - let vertex_shader = unsafe {gl::CreateShader(gl::VERTEX_SHADER) }; + let vertex_shader = unsafe {gl.create_shader(glow::VERTEX_SHADER).unwrap() }; unsafe { - gl::ShaderSource(vertex_shader, 1, &VERT_SHADER.as_bytes().as_ptr().cast(), &VERT_SHADER.len().try_into().unwrap()); - gl::CompileShader(vertex_shader); - } - //error Checking - let mut success = 0; - unsafe { - gl::GetShaderiv(vertex_shader, gl::COMPILE_STATUS, &mut success); - if success == 0 { - let mut log_len = 0_i32; + gl.shader_source(vertex_shader, &VERT_SHADER); + gl.compile_shader(vertex_shader); - let mut v: Vec = Vec::with_capacity(1024); - gl::GetShaderInfoLog(vertex_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); - v.set_len(log_len.try_into().unwrap()); - panic!("Vertex Shader Compile Error: {}", String::from_utf8_lossy(&v)); + } + // create fragment shader + let fragment_shader = unsafe{gl.create_shader(glow::FRAGMENT_SHADER).unwrap()}; + unsafe { + gl.shader_source(fragment_shader, &FRAG_SHADER); + gl.compile_shader(fragment_shader); + if !gl.get_shader_compile_status(fragment_shader) { + panic!("Error, Compiling Fragment Shader: {}", gl.get_shader_info_log(fragment_shader)); } - let fragment_shader = gl::CreateShader(gl::FRAGMENT_SHADER); - gl::ShaderSource(fragment_shader, 1, &FRAG_SHADER.as_bytes().as_ptr().cast(), &FRAG_SHADER.len().try_into().unwrap()); - gl::CompileShader(fragment_shader); + let shader_program = gl.create_program().unwrap(); - let mut success = 0; - gl::GetShaderiv(fragment_shader, gl::COMPILE_STATUS, &mut success); - if success == 0 { - let mut v: Vec = Vec::with_capacity(1024); - let mut log_len = 0_i32; - gl::GetShaderInfoLog(fragment_shader, 1024, &mut log_len, v.as_mut_ptr().cast()); - v.set_len(log_len.try_into().unwrap()); - panic!("Fragment Shader Compile Error: {}", String::from_utf8_lossy(&v)); + gl.attach_shader(shader_program, vertex_shader); + gl.attach_shader(shader_program, fragment_shader); + gl.link_program(shader_program); + if !gl.get_program_link_status(shader_program) { + panic!("Error, Linking Shader Program {}", gl.get_program_info_log(shader_program)); } + gl.detach_shader(shader_program, vertex_shader); + gl.detach_shader(shader_program, fragment_shader); + gl.delete_shader(vertex_shader); + gl.delete_shader(fragment_shader); - let shader_program = gl::CreateProgram(); - - gl::AttachShader(shader_program, vertex_shader); - gl::AttachShader(shader_program, fragment_shader); - gl::LinkProgram(shader_program); - - let mut success = 0; - gl::GetProgramiv(shader_program, gl::LINK_STATUS, &mut success); - if success == 0 { - let mut v: Vec = Vec::with_capacity(1024); - let mut log_len = 0_i32; - gl::GetProgramInfoLog(shader_program, 1024, &mut log_len, v.as_mut_ptr().cast()); - v.set_len(log_len.try_into().unwrap()); - panic!("Program Link Error: {}", String::from_utf8_lossy(&v)); - } - - gl::DetachShader(shader_program, vertex_shader); - gl::DetachShader(shader_program, fragment_shader); - gl::DeleteShader(vertex_shader); - gl::DeleteShader(fragment_shader); - - - - // return program shader { - ID: shader_program, - } + ID: shader_program, + gl: Rc::clone(&gl), } + } } + + + + // return program + /// uses Shader pub fn Use(&self) { - unsafe {gl::UseProgram(self.ID);} + unsafe {self.gl.use_program(Some(self.ID));} } // BOILERPLATE JUMPSCARE - pub fn setBool(&self, name: &CStr, value: bool ) - {unsafe {gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr()), value as i32);}} + /* + pub fn setBool(&self, name: &str, value: bool ) + {unsafe {self.gl.uniform_1_bool(self.gl.get_uniform_location(self.ID, name).as_ref(), value);}} + */ + pub fn setInt(&self, name: &str, value: i32 ) + {unsafe {self.gl.uniform_1_i32(self.gl.get_uniform_location(self.ID, name).as_ref(), value);}} - pub fn setInt(&self, name: &CStr, value: u32 ) - {unsafe {gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr()), value as i32);}} + pub fn setFloat(&self, name: &str, value: f32 ) + {unsafe {self.gl.uniform_1_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), value);}} - pub fn setFloat(&self, name: &CStr, value: f32 ) - {unsafe {gl::Uniform1f(gl::GetUniformLocation(self.ID, name.as_ptr()), value as f32);}} + pub fn setVector2(&self, name: &str, value: cgmath::Vector2 ) + {unsafe {self.gl.uniform_2_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1]);}} - pub fn setVec2(&self, name: &CStr, value: &cgmath::Vector2 ) - {unsafe {gl::Uniform2fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, value.as_ptr());}} + pub fn setVector2d(&self, name: &str, x: f32, y: f32) + {unsafe {self.gl.uniform_2_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), x, y);}} - pub fn setVector2d(&self, name: &CStr, x: f32, y: f32) - {unsafe {gl::Uniform2f(gl::GetUniformLocation(self.ID, name.as_ptr()), x, y);}} + pub fn setVector3(&self, name: &str, value: cgmath::Vector3 ) + {unsafe {self.gl.uniform_3_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1], value[2]);}} - pub fn setVector3(&self, name: &CStr, value: cgmath::Vector3 ) - {unsafe {gl::Uniform3fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, value.as_ptr());}} + pub fn setVector3d(&self, name: &str, x: f32, y: f32, z: f32 ) + {unsafe {self.gl.uniform_3_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), x, y, z);}} - pub fn setVector3d(&self, name: &CStr, x: f32, y: f32, z: f32 ) - {unsafe {gl::Uniform3f(gl::GetUniformLocation(self.ID, name.as_ptr()), x, y, z);}} + pub fn setVector4(&self, name: &str, value: &cgmath::Vector4 ) + {unsafe {self.gl.uniform_4_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), value[0], value[1], value[2], value[3]);}} - pub fn setVector4(&self, name: &CStr, value: &cgmath::Vector4 ) - {unsafe {gl::Uniform4fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, value.as_ptr());}} + pub fn setVector4d(&self, name: &str, x: f32, y: f32, z: f32, w: f32) + {unsafe {self.gl.uniform_4_f32(self.gl.get_uniform_location(self.ID, name).as_ref(), x, y, z, w);}} - pub fn setVector4d(&self, name: &CStr, x: f32, y: f32, z: f32, w: f32) - {unsafe {gl::Uniform4f(gl::GetUniformLocation(self.ID, name.as_ptr()), x, y, z, w);}} + //pub fn setMat2(&self, name: &str, value: cgmath::Matrix2) - pub fn setMat2(&self, name: &CStr, value: &cgmath::Matrix2) - {unsafe {gl::UniformMatrix2fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, gl::FALSE, value.as_ptr());}} - - pub fn setMat3(&self, name: &CStr, value: &cgmath::Matrix3) - {unsafe {gl::UniformMatrix3fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, gl::FALSE, value.as_ptr());}} - - pub fn setMat4(&self, name: &CStr, value: &cgmath::Matrix4) - {unsafe {gl::UniformMatrix4fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, gl::FALSE, value.as_ptr());}} + pub fn setMat3(&self, name: &str, value: cgmath::Matrix3) + { + let nums = vec![value.x.x, value.x.y, value.x.z, + value.y.x, value.y.y, value.y.z, + value.z.x, value.z.y, value.z.z]; + unsafe + { + self.gl.uniform_matrix_3_f32_slice(self.gl.get_uniform_location(self.ID, name).as_ref(), false, nums.as_ref()); + } + } + pub fn setMat4(&self, name: &str, value: &cgmath::Matrix4) + { + let nums = vec![value.x.x, value.x.y, value.x.z, value.x.w, + value.y.x, value.y.y, value.y.z, value.y.w, + value.z.x, value.z.y, value.z.z, value.z.w, + value.w.x, value.w.y, value.w.z, value.w.w]; + unsafe + { + self.gl.uniform_matrix_4_f32_slice(self.gl.get_uniform_location(self.ID, name).as_ref(), false, nums.as_ref()); + } + } } - - - #[cfg(test)] mod tests { use glfw;