Generate random grass texture
Description
Instead of hard coding a 2x2 array, generate an array of random bytes for an 8x8 texture. We're still using gl::GREEN when uploading our texture data, so the random values might look like a poor quality grass texture (if you squint hard enough).
For random values there's the rand crate, but I was curious how random numbers work so I implemented my own. This implementation is a xorshift random number generator which is very simple to implement.
When we add more randomness later, we'll likely switch to the rand crate which is far more robust.
Screenshot
Commands
git clone git@github.com:atsheehan/iridium
cd iridium
git checkout 828b084bdecc26456c04e209e658a4378dbd35e5
cargo run --release
Code Changes
Modified src/math.rsGitHub
@@ -1 +1,23 @@11 pub(crate) struct Vec3(pub(crate) f32, pub(crate) f32, pub(crate) f32);
2+
3+ pub(crate) struct RandomNumberGenerator {
4+ seed: u32,
5+ }
6+
7+ impl RandomNumberGenerator {
8+ pub(crate) fn with_seed(seed: u32) -> Self {
9+ Self { seed }
10+ }
11+
12+ pub(crate) fn gen_u32(&mut self) -> u32 {
13+ self.seed ^= self.seed << 13;
14+ self.seed ^= self.seed >> 17;
15+ self.seed ^= self.seed << 5;
16+ self.seed
17+ }
18+
19+ pub(crate) fn gen_range(&mut self, min: u32, max: u32) -> u32 {
20+ let range = max - min;
21+ min + self.gen_u32() % range
22+ }
23+ }
@@ -1 +1,23 @@1 pub(crate) struct Vec3(pub(crate) f32, pub(crate) f32, pub(crate) f32);
@@ -1 +1,23 @@1 pub(crate) struct Vec3(pub(crate) f32, pub(crate) f32, pub(crate) f32);
2+
3+ pub(crate) struct RandomNumberGenerator {
4+ seed: u32,
5+ }
6+
7+ impl RandomNumberGenerator {
8+ pub(crate) fn with_seed(seed: u32) -> Self {
9+ Self { seed }
10+ }
11+
12+ pub(crate) fn gen_u32(&mut self) -> u32 {
13+ self.seed ^= self.seed << 13;
14+ self.seed ^= self.seed >> 17;
15+ self.seed ^= self.seed << 5;
16+ self.seed
17+ }
18+
19+ pub(crate) fn gen_range(&mut self, min: u32, max: u32) -> u32 {
20+ let range = max - min;
21+ min + self.gen_u32() % range
22+ }
23+ }
Modified src/render.rsGitHub
@@ -18,7 +18,7 @@1818 window::{Window, WindowBuilder, WindowId},
1919 };
2020
21- use crate::math::Vec3;
21+ use crate::math::{RandomNumberGenerator, Vec3};
2222
2323 const CUBE_VERTEX_SHADER_SRC: &str = include_str!("../shaders/cube.vert");
2424 const CUBE_FRAGMENT_SHADER_SRC: &str = include_str!("../shaders/cube.frag");
@@ -87,18 +87,17 @@8787 gl::GenTextures(1, &mut cube_texture_id);
8888 gl::BindTexture(gl::TEXTURE_2D, cube_texture_id);
8989
90- const TEXTURE_WIDTH: usize = 2;
91- const TEXTURE_HEIGHT: usize = 2;
90+ const TEXTURE_WIDTH: usize = 8;
91+ const TEXTURE_HEIGHT: usize = 8;
9292 const VALUES_PER_PIXEL: usize = 3;
9393 const TEXTURE_SIZE: usize = TEXTURE_WIDTH * TEXTURE_HEIGHT * VALUES_PER_PIXEL;
9494
95- #[rustfmt::skip]
96- let data: [u8; TEXTURE_SIZE] = [
97- 252, 244, 183,
98- 137, 233, 51,
99- 117, 21, 246,
100- 157, 12, 112
101- ];
95+ let mut rng = RandomNumberGenerator::with_seed(42);
96+ let mut data: Vec<u8> = Vec::with_capacity(TEXTURE_SIZE);
97+
98+ for _ in 0..TEXTURE_SIZE {
99+ data.push(rng.gen_range(120, 180) as u8);
100+ }
102101
103102 gl::TexImage2D(
104103 gl::TEXTURE_2D,
@@ -18,7 +18,7 @@18 window::{Window, WindowBuilder, WindowId},
19 };
20
21- use crate::math::Vec3;
22
23 const CUBE_VERTEX_SHADER_SRC: &str = include_str!("../shaders/cube.vert");
24 const CUBE_FRAGMENT_SHADER_SRC: &str = include_str!("../shaders/cube.frag");
@@ -87,18 +87,17 @@87 gl::GenTextures(1, &mut cube_texture_id);
88 gl::BindTexture(gl::TEXTURE_2D, cube_texture_id);
89
90- const TEXTURE_WIDTH: usize = 2;
91- const TEXTURE_HEIGHT: usize = 2;
92 const VALUES_PER_PIXEL: usize = 3;
93 const TEXTURE_SIZE: usize = TEXTURE_WIDTH * TEXTURE_HEIGHT * VALUES_PER_PIXEL;
94
95- #[rustfmt::skip]
96- let data: [u8; TEXTURE_SIZE] = [
97- 252, 244, 183,
98- 137, 233, 51,
99- 117, 21, 246,
100- 157, 12, 112
101- ];
102
103 gl::TexImage2D(
104 gl::TEXTURE_2D,
@@ -18,7 +18,7 @@18 window::{Window, WindowBuilder, WindowId},
19 };
20
21+ use crate::math::{RandomNumberGenerator, Vec3};
22
23 const CUBE_VERTEX_SHADER_SRC: &str = include_str!("../shaders/cube.vert");
24 const CUBE_FRAGMENT_SHADER_SRC: &str = include_str!("../shaders/cube.frag");
@@ -87,18 +87,17 @@87 gl::GenTextures(1, &mut cube_texture_id);
88 gl::BindTexture(gl::TEXTURE_2D, cube_texture_id);
89
90+ const TEXTURE_WIDTH: usize = 8;
91+ const TEXTURE_HEIGHT: usize = 8;
92 const VALUES_PER_PIXEL: usize = 3;
93 const TEXTURE_SIZE: usize = TEXTURE_WIDTH * TEXTURE_HEIGHT * VALUES_PER_PIXEL;
94
95+ let mut rng = RandomNumberGenerator::with_seed(42);
96+ let mut data: Vec<u8> = Vec::with_capacity(TEXTURE_SIZE);
97+
98+ for _ in 0..TEXTURE_SIZE {
99+ data.push(rng.gen_range(120, 180) as u8);
100+ }
101
102 gl::TexImage2D(
103 gl::TEXTURE_2D,