From 93217e1a6668e03a72e74a833503a478688ea9a3 Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Sun, 5 Mar 2023 00:49:10 +0100 Subject: [PATCH 1/5] new commit for Porting to Glow --- Cargo.toml | 1 + src/main.rs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 19ddc96..d84d453 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,6 @@ 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..8c5f8f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const TITLE: &str = "GLFWtest"; +use glow; use std::sync::mpsc::Receiver; use std::ptr; @@ -54,7 +55,9 @@ 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 = unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _);}; + let (ourshader, ourModel) = unsafe { gl::Enable(gl::DEPTH_TEST); @@ -81,8 +84,7 @@ fn main() { 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::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); // outline From adc2c93af20d38a0fc3afba66203d0e1a2814829 Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Mon, 6 Mar 2023 10:13:01 +0100 Subject: [PATCH 2/5] unifinished port to glow for shader.rs --- src/main.rs | 11 ++++-- src/shader.rs | 99 +++++++++++++++++++-------------------------------- 2 files changed, 44 insertions(+), 66 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8c5f8f6..df624d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ const SCR_WIDTH: u32 = 1600; const SCR_HEIGHT: u32 = 900; const TITLE: &str = "GLFWtest"; -use glow; +use glow::*; use std::sync::mpsc::Receiver; use std::ptr; @@ -56,13 +56,18 @@ fn main() { let mut lastFrame: f32 = 0.0; //gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - let gl = unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _);}; + let gl = { + unsafe{ + let glue = glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); + glue + } + }; let (ourshader, ourModel) = unsafe { gl::Enable(gl::DEPTH_TEST); - let ourShader = shader::shader::new("model"); + let ourShader = shader::shader::new("model", gl); let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj"); diff --git a/src/shader.rs b/src/shader.rs index 8669e62..ace22d1 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,19 +1,19 @@ -use gl; +use glow::*; use std::fs; use std::ffi::{CString, CStr}; use std::str; use cgmath::prelude::*; /// Shader Struct for creating and using shaders in the Context of engine /// - pub struct shader { + pub struct shader { - pub ID: gl::types::GLuint, + pub ID: T::Program, } - impl shader + impl shader { /// Shader Constructor, will read, Compile and Create GLSL Program for use /// @@ -21,74 +21,51 @@ 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: glow::Context) -> 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, + }; + } } + + + + // return program + /// uses Shader pub fn Use(&self) { @@ -132,11 +109,7 @@ use cgmath::prelude::*; 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());}} - - } - - - + } #[cfg(test)] mod tests { use glfw; From 0df79f7509ccd2f8d7ee0d848e7a3dd84a562825 Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Wed, 8 Mar 2023 10:19:23 +0100 Subject: [PATCH 3/5] finished Porting shader Code --- src/main.rs | 9 +----- src/shader.rs | 84 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/main.rs b/src/main.rs index df624d5..492e3ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,14 +56,7 @@ fn main() { let mut lastFrame: f32 = 0.0; //gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - let gl = { - - unsafe{ - let glue = glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); - glue - } - }; - + let gl = std::rc::Rc::new(glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)); let (ourshader, ourModel) = unsafe { gl::Enable(gl::DEPTH_TEST); diff --git a/src/shader.rs b/src/shader.rs index ace22d1..b5e9b40 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -2,18 +2,20 @@ 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 struct shader { - pub ID: T::Program, + pub ID: NativeProgram, + gl: Rc } - impl shader + impl shader { /// Shader Constructor, will read, Compile and Create GLSL Program for use /// @@ -21,7 +23,7 @@ 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, gl: glow::Context) -> 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(); @@ -58,6 +60,7 @@ use cgmath::prelude::*; shader { ID: shader_program, + gl: Rc::clone(&gl), }; } } @@ -67,49 +70,66 @@ use cgmath::prelude::*; // return program /// uses Shader - pub fn Use(&self) + pub fn Use(&self, gl: glow::Context) { - unsafe {gl::UseProgram(self.ID);} + unsafe {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: &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 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: &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()); + } + } - 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());}} - - } + } #[cfg(test)] mod tests { use glfw; From 219fc7f57fcf0bfe69cd9280fa68de5d1947a7dd Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Wed, 8 Mar 2023 15:09:25 +0100 Subject: [PATCH 4/5] Runs, however buggy --- Cargo.toml | 1 - src/main.rs | 25 ++++++------ src/model.rs | 55 ++++++++++++--------------- src/model/mesh.rs | 96 ++++++++++++++++++++++++++--------------------- src/shader.rs | 10 ++--- 5 files changed, 96 insertions(+), 91 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d84d453..9742bb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ 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" diff --git a/src/main.rs b/src/main.rs index 492e3ea..5e3d8e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ 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"; @@ -56,13 +57,13 @@ fn main() { let mut lastFrame: f32 = 0.0; //gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); - let gl = std::rc::Rc::new(glow::Context::from_loader_function(|s| window.get_proc_address(s) 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", gl); + 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) }; @@ -72,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; @@ -81,23 +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.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..128eaaa 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,9 +24,9 @@ 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 } @@ -37,7 +37,7 @@ impl Model { } // 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 +53,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 +70,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 +100,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 +109,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..c0bc897 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,28 @@ pub struct Mesh { pub vertices: Vec, pub indices: Vec, pub textures: Vec, - pub VAO: u32, + pub VAO: glow::VertexArray, /* Render data */ - VBO: u32, - EBO: u32, + VBO: glow::Buffer, + EBO: glow::Buffer, } impl Mesh { - pub fn new(vertices: Vec, indices: Vec, textures: Vec) -> Mesh { + pub fn new(vertices: Vec, indices: Vec, textures: Vec,gl: std::rc::Rc) -> Mesh { + + let mut mesh = + { + unsafe { let mut mesh = Mesh { vertices, indices, textures, - VAO: 0, VBO: 0, EBO: 0 + VAO: gl.create_vertex_array().unwrap(), VBO: gl.create_buffer().unwrap(), EBO: gl.create_buffer().unwrap() }; - + mesh + } + }; // 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 +86,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 +109,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 = String::from(format!("{}{}", name, number)); + shader.setInt(&sampler, 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(Some(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) { // create buffers/arrays - gl::GenVertexArrays(1, &mut self.VAO); - gl::GenBuffers(1, &mut self.VBO); - gl::GenBuffers(1, &mut self.EBO); - - gl::BindVertexArray(self.VAO); + gl.bind_vertex_array(Some(self.VAO)); // load data into vertex buffers - gl::BindBuffer(gl::ARRAY_BUFFER, self.VBO); + gl.bind_buffer(glow::ARRAY_BUFFER, Some(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); + //let size = (self.vertices.len() * size_of::()) as isize; + //let data = &self.vertices[0] as *const Vertex as *const c_void; + let data: &[u8] = 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.buffer_data_u8_slice(glow::ARRAY_BUFFER, data, glow::STATIC_DRAW); + + gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.EBO)); + let data: &[u8] = core::slice::from_raw_parts( + self.indices.as_ptr() as *const u8, + self.indices.len() * core::mem::size_of::(), + ); + gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, 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, offset_of!(Vertex => Position).get_byte_offset() as i32); // 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, offset_of!(Vertex => Normal).get_byte_offset() as i32); // 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, offset_of!(Vertex => TexCoords).get_byte_offset() as i32); // 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, offset_of!(Vertex => Tangent).get_byte_offset() as i32); // 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, offset_of!(Vertex => Bitangent).get_byte_offset() as i32); - gl::BindVertexArray(0); + gl.bind_vertex_array(None); } } diff --git a/src/shader.rs b/src/shader.rs index b5e9b40..9f066bc 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,16 +1,14 @@ 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: NativeProgram, - gl: Rc + pub gl: Rc } @@ -61,7 +59,7 @@ use cgmath::prelude::*; shader { ID: shader_program, gl: Rc::clone(&gl), - }; + } } } @@ -70,9 +68,9 @@ use cgmath::prelude::*; // return program /// uses Shader - pub fn Use(&self, gl: glow::Context) + pub fn Use(&self) { - unsafe {gl.use_program(Some(self.ID));} + unsafe {self.gl.use_program(Some(self.ID));} } // BOILERPLATE JUMPSCARE From aa6ce170ba508640a08455f45b73b1c6f6ca10d4 Mon Sep 17 00:00:00 2001 From: Melik Houij Date: Thu, 9 Mar 2023 13:46:53 +0100 Subject: [PATCH 5/5] we are SO back, found the issue --- src/main.rs | 4 +-- src/model.rs | 1 + src/model/mesh.rs | 63 +++++++++++++++++++++++------------------------ 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5e3d8e1..1f3ab4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,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(); diff --git a/src/model.rs b/src/model.rs index 128eaaa..d513a4b 100644 --- a/src/model.rs +++ b/src/model.rs @@ -32,6 +32,7 @@ impl Model { pub fn Draw(&self, shader: &shader) { for mesh in &self.meshes { + unsafe { mesh.Draw(shader); } } } diff --git a/src/model/mesh.rs b/src/model/mesh.rs index c0bc897..92bda72 100644 --- a/src/model/mesh.rs +++ b/src/model/mesh.rs @@ -53,11 +53,11 @@ pub struct Mesh { pub vertices: Vec, pub indices: Vec, pub textures: Vec, - pub VAO: glow::VertexArray, + pub VAO: Option, /* Render data */ - VBO: glow::Buffer, - EBO: glow::Buffer, + VBO: Option, + EBO: Option, } impl Mesh { @@ -66,11 +66,10 @@ impl Mesh { let mut mesh = { unsafe { - let mut mesh = Mesh { + Mesh { vertices, indices, textures, - VAO: gl.create_vertex_array().unwrap(), VBO: gl.create_buffer().unwrap(), EBO: gl.create_buffer().unwrap() - }; - mesh + VAO: None, VBO: None, EBO: None + } } }; // now that we have all the required data, set the vertex buffers and its attribute pointers. @@ -109,65 +108,65 @@ impl Mesh { _ => panic!("unknown texture type") }; // now set the sampler to the correct texture unit - let sampler = String::from(format!("{}{}", name, number)); + 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 shader.gl.bind_texture(glow::TEXTURE_2D, Some(texture.id)); + } // draw mesh - shader.gl.bind_vertex_array(Some(self.VAO)); + 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. shader.gl.active_texture(glow::TEXTURE0); } 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.bind_vertex_array(Some(self.VAO)); - // load data into vertex buffers - gl.bind_buffer(glow::ARRAY_BUFFER, Some(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; - let data: &[u8] = core::slice::from_raw_parts( + gl.bind_buffer(glow::ARRAY_BUFFER, self.VBO); + + 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::(), + self.vertices.len() * core::mem::size_of::(), ); + gl.named_buffer_data_u8_slice(self.VBO.unwrap(), data, glow::STATIC_DRAW); - - gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, data, glow::STATIC_DRAW); - - gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.EBO)); - let data: &[u8] = core::slice::from_raw_parts( + 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::(), + self.indices.len() * core::mem::size_of::(), ); - gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, data, glow::STATIC_DRAW); + 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.enable_vertex_attrib_array(0); - gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size, offset_of!(Vertex => Position).get_byte_offset() as i32); + gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size, 0); // vertex normals gl.enable_vertex_attrib_array(1); - gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, size, offset_of!(Vertex => Normal).get_byte_offset() as i32); + gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, size, 3*4); // vertex texture coords gl.enable_vertex_attrib_array(2); - gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, size, offset_of!(Vertex => TexCoords).get_byte_offset() as i32); + gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, size, 6*4); // vertex tangent gl.enable_vertex_attrib_array(3); - gl.vertex_attrib_pointer_f32(3, 3, glow::FLOAT, false, size, offset_of!(Vertex => Tangent).get_byte_offset() as i32); + gl.vertex_attrib_pointer_f32(3, 3, glow::FLOAT, false, size, 8*4); // vertex bitangent gl.enable_vertex_attrib_array(4); - gl.vertex_attrib_pointer_f32(4, 3, glow::FLOAT, false, size, offset_of!(Vertex => Bitangent).get_byte_offset() as i32); + gl.vertex_attrib_pointer_f32(4, 3, glow::FLOAT, false, size, 11*4); gl.bind_vertex_array(None); }