perlinimage/
perlinimage.rs1use 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}