perlinimage/
perlinimage.rs

1use std::sync::Arc;
2
3use glam::{Vec2, Vec3};
4use image::{Rgba, RgbaImage};
5use rhachis::{
6    game_data,
7    graphics::{Renderer, SamplerType},
8    math::smootherstep,
9    model::{Model, Transform},
10    rand::{perlin_2d, Noise},
11    renderers::{SimpleRenderer, SimpleRendererBuilder},
12    texture::Texture,
13    Game, GameExt,
14};
15
16const IMAGE_WIDTH: u32 = 1200;
17const IMAGE_HEIGHT: u32 = 800;
18
19#[rhachis::run]
20struct PerlinImage(SimpleRenderer);
21
22impl Game for PerlinImage {
23    fn init() -> Self {
24        let noise = match std::env::args().nth(1) {
25            Some(seed) => Noise::from_seed(seed.parse().unwrap()),
26            None => Noise::new(),
27        };
28        game_data().set_window_size((IMAGE_WIDTH, IMAGE_HEIGHT).into());
29
30        let mut image = RgbaImage::new(IMAGE_WIDTH, IMAGE_HEIGHT);
31
32        for x in 0..IMAGE_WIDTH {
33            for y in 0..IMAGE_HEIGHT {
34                let perlin = [
35                    perlin_2d(&noise, Vec2::new(x as f32, y as f32) / 16.0, smootherstep) * 0.0625,
36                    perlin_2d(&noise, Vec2::new(x as f32, y as f32) / 32.0, smootherstep) * 0.125,
37                    perlin_2d(&noise, Vec2::new(x as f32, y as f32) / 64.0, smootherstep) * 0.25,
38                    perlin_2d(&noise, Vec2::new(x as f32, y as f32) / 128.0, smootherstep) * 0.5,
39                    perlin_2d(&noise, Vec2::new(x as f32, y as f32) / 256.0, smootherstep),
40                ];
41                let value = ((perlin.into_iter().sum::<f32>() + 1.0) * 127.0) as u8;
42                image.put_pixel(x, y, Rgba([value, value, value, 255]));
43            }
44        }
45
46        let mut renderer = SimpleRendererBuilder::default().build();
47        let texture = Arc::new(Texture::from_image(&image, SamplerType::NEAREST).unwrap());
48
49        renderer.models.push(Model::quad_texture(
50            texture,
51            vec![Transform::scale(Vec3::new(2.0, 2.0, 1.0))
52                .with_translation(Vec3::new(-1.0, -1.0, 0.0))],
53        ));
54
55        Self(renderer)
56    }
57
58    fn get_renderer(&mut self) -> &mut dyn Renderer {
59        &mut self.0
60    }
61}