From b24be88bdcf8348dcf3cbfe1f37828399e40c9d2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 28 Aug 2025 18:21:53 +0200 Subject: [PATCH] added more code to render my first scene; STILL WITH ERRORS --- .../resources/shaders/sphere.frag | 12 +++ .../resources/shaders/sphere.vert | 22 +++++ .../src/custom/sphere_generator.rs | 13 ++- opengl_beginnings/src/engine/nebulix.rs | 11 +++ opengl_beginnings/src/engine/shader.rs | 82 +++++++++++++------ 5 files changed, 111 insertions(+), 29 deletions(-) create mode 100644 opengl_beginnings/resources/shaders/sphere.frag create mode 100644 opengl_beginnings/resources/shaders/sphere.vert diff --git a/opengl_beginnings/resources/shaders/sphere.frag b/opengl_beginnings/resources/shaders/sphere.frag new file mode 100644 index 0000000..1bd67a8 --- /dev/null +++ b/opengl_beginnings/resources/shaders/sphere.frag @@ -0,0 +1,12 @@ +#version 330 core + +//in vec3 fragPos; +//in vec3 fragNormal; + +out vec4 FragColor; + +void main() +{ +// FragColor = vec4(fragPos, 1.0); + FragColor = vec4(1.0, 1.0, 1.0 , 1.0); +} \ No newline at end of file diff --git a/opengl_beginnings/resources/shaders/sphere.vert b/opengl_beginnings/resources/shaders/sphere.vert new file mode 100644 index 0000000..0fdae0a --- /dev/null +++ b/opengl_beginnings/resources/shaders/sphere.vert @@ -0,0 +1,22 @@ +#version 330 core + +layout(location=0) in vec3 position; +layout(location=1) in vec3 normals; + +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; + +//out vec3 fragPos; +//out vec3 fragNormal; + +void main() +{ + vec4 pos = vec4(position, 1.0); + + // the inverse should be calculated on the CPU as it is quite expensive to run and doesn't need to be run for every vertex +// fragNormal = mat3(transpose(inverse(modelMatrix))) * normals; +// fragPos = vec3(modelMatrix * pos); + + gl_Position = projectionMatrix * viewMatrix * modelMatrix * pos; +} \ No newline at end of file diff --git a/opengl_beginnings/src/custom/sphere_generator.rs b/opengl_beginnings/src/custom/sphere_generator.rs index 2405cf5..270fc07 100644 --- a/opengl_beginnings/src/custom/sphere_generator.rs +++ b/opengl_beginnings/src/custom/sphere_generator.rs @@ -1,4 +1,5 @@ use crate::engine::mesh::Mesh; +use glow::Context; use nalgebra::Vector3; pub struct OctaSphere { @@ -20,7 +21,14 @@ impl OctaSphere { } } - pub fn generate_sphere(&mut self) { + pub fn render(&mut self, gl: &Context) { + match self.mesh.as_mut() { + None => {self.generate_sphere(); self.render(gl)}, + Some(mut mesh) => {mesh.render(gl)} + } + } + + fn generate_sphere(&mut self) { let (vertices, indices) = self.generator.generate_sphere(); self.mesh = Some(Mesh::new(vertices, indices)) } @@ -51,9 +59,10 @@ impl OctaSphereGenerator { let num_vertices = num_vertices_per_face * 8 - (num_divisions + 2) * 12 + 6; let num_tris_per_face = (num_divisions + 1) * (num_divisions + 1); + let mut vertices = Vec::>::with_capacity(num_vertices as usize); let mut indicies = Vec::::with_capacity((num_tris_per_face * 8 * 3) as usize); - vertices.copy_from_slice(&base_vertices); + vertices.extend_from_slice(&base_vertices); // Create 12 edges, with n vertices added along them (n = numDivisions) let mut edges = Vec::::with_capacity(12); diff --git a/opengl_beginnings/src/engine/nebulix.rs b/opengl_beginnings/src/engine/nebulix.rs index 2349467..0b81e15 100644 --- a/opengl_beginnings/src/engine/nebulix.rs +++ b/opengl_beginnings/src/engine/nebulix.rs @@ -1,5 +1,7 @@ use crate::camera::perspective_camera::PerspectiveCamera; +use crate::custom::sphere_generator::OctaSphere; use crate::engine::input::Input; +use crate::engine::shader::Shader; use crate::engine::time::Time; use crate::Extension; use glow::{Context, HasContext}; @@ -136,6 +138,15 @@ impl ApplicationHandler for Nebulix { } // Custom code HERE + let mut sphere = OctaSphere::new(2).unwrap(); + let sphere_shader = Shader::new(gl, "./resources/shaders/sphere.vert".into(), "./resources/shaders/sphere.frag".into()).unwrap(); + + sphere_shader.set_matrix4_f32("modelMatrix", model_matrix); + sphere_shader.set_matrix4_f32("viewMatrix", view_matrix); + sphere_shader.set_matrix4_f32("projectionMatrix", projection_matrix); + + sphere_shader.use_shader(); + sphere.render(gl); gl_surface.swap_buffers(&gl_context).unwrap(); self.window.as_ref().unwrap().request_redraw(); diff --git a/opengl_beginnings/src/engine/shader.rs b/opengl_beginnings/src/engine/shader.rs index f19c5f3..fe72d49 100644 --- a/opengl_beginnings/src/engine/shader.rs +++ b/opengl_beginnings/src/engine/shader.rs @@ -14,21 +14,41 @@ impl ShaderType { } } -struct Shader<'a> { +pub struct Shader<'a> { gl: &'a Context, program: NativeProgram, } impl<'a> Shader<'a> { - pub fn new(&self, gl: &'a Context, vertex_shader_file: String, fragment_shader_file: String) -> Self { - let vertex_shader = self.compile_shader(vertex_shader_file, ShaderType::Vertex); - let fragment_shader = self.compile_shader(fragment_shader_file, ShaderType::Fragment); - let program = self.create_program(vertex_shader, fragment_shader); + pub fn new(gl: &'a Context, vertex_shader_file: String, fragment_shader_file: String) -> Result { + let vertex_shader_code = match std::fs::read_to_string(vertex_shader_file) { + Ok(vsc) => {vsc} + Err(error) => {return Err(error.to_string())} + }; + let vertex_shader = match Self::compile_shader(gl, vertex_shader_code, ShaderType::Vertex) { + Ok(vs) => {vs} + Err(error) => {return Err(error)} + }; - Self { - gl, - program, + let fragment_shader_code = match std::fs::read_to_string(fragment_shader_file) { + Ok(fsc) => {fsc} + Err(error) => {return Err(error.to_string())} + }; + let fragment_shader = match Self::compile_shader(gl, fragment_shader_code, ShaderType::Fragment) { + Ok(fs) => {fs} + Err(error) => {return Err(error)} + }; + + let program = Self::create_program(gl, vertex_shader, fragment_shader); + match program { + Err(error) => {return Err(error);}, + _ => () } + + Ok(Self { + gl, + program: program?, + }) } pub fn use_shader(&self) { @@ -65,38 +85,46 @@ impl<'a> Shader<'a> { } } - fn compile_shader(&self, shader_code: String, shader_type: ShaderType) -> NativeShader { + fn compile_shader(gl: &Context, shader_code: String, shader_type: ShaderType) -> Result { unsafe { - let shader = self.gl.create_shader(shader_type.to_u32()).unwrap(); + let shader = match gl.create_shader(shader_type.to_u32()) { + Ok(s) => {s} + Err(error) => {return Err(error);} + }; - self.gl.shader_source(shader, shader_code.as_str()); - self.gl.compile_shader(shader); + gl.shader_source(shader, shader_code.as_str()); + gl.compile_shader(shader); - if self.gl.get_shader_compile_status(shader) { - panic!("{}", self.gl.get_shader_info_log(shader)); + if !gl.get_shader_compile_status(shader) { + Err(gl.get_shader_info_log(shader)) + } else { + Ok(shader) } - shader } } - fn create_program(&self, vertex_shader: NativeShader, fragment_shader: NativeShader) -> NativeProgram { + fn create_program(gl: &Context, vertex_shader: NativeShader, fragment_shader: NativeShader) -> Result { unsafe { - let program = self.gl.create_program().unwrap(); - self.gl.attach_shader(program, vertex_shader); - self.gl.attach_shader(program, fragment_shader); - self.gl.link_program(program); + let program = match gl.create_program() { + Ok(p) => {p} + Err(error) => {return Err(error)}, + }; - if(!self.gl.get_program_link_status(program)) { - panic!("Error while linking shaders with message: \n{}", self.gl.get_program_info_log(program)); + gl.attach_shader(program, vertex_shader); + gl.attach_shader(program, fragment_shader); + gl.link_program(program); + + if(!gl.get_program_link_status(program)) { + return Err(format!("Error while linking shaders with message: '{}'", gl.get_program_info_log(program))); } - self.gl.detach_shader(program, vertex_shader); - self.gl.detach_shader(program, fragment_shader); - self.gl.delete_shader(vertex_shader); - self.gl.delete_shader(fragment_shader); + gl.detach_shader(program, vertex_shader); + gl.detach_shader(program, fragment_shader); + gl.delete_shader(vertex_shader); + gl.delete_shader(fragment_shader); - program + Ok(program) } } } \ No newline at end of file