From ddf0c4278478053abab8dfbe5fa363bc563436b6 Mon Sep 17 00:00:00 2001 From: Piotrek Date: Wed, 28 Apr 2021 23:17:16 +0200 Subject: [PATCH] working generating terrain --- src/app/world_gen.rs | 116 ++++++++++-------------- src/renderer/buffers/blocks.rs | 20 ++-- src/renderer/buffers/mod.rs | 2 +- src/renderer/level.rs | 12 ++- src/shaders/raytrace/.bin/main.frag.spv | Bin 13632 -> 13692 bytes src/shaders/raytrace/main.frag | 2 +- 6 files changed, 64 insertions(+), 88 deletions(-) diff --git a/src/app/world_gen.rs b/src/app/world_gen.rs index e681d44..e315980 100644 --- a/src/app/world_gen.rs +++ b/src/app/world_gen.rs @@ -1,10 +1,12 @@ use cgmath::{Point3, InnerSpace}; use noise::{Perlin, NoiseFn}; -use rand::Rng; +use rand::{Rng, prelude::ThreadRng}; use crate::renderer::Level; use crate::renderer::buffers::{BLOCK_SIZE, NODE_TEX_SIZE, Block}; +const SCALE: f64 = 150.0; + pub struct WorldGen { @@ -16,85 +18,63 @@ impl WorldGen { Self{} } + /* + * Generate height map for given block position + */ + fn gen_height_map(x: usize, z: usize, rand: &mut ThreadRng, noise: &Perlin) -> ([[usize;BLOCK_SIZE]; BLOCK_SIZE], usize) { + let x = x * BLOCK_SIZE; + let z = z * BLOCK_SIZE; + + // Generate map + let mut max: usize = 0; + let mut map = [[0_usize; BLOCK_SIZE]; BLOCK_SIZE]; + for lx in 0..BLOCK_SIZE { + for lz in 0..BLOCK_SIZE { + let value = (noise.get([(x + lx) as f64 / SCALE, (z + lz) as f64 /SCALE]) + 1.0) / 2.0; + let mut h = (value * 30.0) as usize + 1; + h += (rand.gen::() * 2.0) as usize; + if h > max { max = h; } + map[lx][lz] = h; + } + } + (map, max) + } /* * Generate world */ pub fn generate(&mut self, level: &mut dyn Level, noise: &Perlin) { - - const SCALE: f64 = 150.0; let mut rng = rand::thread_rng(); + let mut dirty: Vec = Vec::new(); - - for bx in 0..16 { - for bz in 0..16 { - - for x in 0..BLOCK_SIZE { - for z in 0..BLOCK_SIZE { - // world x,z - let wx = bx * BLOCK_SIZE + x; - let wz = bz * BLOCK_SIZE + z; - // world h - let value1 = (noise.get([wx as f64 /SCALE*2.0, wz as f64 /SCALE*2.0]) + 1.0) / 1.5 - 0.6; - let value2 = (noise.get([wx as f64 /SCALE, wz as f64 /SCALE]) + 1.0) / 2.0; - let value = if value1 > value2 { value1 } else {value2}; - - let mut wh = (value * 40.0) as usize + 1; - wh += (rng.gen::() * 2.0) as usize; - - // fill column - for wy in 0..wh { - let y = wy % BLOCK_SIZE; - let by = wy / BLOCK_SIZE; - let val = if wy == wh-1 { 2 } else { 1 }; - - level.block_get(Point3{x:bx, y:by, z:bz}).set(Point3{x, y, z}, val); + for bx in 0..48 { + for bz in 0..48 { + // Generate height map + let (map, max) = WorldGen::gen_height_map(bx, bz, &mut rng, noise); + let bh = max % BLOCK_SIZE; + // Generate blocks + for by in 0..bh { + // Get + let b = level.block_get(Point3{x:bx, y:by, z:bz}); + dirty.push(b.id); + // Fill + for x in 0..BLOCK_SIZE { + for z in 0..BLOCK_SIZE { + // TODO + let h = map[x][z]; + for y in 0..h { + let val = if y+1 == h { 2 } else { 1 }; + b.set(Point3{x, y, z}, val); + } } } } + } } - - // let mut rng = rand::thread_rng(); - // let mut apply = false; - - - // let voxel_pos = pos * BLOCK_SIZE; - - // // Genereate grass - // if pos.y < 1 { - // for x in 0..32 { - // for z in 0..32 { - // let wx = voxel_pos.x + x; - // let wz = voxel_pos.z + z; - - // let value = (noise.get([wx as f64 * 0.0123, wz as f64 * 0.0123]) + 1.0) / 2.0; - // let h = (value * 30.0) as usize + 1; - - // for y in 0..h { - // renderer.block_set_voxel(block_id, x, y, z, 2); - // } - // } - // } - // apply = true; - // } - - // // Generate wall - // if pos.x == 8 && pos.y < 3 && pos.z < 8 && pos.z > 4 { - // for z in 0..32 { - // for y in 0..32 { - // renderer.block_set_voxel(block_id, 16, y, z, 3); - // } - // } - // apply = true; - // } - - // // Apply - // if apply { - // if block_id != renderer.block_get_id(pos, true) { - // panic!("Block already consumed?"); - // } - // } + for id in dirty { + level.block_dirty(id); + } } } \ No newline at end of file diff --git a/src/renderer/buffers/blocks.rs b/src/renderer/buffers/blocks.rs index 5a6cbe2..1e3ed60 100644 --- a/src/renderer/buffers/blocks.rs +++ b/src/renderer/buffers/blocks.rs @@ -99,7 +99,9 @@ impl Blocks { } pub fn write_id(&mut self, queue: &wgpu::Queue, block_id: usize) { - let block = self.get(block_id).unwrap(); + + // Get block from id + let block = &self.blocks[block_id]; // Calculate block position in texture let y = (block.id%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; @@ -117,6 +119,10 @@ impl Blocks { ); } + pub fn get(&mut self, block_id: usize) -> &mut Block { + &mut self.blocks[block_id] + } + // /* // Write block data to gpu, should be called to apply changes // */ @@ -147,16 +153,4 @@ impl Blocks { self.free_block += 1; &mut self.blocks[self.free_block - 1] } - - /* - * Gets block with id - */ - pub fn get(&mut self, id: usize) -> Option<&mut Block> { - for b in self.blocks.iter_mut() { - if b.id == id { - return Some(b); - } - } - None - } } \ No newline at end of file diff --git a/src/renderer/buffers/mod.rs b/src/renderer/buffers/mod.rs index 67716a9..115566f 100644 --- a/src/renderer/buffers/mod.rs +++ b/src/renderer/buffers/mod.rs @@ -8,7 +8,7 @@ pub const NODE_TEX_SIZE: usize = 48; // 32x32x32 nodes in texture pub const NODE_TEX_LEN: usize = NODE_TEX_SIZE*NODE_TEX_SIZE*NODE_TEX_SIZE; // Number of u32 in node texture pub const BLOCK_LEN : usize = BLOCK_SIZE*BLOCK_SIZE*BLOCK_SIZE; // Number of u8 in one block -pub const BLOCK_ARR_LEN: usize = BLOCK_TEX_SIZE*BLOCK_TEX_SIZE; // Number of blocks in texture +pub const BLOCK_ARR_LEN: usize = NODE_TEX_SIZE*NODE_TEX_SIZE; // Number of blocks in texture pub const BLOCK_TEX_LEN: usize = BLOCK_TEX_SIZE*BLOCK_TEX_SIZE * BLOCK_LEN; // Number of u8 in block texture diff --git a/src/renderer/level.rs b/src/renderer/level.rs index 82225ce..9629f8f 100644 --- a/src/renderer/level.rs +++ b/src/renderer/level.rs @@ -4,7 +4,7 @@ use crate::renderer::{Renderer, buffers}; pub trait Level { fn block_get(&mut self, block_pos: Point3) -> &mut buffers::Block; - fn block_dirty(&mut self, block: &buffers::Block); + fn block_dirty(&mut self, id: usize); } impl Level for Renderer { @@ -17,15 +17,17 @@ impl Level for Renderer { // Allocate new block if node_value == 0 { let block = self.buffers.brick_buffer.alloc(); - self.buffers.node_buffer.nodes[node_idx] = block.id as u32; + self.buffers.node_buffer.nodes[node_idx] = (block.id+1) as u32; return block; } // Return existing block - self.buffers.brick_buffer.get(node_idx).unwrap() + self.buffers.brick_buffer.get((node_value-1) as usize) } - fn block_dirty(&mut self, block: &buffers::Block) { - self.changed_bricks.push(block.id); + fn block_dirty(&mut self, id: usize) { + if !self.changed_bricks.contains(&id) { + self.changed_bricks.push(id); + } } } \ No newline at end of file diff --git a/src/shaders/raytrace/.bin/main.frag.spv b/src/shaders/raytrace/.bin/main.frag.spv index 35ac2decfb18e58c7a8218f51f00ad5c6b110249..412d9d83bf1b264ba4dab5b88e4f5ce332177156 100644 GIT binary patch delta 2122 zcmZ9NO>C4^6o&7#WlE8$l#0~~S}6u}kjhY@9;p^Ra=QD>iP-tW8{)xG^qdVKn~BkN?n^h#;cR^UZh3K%1NUzVA8r+;h*p=bH}? zUOiaq?i%e4p%9jZQkZ$Cw5w2i|C!yz>X||ahvyF*YR)f&C7~yrlQ-v^heF8sPdD)k z@aN}VoSRP+bR@ltta~4?s;x0^4Fvg!mBeILoxJ$zJaSfmD|c3 zvIstlW*oWex(I#rlX4~6Z-H0PW1Q9LK>tuOg8FoId@8QG7v6Yts2=%R_{CE%)Z?mA zxNG#&Ho|Tjn9aalYdQB|YBA0O@DM(GO#d>NWcA;9-C<0JkyG1Uumv~{?_rJswrQU} zx!nMdfV-j3GTcyJOBegsCx+h0_?Y;ou})$&tp{`cb*e1i1UDu188p{D#Bkl#j&+-J zJ+7<3%~btZ9%~EOc-WFG*faqiM%csbF=7&1!Rj&C1X#_Z#b8yi0kutWNb9IptY_?V8+HI@Ioo%bgXW_P$ zoa<~2j(t!_EU6{?mSA5oY@9~kMBjmTV2k68-1mEQ{k3~-uKxl2DWieUDEvpTe(F~1 z3uZO_wVwy0C7IEBDd=de?9wVp4CDAScmuOO+VrvB>YO4w%`afJas1rCp86H8{vJLb z!G8m*`QR@R;}38M>qEH00*${j6#oug88*0Aw1{>l9jJ^IJwrXDk5|^N(r`%w<4ZdPoH{^|v^in|6cM{0zR9Ydv6tX>)U*pjzCh2v#$h31alZ_b@jZlObt8 zhoy)b;&bQ&yHMSrzGF3m`W#ANHEq6Ox!CvXH#xqBTfx2teYELg52$CAPcW{4D0Y^9 z0InXN!%DDPd=9sP{qr?w8)T^Y8pQGRtH54Itl;f%wcV^WnHi0WmsuDCIL81(V12G( z7rTMaF5c~M`tJB(au=3i#&L@5r+5umZ8hUquH6k*ckAVN>30vDVA5N`a-o;9^b{rt_di#X;6VTY delta 2083 zcmZ9N&u>&!6vyvOr&EelkQypzbp#P)fXcMOjMx?ei7~`K|tj5dGjs|eaX%Je!u73bI-Z&-1lxB z`t(pwM}9?D2)Qsn^n{V=o*lXBCws<0HhdwFB3aX5sO|2T*L z0pC0M#^h9HzZ~t&OT|se4cLK$$Lo{FT-_P+`4EmBXzZIjxwCO9ThVn_YwgetZ{P8O z`*=rK0zYxI<@>a2Cnok0Dve)-zczN___kI?vol>E<#N^8m%HC9Bt?9_BOjg1R5p+K zfB4DI%N4oyd91H6uZ49pFNN=7ev#oE*Y%_Ct__Vu{y4n;PTy$cPr$Ft>>rJBO8Jlk z7wM?6#D*)G(@hDyIpY?j76Yw}#Y?luLH^2+b(LSVo%Lm&_ zp|21&K|0{CGTcyJZ7yB7Dlzmkj5EYPi**>Q=d&i$-{N%TWw{uwyj&A z>2civ+*H+1XR)3I8xLEO2HQe_3c~Bm))A8!1gpnj&w)XpzAr`MM!RQ{P`@k&KcBYUMHZ)$7f+PzNE?(B7nd>p=H zcEiA#Tz5U|_>0XCSN0`e6X+|(MTW1zBm4&Z1*6Upu7H0F)=%B)&ois(ul)zGnl{Uq zi!I%ISYyX!`27T4&8&|$e3Ib#X|T!6_Ghr#5ZDd8Bfr4aKgQ=X_^)6!8~7R<{SNlI zfxouj7;4u;KE=lN?EgeF_9(bjEb0G+puvp&rpe=izrp95{gr{D%P!=aJ1ff*v%ChK zo8@&hbp!b>pwqAUheQ4f|do4#J zpsBx4g??+7fz|v6ozApJ!RjWm;1%3-d<=nD>Gw^C_`@<&f0o)!Oy4KLYO%8A;1WaK JWaU+&-2p;O;e!AG diff --git a/src/shaders/raytrace/main.frag b/src/shaders/raytrace/main.frag index a296136..007b93e 100644 --- a/src/shaders/raytrace/main.frag +++ b/src/shaders/raytrace/main.frag @@ -62,7 +62,7 @@ vec3 solve() // Calculate ray direction vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz; vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz; - Ray primaryRay = Ray(_CamPos / SCALE, rayDir); + Ray primaryRay = Ray((_CamPos + vec3(16, 0, 16)) / SCALE, rayDir); // Raycast HitResult primary = castNodes(primaryRay, 100);