From 2654a9fdc928543c03e58eff4ac121094146a8d5 Mon Sep 17 00:00:00 2001 From: lisk77 Date: Wed, 1 Jan 2025 06:21:32 +0100 Subject: [PATCH] fix: some things are outdated for some reason... --- Cargo.toml | 10 +- README.md | 25 +- crates/comet_math/src/lib.rs | 2 +- crates/comet_math/src/noise.rs | 301 +++++++++++++++++++++- crates/comet_math/src/utilities.rs | 36 ++- crates/comet_renderer/src/camera.rs | 7 +- crates/comet_renderer/src/lib.rs | 1 + crates/comet_renderer/src/render_group.rs | 4 + crates/comet_renderer/src/renderer2d.rs | 46 ++-- src/lib.rs | 6 + src/main.rs | 37 ++- 11 files changed, 431 insertions(+), 44 deletions(-) create mode 100644 crates/comet_renderer/src/render_group.rs diff --git a/Cargo.toml b/Cargo.toml index 52eaa57..03ba166 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,9 @@ name = "comet" version = "0.1.0" edition = "2021" +authors = ["lisk77 "] +description = "A games framework" +repository = "https://github.com/lisk77/comet" [dependencies] comet_app = { path = "./crates/comet_app", workspace = true } @@ -43,8 +46,11 @@ members = [ "./crates/comet_resources", "./crates/comet_ecs", "./crates/comet_input", - "./crates/comet_log" -, "crates/comet_ui", "crates/comet_fonts", "crates/comet_sound"] + "./crates/comet_log", + "./crates/comet_ui", + "./crates/comet_fonts", + "./crates/comet_sound" +] [workspace.dependencies] comet_app = { path = "./crates/comet_app", workspace = true } diff --git a/README.md b/README.md index a34091f..a857eeb 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,9 @@ fn main() -> Result<()> { - [ ] UI - [ ] Buttons - [ ] Input - - [ ] Multiple render passes + - [ ] Post-processing + - [ ] Multiple render passes + - [ ] Individual effects - [ ] Sound - [ ] Input - [ ] Universal input manager @@ -135,4 +137,23 @@ fn main() -> Result<()> { - [ ] 3D - [x] Plugin System (at least right now) - [x] Adding custom game state struct - - [x] Adding custom renderer \ No newline at end of file + - [x] Adding custom renderer +- [ ] Math + - [x] Vectors + - [x] Matrices + - [ ] Quaternions + - [x] Interpolation + - [ ] Bezier curves + - [x] Easing functions + - [ ] Noise + - [ ] White + - [ ] Perlin + - [ ] Simplex + - [ ] Worley + - [ ] Fractal + - [ ] Cellular + - [ ] Gradient + - [ ] Value + - [ ] Cubic + - [ ] Ray-casting + - [ ] Pathfinding \ No newline at end of file diff --git a/crates/comet_math/src/lib.rs b/crates/comet_math/src/lib.rs index 43ddbff..a882c28 100644 --- a/crates/comet_math/src/lib.rs +++ b/crates/comet_math/src/lib.rs @@ -12,4 +12,4 @@ pub mod matrix; pub mod quaternion; pub mod bezier; pub mod easings; -mod noise; \ No newline at end of file +pub mod noise; \ No newline at end of file diff --git a/crates/comet_math/src/noise.rs b/crates/comet_math/src/noise.rs index 9f28fde..6d4cc3f 100644 --- a/crates/comet_math/src/noise.rs +++ b/crates/comet_math/src/noise.rs @@ -1,4 +1,14 @@ -use rand::Rng; +use rand::{Rng, SeedableRng}; +use comet_log::debug; +use crate::utilities::{lerp, lerp2, PI}; +use crate::{dot, InnerSpace, Vec2}; + +// TODO +// Make noise struct keep their generated noise +// Create noise trait as a common interface for all noise types +// Use noise trait to let the generated noise be outputed in different ways like images or Vec + + /// The WhiteNoise struct works a factory for generating white noise, given the size of the texture. pub struct WhiteNoise { @@ -29,11 +39,298 @@ impl WhiteNoise { let mut rng = rand::rng(); let mut noise = Vec::with_capacity(self.size.0 * self.size.1); - for _ in 0..self.size.0 * self.size.1 { + let dot_vec2 = Vec2::new(12.9898, 78.233); + + for i in 0..self.size.0 * self.size.1 { noise.push(rng.random_range(0.0..1.0)); + //noise.push(((dot(&Vec2::new(x,y), &dot_vec2)).sin() * 43758.5453).fract()); } noise } } +pub struct PerlinNoise { + size: (usize, usize), + frequency: f64, + seed: u32, +} + +impl PerlinNoise { + pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self { + Self { + size: (width, height), + frequency, + seed, + } + } + + pub fn set_width(&mut self, width: usize) { + self.size.0 = width; + } + + pub fn set_height(&mut self, height: usize) { + self.size.1 = height; + } + + pub fn set_size(&mut self, width: usize, height: usize) { + self.size = (width, height); + } + + pub fn set_frequency(&mut self, frequency: f64) { + self.frequency = frequency; + } + + pub fn set_seed(&mut self, seed: u32) { + self.seed = seed; + } + + /// Generates Perlin noise as a `Vec`. Size of the vector is `width * height`. + pub fn generate(&self) -> Vec { + let mut noise = Vec::with_capacity(self.size.0 * self.size.1); + + for y in 0..self.size.1 { + for x in 0..self.size.0 { + let nx = x as f64 / self.size.0 as f64; + let ny = y as f64 / self.size.1 as f64; + let value = self.perlin(nx * self.frequency, ny * self.frequency); + noise.push(((value+1.0) * 0.5)); + } + } + + noise + } + + /// Generates Perlin noise with multiple octaves as a `Vec`. + pub fn generate_with_octaves(&self, octaves: u32, persistence: f64) -> Vec { + let mut noise = vec![0.0; self.size.0 * self.size.1]; + let mut amplitude = 1.0; + let mut frequency = self.frequency; + let mut max_value = 0.0; // Used for normalization + + for _ in 0..octaves { + for y in 0..self.size.1 { + for x in 0..self.size.0 { + let nx = x as f64 / self.size.0 as f64; + let ny = y as f64 / self.size.1 as f64; + noise[y * self.size.0 + x] += self.perlin(nx * frequency, ny * frequency) as f32 * amplitude as f32; + } + } + max_value += amplitude; + amplitude *= persistence; // Reduce amplitude for next octave + frequency *= 2.0; // Double frequency for next octave + } + + // Normalize the noise to the range [0, 1] + noise.iter_mut().for_each(|value| *value /= max_value as f32); + + noise.iter_mut().for_each(|value| *value = (*value + 1.0) * 0.5); + + noise + } + + + /// A raw Perlin noise function implementation. + fn perlin(&self, x: f64, y: f64) -> f32 { + let xi = x.floor() as i32 & 255; + let yi = y.floor() as i32 & 255; + + let xf = x - x.floor(); + let yf = y - y.floor(); + + let u = Self::fade(xf); + let v = Self::fade(yf); + + let a = self.permutation(xi) + yi; + let b = self.permutation(xi + 1) + yi; + + let aa = self.permutation(a); + let ab = self.permutation(a + 1); + let ba = self.permutation(b); + let bb = self.permutation(b + 1); + + let x1 = lerp(u as f32, Self::grad(self.permutation(aa), xf, yf) as f32, Self::grad(self.permutation(ba), xf - 1.0, yf) as f32); + let x2 = lerp(u as f32, Self::grad(self.permutation(ab), xf, yf - 1.0) as f32, Self::grad(self.permutation(bb), xf - 1.0, yf - 1.0) as f32); + + lerp(v as f32, x1, x2) + } + + fn fade(t: f64) -> f64 { + t * t * t * (t * (t * 6.0 - 15.0) + 10.0) + } + + fn lerp(t: f64, a: f64, b: f64) -> f64 { + a + t * (b - a) + } + + fn grad(hash: i32, x: f64, y: f64) -> f64 { + let h = hash & 3; + let u = if h & 2 == 0 { x } else { -x }; + let v = if h & 1 == 0 { y } else { -y }; + u + v + } + + fn permutation(&self, value: i32) -> i32 { + const P: [i32; 256] = [ + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, + 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, + 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, + 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, + 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, + 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, + 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, + 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, + 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, + 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, + 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 + ]; + + P[((value ^ self.seed as i32) & 255) as usize] + } +} + +pub struct ValueNoise { + size: (usize, usize), + frequency: f64, + seed: u32, +} + +impl ValueNoise { + pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self { + Self { + size: (width, height), + frequency, + seed, + } + } + + fn permutation(&self, value: i32) -> i32 { + const P: [i32; 256] = [ + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, + 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, + 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, + 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, + 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, + 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, + 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, + 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, + 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, + 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, + 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 + ]; + + P[((value ^ self.seed as i32) & 255) as usize] + } + + fn noise(&self, p: (f32, f32)) -> f32 { + let i = (p.0.floor() as i32, p.1.floor() as i32); + let f = (p.0.fract(), p.1.fract()); + + // cubic interpolant + let u = ( + f.0 * f.0 * (3.0 - 2.0 * f.0), + f.1 * f.1 * (3.0 - 2.0 * f.1) + ); + + let a = self.permutation(i.0) + i.1; + let b = self.permutation(i.0 + 1) + i.1; + + lerp( + lerp( + self.permutation(a) as f32 / 255.0 * 2.0 - 1.0, + self.permutation(b) as f32 / 255.0 * 2.0 - 1.0, + u.0 + ), + lerp( + self.permutation(a + 1) as f32 / 255.0 * 2.0 - 1.0, + self.permutation(b + 1) as f32 / 255.0 * 2.0 - 1.0, + u.0 + ), + u.1 + ) + } + + pub fn generate(&self) -> Vec { + let mut noise = Vec::with_capacity(self.size.0 * self.size.1); + let mut max_amplitude = 0.0; + let mut amplitude = 0.5; + + // Calculate max amplitude for normalization + for _ in 0..4 { + max_amplitude += amplitude; + amplitude *= 0.5; + } + + for y in 0..self.size.1 { + for x in 0..self.size.0 { + let mut uv = ( + x as f32 / self.size.0 as f32 * self.frequency as f32, + y as f32 / self.size.1 as f32 * self.frequency as f32, + ); + + let mut f = 0.0; + let mut amplitude = 0.5; + + /*for _ in 0..4 { // 4 octaves*/ + f += amplitude * self.noise(uv); + + // Double frequency for next octave + uv = (uv.0 * 2.0, uv.1 * 2.0); + + // Reduce amplitude (persistence) + amplitude *= 0.5; + /*}*/ + + // Normalize and convert to [0, 1] + f = ((f / max_amplitude) + 1.0) * 0.5; + + noise.push(f); + } + } + + noise + } + + + pub fn generate_with_octaves(&self, octaves: u32, persistence: f64) -> Vec { + let mut noise = Vec::with_capacity(self.size.0 * self.size.1); + let mut max_amplitude = 0.0; + let mut amplitude = 1.0; + + // Calculate max amplitude for normalization + for _ in 0..octaves { + max_amplitude += amplitude; + amplitude *= persistence; + } + + for y in 0..self.size.1 { + for x in 0..self.size.0 { + // Convert to UV space and scale by frequency + let mut uv = ( + x as f32 / self.size.0 as f32 * self.frequency as f32, + y as f32 / self.size.1 as f32 * self.frequency as f32, + ); + + let mut f = 0.0; + let mut amplitude = 1.0; + + for _ in 0..octaves { + f += amplitude * self.noise(uv); + + // Double frequency for next octave + uv = (uv.0 * 2.0, uv.1 * 2.0); + + // Reduce amplitude (persistence) + amplitude *= persistence as f32; + } + + // Normalize and convert to [0, 1] + f = ((f / max_amplitude as f32) + 1.0) * 0.5; + + noise.push(f); + } + } + + noise + } +} \ No newline at end of file diff --git a/crates/comet_math/src/utilities.rs b/crates/comet_math/src/utilities.rs index 3f85e10..a1cd2ec 100644 --- a/crates/comet_math/src/utilities.rs +++ b/crates/comet_math/src/utilities.rs @@ -101,19 +101,23 @@ pub fn pointDerivative(func: fn(f32) -> f32, x: f32, h: f32) -> f32 { // # INTERPOLATION # // ################################################## +/// Linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. pub fn lerp(a: f32, b: f32, t: f32) -> f32 { (1.0 - t) * a + t * b } -pub fn invLerp(a: f32, b:f32, value: f32) -> f32 { +/// The inverse operation of linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. +pub fn inv_lerp(a: f32, b:f32, value: f32) -> f32 { (value - a) / (b - a) } +/// Two-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. pub fn lerp2(a: Vec2, b: Vec2, t: f32) -> Vec2 { a * (1.0 - t) + b * t } -pub fn invLerp2(a: Vec2, b: Vec2, value: Vec2) -> Option { +/// The inverse operation of the two-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. +pub fn inv_lerp2(a: Vec2, b: Vec2, value: Vec2) -> Option { let tx = (value.x() - a.x()) / (b.x() - a.x()); let ty = (value.y() - a.y()) / (b.y() - a.y()); @@ -123,11 +127,13 @@ pub fn invLerp2(a: Vec2, b: Vec2, value: Vec2) -> Option { None } +/// Three-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. pub fn lerp3(a: Vec3, b: Vec3, t: f32) -> Vec3 { a * (1.0 - t) + b * t } -pub fn invLerp3(a: Vec3, b: Vec3, value: Vec3) -> Option { +/// The inverse operation of the three-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. +pub fn inv_lerp3(a: Vec3, b: Vec3, value: Vec3) -> Option { let tx = (value.x() - a.x())/(b.x() - a.x()); let ty = (value.y() - a.y())/(b.y() - a.y()); let tz = (value.z() - a.z())/(b.z() - a.z()); @@ -138,6 +144,30 @@ pub fn invLerp3(a: Vec3, b: Vec3, value: Vec3) -> Option { None } +/// Four-dimensional linear interpolation between the values `a` and `b` with the parameter `t`, while `t` is in the range [0,1]. +pub fn lerp4(a: Vec4, b: Vec4, t: f32) -> Vec4 { + a * (1.0 - t) + b * t +} + +/// The inverse operation of the four-dimensional linear interpolation. Given the values `a` and `b` and the result `value`, this function returns the parameter `t`. +pub fn inv_lerp4(a: Vec4, b: Vec4, value: Vec4) -> Option { + let tx = (value.x() - a.x())/(b.x() - a.x()); + let ty = (value.y() - a.y())/(b.y() - a.y()); + let tz = (value.z() - a.z())/(b.z() - a.z()); + let tw = (value.w() - a.w())/(b.w() - a.w()); + + if (tx == ty) && (ty == tz) && (tz == tw) { + return Some(tx); + } + None +} + +/// Cubic interpolation with the polynomial 3t² - 2t³ +fn cubic_interpolation(a: f32, b: f32, t: f32) -> f32 { + let g = (3.0 - t * 2.0) * t * t; + (b-a) * g + a +} + // ################################################## // # BEZIER CURVES # // ################################################## diff --git a/crates/comet_renderer/src/camera.rs b/crates/comet_renderer/src/camera.rs index f95ce97..d3ad19c 100644 --- a/crates/comet_renderer/src/camera.rs +++ b/crates/comet_renderer/src/camera.rs @@ -30,7 +30,12 @@ impl Camera { } pub fn build_view_projection_matrix(&self) -> cgmath::Matrix4 { - OPENGL_TO_WGPU_MATRIX * cgmath::ortho(self.position.x() - self.dimension.x() / 2.0, self.position.x() + self.dimension.x() / 2.0, self.position.y() - self.dimension.y() / 2.0, self.position.y() + self.dimension.y() / 2.0, 1.0, 0.0) + OPENGL_TO_WGPU_MATRIX * cgmath::ortho(self.position.x() - self.dimension.x() / 2.0, + self.position.x() + self.dimension.x() / 2.0, + self.position.y() - self.dimension.y() / 2.0, + self.position.y() + self.dimension.y() / 2.0, + 1.0, + 0.0) } } diff --git a/crates/comet_renderer/src/lib.rs b/crates/comet_renderer/src/lib.rs index 8f7748f..8046ee0 100644 --- a/crates/comet_renderer/src/lib.rs +++ b/crates/comet_renderer/src/lib.rs @@ -4,6 +4,7 @@ mod camera; pub mod renderer; pub mod renderer2d; mod render_pass; +mod render_group; pub struct Projection { aspect: f32, diff --git a/crates/comet_renderer/src/render_group.rs b/crates/comet_renderer/src/render_group.rs new file mode 100644 index 0000000..a9e795d --- /dev/null +++ b/crates/comet_renderer/src/render_group.rs @@ -0,0 +1,4 @@ + pub struct RenderGroup { + pipeline: wgpu::RenderPipeline, + entities: Vec + } \ No newline at end of file diff --git a/crates/comet_renderer/src/renderer2d.rs b/crates/comet_renderer/src/renderer2d.rs index 1ba78ff..f4062db 100644 --- a/crates/comet_renderer/src/renderer2d.rs +++ b/crates/comet_renderer/src/renderer2d.rs @@ -24,7 +24,7 @@ pub struct Renderer2D<'a> { config: wgpu::SurfaceConfiguration, size: winit::dpi::PhysicalSize, render_pipeline_layout: wgpu::PipelineLayout, - render_pipeline: wgpu::RenderPipeline, + pipelines: Vec, render_pass: Vec, last_frame_time: Instant, deltatime: f32, @@ -254,6 +254,9 @@ impl<'a> Renderer2D<'a> { cache: None, }); + let mut pipelines = Vec::new(); + pipelines.push(render_pipeline); + let clear_color = match clear_color { Some(color) => color.to_wgpu(), None => wgpu::Color { @@ -271,7 +274,7 @@ impl<'a> Renderer2D<'a> { config, size, render_pipeline_layout, - render_pipeline, + pipelines, render_pass: vec![], last_frame_time: Instant::now(), deltatime: 0.0, @@ -323,6 +326,13 @@ impl<'a> Renderer2D<'a> { info!("Shader ({}) loaded successfully", file_name); } + pub fn load_shaders(&mut self, shader_stages: Vec>, file_names: Vec<&str>) { + for (i, file_name) in file_names.iter().enumerate() { + self.load_shader(shader_stages[i].clone(), file_name); + info!("Shader ({}) loaded successfully", file_name); + } + } + /// A function that applies a shader to the entire surface of the `Renderer2D` if the shader is loaded. pub fn apply_shader(&mut self, shader: &str) { let shader_module = self.graphic_resource_manager.get_shader(((Self::get_project_root().unwrap().as_os_str().to_str().unwrap().to_string() + "\\resources\\shaders\\").as_str().to_string() + shader).as_str()).unwrap(); @@ -372,7 +382,7 @@ impl<'a> Renderer2D<'a> { push_constant_ranges: &[], }); - self.render_pipeline = self.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + self.pipelines[0] = self.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Render Pipeline"), layout: Some(&render_pipeline_layout), vertex: wgpu::VertexState { @@ -477,7 +487,7 @@ impl<'a> Renderer2D<'a> { push_constant_ranges: &[], }); - self.render_pipeline = self.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + self.pipelines[0] = self.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Render Pipeline"), layout: Some(&render_pipeline_layout), vertex: wgpu::VertexState { @@ -779,7 +789,7 @@ impl<'a> Renderer2D<'a> { label: Some("Render Encoder"), }); - + for pipeline in &self.pipelines { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { @@ -795,35 +805,13 @@ impl<'a> Renderer2D<'a> { timestamp_writes: None, }); - render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); render_pass.set_bind_group(1, &self.camera_bind_group, &[]); render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); render_pass.draw_indexed(0..self.num_indices, 0, 0..1); - - - if self.render_pass.len() > 0 { - for (i, pass_info) in self.render_pass.iter().enumerate() { - let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some(format!("Custom Render Pass {}", i).as_str()), - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Load, - store: wgpu::StoreOp::Store, - }, - })], - depth_stencil_attachment: None, - occlusion_query_set: None, - timestamp_writes: None, - }); - - } - - - } + } self.queue.submit(iter::once(encoder.finish())); output.present(); diff --git a/src/lib.rs b/src/lib.rs index dc25d3c..b21606b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,4 +10,10 @@ pub use comet_log as log; pub mod prelude { pub use comet_app::App; + pub use comet_app::ApplicationType::App2D; + pub use comet_renderer::renderer2d::Renderer2D; + pub use comet_input::input_handler; + pub use comet_log::*; + pub use comet_colors::*; + pub use comet_ecs::*; } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c60592c..e2152db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ use std::ops::Deref; +use colored::Color::White; +use image::{GrayImage, Luma}; use comet::{ app::{ App, @@ -18,6 +20,7 @@ use comet::{ use winit_input_helper::WinitInputHelper; use comet_input::input_handler::InputHandler; +use comet_math::noise::{PerlinNoise, ValueNoise, WhiteNoise}; #[derive(Debug, Clone)] struct GameState { @@ -42,7 +45,6 @@ impl GameState { fn update_position(input: WinitInputHelper, transform: &mut Transform2D, dt: f32) { let mut direction = Vec2::ZERO; - let previous = transform.position().clone(); if input.key_held(Key::KeyW) { direction += Vec2::Y; @@ -86,7 +88,6 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) { renderer.load_shader(None, "blacknwhite.wgsl"); renderer.load_shader(None, "crt.wgsl"); renderer.load_shader(None, "glitch.wgsl"); - renderer.apply_shader("glitch.wgsl"); let world = app.world_mut(); world.register_component::(); @@ -130,12 +131,40 @@ fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) { renderer.render_scene_2d(app.world()); } +fn save_image_fromg_f32_vec(pixels: Vec, width: u32, height: u32, path: &str) -> Result<(), Box>{ + //debug!("{:?}", pixels); + if pixels.len() != (width * height) as usize { + return Err("The size of the input Vec does not match the width and height".into()); + } + + // Create a new image buffer with the given width and height. + let mut img = GrayImage::new(width, height); + + // Iterate over the `Vec` and convert each value to u8. + for (i, &val) in pixels.iter().enumerate() { + let pixel_value = (val * 255.0).clamp(0.0, 255.0) as u8; + let x = (i as u32) % width; + let y = (i as u32) / width; + + img.put_pixel(x, y, Luma([pixel_value])); + } + + // Save the image to the specified path. + img.save(path)?; + + Ok(()) +} + fn main() { - App::new(App2D) + //let mut perlin = PerlinNoise::new(1000, 1000, 5.0, 777); + let mut perlin = ValueNoise::new(1000, 1000, 15.0, 77); + let noise = perlin.generate(); + save_image_fromg_f32_vec(noise, 1000, 1000, "C:\\Users\\lisk77\\Code Sharing\\comet\\resources\\textures\\perlin.png").unwrap(); + /*App::new(App2D) .with_title("Comet App") .with_icon(r"resources/textures/comet_icon.png") .with_size(1920, 1080) .with_game_state(GameState::new()) .run::(setup, update) - ; + ;*/ } \ No newline at end of file