Runs, however buggy

pull/1/head
Milk.H 2023-03-08 15:09:25 +01:00
parent 0df79f7509
commit 219fc7f57f
No known key found for this signature in database
GPG Key ID: 3D9DAE46AAC37BD8
5 changed files with 96 additions and 91 deletions

View File

@ -8,7 +8,6 @@ edition = "2021"
[dependencies] [dependencies]
field-offset = "0.3.4" field-offset = "0.3.4"
image = "0.24.5" image = "0.24.5"
gl = "0.14.0"
cgmath = "0.18.0" cgmath = "0.18.0"
tobj = "2.0.0" tobj = "2.0.0"
glow = "0.12.1" glow = "0.12.1"

View File

@ -3,6 +3,7 @@ use glfw;
use glfw::{Action, Context, Key}; use glfw::{Action, Context, Key};
use cgmath::{Matrix4, vec3, Point3, Deg, perspective}; use cgmath::{Matrix4, vec3, Point3, Deg, perspective};
use cgmath::prelude::*; use cgmath::prelude::*;
use std::rc::Rc;
const SCR_WIDTH: u32 = 1600; const SCR_WIDTH: u32 = 1600;
const SCR_HEIGHT: u32 = 900; const SCR_HEIGHT: u32 = 900;
const TITLE: &str = "GLFWtest"; const TITLE: &str = "GLFWtest";
@ -56,13 +57,13 @@ fn main() {
let mut lastFrame: f32 = 0.0; 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(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 { 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) (ourShader, ourModel)
}; };
@ -72,7 +73,6 @@ fn main() {
let projection: Matrix4<f32> = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0); let projection: Matrix4<f32> = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0);
println!("entering main loop"); println!("entering main loop");
unsafe {gl::StencilOp(gl::KEEP, gl::KEEP, gl::REPLACE);}
while !window.should_close() { while !window.should_close() {
let currentFrame = glfw.get_time() as f32; let currentFrame = glfw.get_time() as f32;
deltaTime = currentFrame - lastFrame; deltaTime = currentFrame - lastFrame;
@ -81,23 +81,23 @@ fn main() {
processInput(&mut window, deltaTime, &mut camera); processInput(&mut window, deltaTime, &mut camera);
unsafe { unsafe {
gl::Enable(gl::DEPTH_TEST); gl.enable(glow::DEPTH_TEST);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
// outline // outline
ourshader.Use(); ourshader.Use();
let Projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0); let Projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0);
let view = camera.GetViewMatrix(); let view = camera.GetViewMatrix();
ourshader.setMat4(&CString::new("projection").unwrap(), &projection); ourshader.setMat4("projection", &projection);
ourshader.setMat4(&CString::new("view").unwrap(), &view); ourshader.setMat4("view", &view);
//let mut model = Matrix4::<f32>::from_translation(vec3(0.0, -0.3, 0.0)); //let mut model = Matrix4::<f32>::from_translation(vec3(0.0, -0.3, 0.0));
let mut model: Matrix4<f32> = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(), let mut model: Matrix4<f32> = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(),
cgmath::Rad(glfw.get_time() as f32)); cgmath::Rad(glfw.get_time() as f32));
model = model * Matrix4::from_scale(0.2); model = model * Matrix4::from_scale(0.2);
ourshader.setMat4(&CString::new("model").unwrap(), &model); ourshader.setMat4("model", &model);
ourModel.Draw(&ourshader); ourModel.Draw(&ourshader);
@ -131,7 +131,7 @@ fn main() {
} }
*/ */
} }
/*
fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>, fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>,
firstMouse: &mut bool, firstMouse: &mut bool,
lastX: &mut f32, lastX: &mut f32,
@ -142,7 +142,7 @@ fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>,
glfw::WindowEvent::FramebufferSize(width, height) => { glfw::WindowEvent::FramebufferSize(width, height) => {
// make sure the viewport matches the new window dimensions; note that width and // make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays. // 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) => { glfw::WindowEvent::CursorPos(xpos, ypos) => {
let (xpos, ypos) = (xpos as f32, ypos as f32); let (xpos, ypos) = (xpos as f32, ypos as f32);
@ -167,3 +167,4 @@ fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>,
} }
} }
} }
*/

View File

@ -3,10 +3,10 @@
use std::os::raw::c_void; use std::os::raw::c_void;
use std::path::Path; use std::path::Path;
use std::rc::Rc;
use cgmath::{vec2, vec3}; use cgmath::{vec2, vec3};
use gl;
use image; use image;
use glow::*;
use image::DynamicImage::*; use image::DynamicImage::*;
use image::GenericImage; use image::GenericImage;
use tobj; use tobj;
@ -24,9 +24,9 @@ pub struct Model {
impl Model { impl Model {
/// constructor, expects a filepath to a 3D model. /// constructor, expects a filepath to a 3D model.
pub fn new(path: &str) -> Model { pub fn new(path: &str, gl: std::rc::Rc<glow::Context>) -> Model {
let mut model = Model::default(); let mut model = Model::default();
model.loadModel(path); model.loadModel(path, Rc::clone(&gl));
model model
} }
@ -37,7 +37,7 @@ impl Model {
} }
// loads a model from file and stores the resulting meshes in the meshes vector. // 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<glow::Context>) {
let path = Path::new(path); let path = Path::new(path);
// retrieve the directory path of the filepath // retrieve the directory path of the filepath
@ -53,9 +53,6 @@ impl Model {
let mut vertices: Vec<Vertex> = Vec::with_capacity(num_vertices); let mut vertices: Vec<Vertex> = Vec::with_capacity(num_vertices);
let indices: Vec<u32> = mesh.indices.clone(); let indices: Vec<u32> = 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); let (p, n, t) = (&mesh.positions, &mesh.normals, &mesh.texcoords);
for i in 0..num_vertices { for i in 0..num_vertices {
vertices.push(Vertex { vertices.push(Vertex {
@ -73,28 +70,28 @@ impl Model {
// 1. diffuse map // 1. diffuse map
if !material.diffuse_texture.is_empty() { 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); textures.push(texture);
} }
// 2. specular map // 2. specular map
if !material.specular_texture.is_empty() { 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); textures.push(texture);
} }
// 3. normal map // 3. normal map
if !material.normal_texture.is_empty() { 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); textures.push(texture);
} }
// NOTE: no height maps // 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<glow::Context>) -> Texture {
{ {
let texture = self.textures_loaded.iter().find(|t| t.path == path); let texture = self.textures_loaded.iter().find(|t| t.path == path);
if let Some(texture) = texture { if let Some(texture) = texture {
@ -103,7 +100,7 @@ impl Model {
} }
let texture = Texture { let texture = Texture {
id: unsafe { TextureFromFile(path, &self.directory) }, id: unsafe { TextureFromFile(path, &self.directory, std::rc::Rc::clone(&gl)) },
type_: typeName.into(), type_: typeName.into(),
path: path.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::Context>) -> glow::NativeTexture {
let filename = format!("{}/{}", directory, path); let filename = format!("{}/{}", directory, path);
let mut textureID = 0; let mut textureID = gl.create_texture().unwrap();
gl::GenTextures(1, &mut textureID);
let img = image::open(&Path::new(&filename)).expect("Texture failed to load"); let img = image::open(&Path::new(&filename)).expect("Texture failed to load");
let img = img.flipv(); let img = img.flipv();
let format = match img { let format = match img {
ImageLuma8(_) => gl::RED, ImageLuma8(_) => glow::RED,
ImageLumaA8(_) => gl::RG, ImageLumaA8(_) => glow::RG,
ImageRgb8(_) => gl::RGB, ImageRgb8(_) => glow::RGB,
ImageRgba8(_) => gl::RGBA, ImageRgba8(_) => glow::RGBA,
_ => panic!("really weird image type"), _ => panic!("really weird image type"),
}; };
let data = img.as_bytes(); let data = img.as_bytes();
gl::BindTexture(gl::TEXTURE_2D, textureID); gl.bind_texture(glow::TEXTURE_2D, Some(textureID));
gl::TexImage2D(gl::TEXTURE_2D, 0, format as i32, img.width() as i32, img.height() as i32, gl.tex_image_2d(glow::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); 0, format, glow::UNSIGNED_BYTE, Some(&data));
gl::GenerateMipmap(gl::TEXTURE_2D); gl.generate_mipmap(glow::TEXTURE_2D);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR_MIPMAP_LINEAR as i32); gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::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_MAG_FILTER, glow::LINEAR as i32);
textureID textureID
} }

View File

@ -8,7 +8,7 @@ use std::ptr;
use cgmath::{ Vector3, Vector2 }; use cgmath::{ Vector3, Vector2 };
use cgmath::prelude::*; use cgmath::prelude::*;
use gl; use glow::*;
use field_offset::offset_of; use field_offset::offset_of;
use crate::shader::shader; use crate::shader::shader;
@ -43,7 +43,7 @@ impl Default for Vertex {
#[derive(Clone)] #[derive(Clone)]
pub struct Texture { pub struct Texture {
pub id: u32, pub id: glow::NativeTexture,
pub type_: String, pub type_: String,
pub path: String, pub path: String,
} }
@ -53,22 +53,28 @@ pub struct Mesh {
pub vertices: Vec<Vertex>, pub vertices: Vec<Vertex>,
pub indices: Vec<u32>, pub indices: Vec<u32>,
pub textures: Vec<Texture>, pub textures: Vec<Texture>,
pub VAO: u32, pub VAO: glow::VertexArray,
/* Render data */ /* Render data */
VBO: u32, VBO: glow::Buffer,
EBO: u32, EBO: glow::Buffer,
} }
impl Mesh { impl Mesh {
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>) -> Mesh { pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>,gl: std::rc::Rc<glow::Context>) -> Mesh {
let mut mesh =
{
unsafe {
let mut mesh = Mesh { let mut mesh = Mesh {
vertices, indices, textures, 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. // now that we have all the required data, set the vertex buffers and its attribute pointers.
unsafe { mesh.setupMesh() } unsafe { mesh.setupMesh(gl) }
mesh mesh
} }
@ -80,7 +86,7 @@ impl Mesh {
let mut normalNr = 0; let mut normalNr = 0;
let mut heightNr = 0; let mut heightNr = 0;
for (i, texture) in self.textures.iter().enumerate() { 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) // retrieve texture number (the N in diffuse_textureN)
let name = &texture.type_; let name = &texture.type_;
let number = match name.as_str() { let number = match name.as_str() {
@ -103,60 +109,66 @@ impl Mesh {
_ => panic!("unknown texture type") _ => panic!("unknown texture type")
}; };
// now set the sampler to the correct texture unit // now set the sampler to the correct texture unit
let sampler = CString::new(format!("{}{}", name, number)).unwrap(); let sampler = String::from(format!("{}{}", name, number));
gl::Uniform1i(gl::GetUniformLocation(shader.ID, sampler.as_ptr()), i as i32); shader.setInt(&sampler, i as i32);
// and finally bind the texture // and finally bind the texture
gl::BindTexture(gl::TEXTURE_2D, texture.id); shader.gl.bind_texture(glow::TEXTURE_2D, Some(texture.id));
} }
// draw mesh // draw mesh
gl::BindVertexArray(self.VAO); shader.gl.bind_vertex_array(Some(self.VAO));
gl::DrawElements(gl::TRIANGLES, self.indices.len() as i32, gl::UNSIGNED_INT, ptr::null()); shader.gl.draw_elements(glow::TRIANGLES, self.indices.len() as i32, glow::UNSIGNED_INT, 0);
gl::BindVertexArray(0); shader.gl.bind_vertex_array(None);
// always good practice to set everything back to defaults once configured. // 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<glow::Context>) {
// create buffers/arrays // create buffers/arrays
gl::GenVertexArrays(1, &mut self.VAO); gl.bind_vertex_array(Some(self.VAO));
gl::GenBuffers(1, &mut self.VBO);
gl::GenBuffers(1, &mut self.EBO);
gl::BindVertexArray(self.VAO);
// load data into vertex buffers // 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. // 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 // 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. // again translates to 3/2 floats which translates to a byte array.
let size = (self.vertices.len() * size_of::<Vertex>()) as isize; //let size = (self.vertices.len() * size_of::<Vertex>()) as isize;
let data = &self.vertices[0] as *const Vertex as *const c_void; //let data = &self.vertices[0] as *const Vertex as *const c_void;
gl::BufferData(gl::ARRAY_BUFFER, size, data, gl::STATIC_DRAW); let data: &[u8] = core::slice::from_raw_parts(
self.vertices.as_ptr() as *const u8,
self.vertices.len() * core::mem::size_of::<f32>(),
);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.EBO);
let size = (self.indices.len() * size_of::<u32>()) 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::<f32>(),
);
gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, data, glow::STATIC_DRAW);
// set the vertex attribute pointers // set the vertex attribute pointers
let size = size_of::<Vertex>() as i32; let size = size_of::<Vertex>() as i32;
// vertex Positions // vertex Positions
gl::EnableVertexAttribArray(0); gl.enable_vertex_attrib_array(0);
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Position).get_byte_offset() as *const c_void); gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, size, offset_of!(Vertex => Position).get_byte_offset() as i32);
// vertex normals // vertex normals
gl::EnableVertexAttribArray(1); gl.enable_vertex_attrib_array(1);
gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Normal).get_byte_offset() as *const c_void); gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, size, offset_of!(Vertex => Normal).get_byte_offset() as i32);
// vertex texture coords // vertex texture coords
gl::EnableVertexAttribArray(2); gl.enable_vertex_attrib_array(2);
gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => TexCoords).get_byte_offset() as *const c_void); gl.vertex_attrib_pointer_f32(2, 2, glow::FLOAT, false, size, offset_of!(Vertex => TexCoords).get_byte_offset() as i32);
// vertex tangent // vertex tangent
gl::EnableVertexAttribArray(3); gl.enable_vertex_attrib_array(3);
gl::VertexAttribPointer(3, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Tangent).get_byte_offset() as *const c_void); gl.vertex_attrib_pointer_f32(3, 3, glow::FLOAT, false, size, offset_of!(Vertex => Tangent).get_byte_offset() as i32);
// vertex bitangent // vertex bitangent
gl::EnableVertexAttribArray(4); gl.enable_vertex_attrib_array(4);
gl::VertexAttribPointer(4, 3, gl::FLOAT, gl::FALSE, size, offset_of!(Vertex => Bitangent).get_byte_offset() as *const c_void); 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);
} }
} }

View File

@ -1,16 +1,14 @@
use glow::*; use glow::*;
use std::fs; use std::fs;
use std::ffi::{CString, CStr};
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
use cgmath::prelude::*;
/// Shader Struct for creating and using shaders in the Context of engine /// Shader Struct for creating and using shaders in the Context of engine
/// ///
pub struct shader { pub struct shader {
pub ID: NativeProgram, pub ID: NativeProgram,
gl: Rc<glow::Context> pub gl: Rc<glow::Context>
} }
@ -61,7 +59,7 @@ use cgmath::prelude::*;
shader { shader {
ID: shader_program, ID: shader_program,
gl: Rc::clone(&gl), gl: Rc::clone(&gl),
}; }
} }
} }
@ -70,9 +68,9 @@ use cgmath::prelude::*;
// return program // return program
/// uses Shader /// 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 // BOILERPLATE JUMPSCARE