From c5bcd148ca95006194c2d80ea7b4b534892def4c Mon Sep 17 00:00:00 2001 From: zomseffen Date: Mon, 9 Sep 2024 19:23:09 +0200 Subject: [PATCH] pre double pipeline commit. The following will attempt to add another rendering stage for textured cuboids. --- build.rs | 41 +++ shaders/compile.bat | 10 +- shaders/{shader.frag => cube.frag} | 0 shaders/{shader.geom => cube.geom} | 0 shaders/{shader.vert => cube.vert} | 0 shaders/cuboid.frag | 11 + shaders/cuboid.geom | 181 ++++++++++++ shaders/cuboid.vert | 30 ++ shaders/{frag.spv => frag_cube.spv} | Bin shaders/frag_cuboid.spv | Bin 0 -> 796 bytes shaders/{geo.spv => geo_cube.spv} | Bin shaders/geo_cuboid.spv | Bin 0 -> 16684 bytes shaders/{vert.spv => vert_cube.spv} | Bin shaders/vert_cuboid.spv | Bin 0 -> 2656 bytes src/main.rs | 6 +- src/primitives.rs | 1 - src/primitives/cube.rs | 5 +- src/primitives/drawable.rs | 6 + src/primitives/mod.rs | 3 + src/primitives/rec_cuboid.rs | 133 +++++++++ src/scene.rs | 409 +++++++++++++++++++++++++--- src/vertex.rs | 71 +++++ 22 files changed, 854 insertions(+), 53 deletions(-) create mode 100644 build.rs rename shaders/{shader.frag => cube.frag} (100%) rename shaders/{shader.geom => cube.geom} (100%) rename shaders/{shader.vert => cube.vert} (100%) create mode 100644 shaders/cuboid.frag create mode 100644 shaders/cuboid.geom create mode 100644 shaders/cuboid.vert rename shaders/{frag.spv => frag_cube.spv} (100%) create mode 100644 shaders/frag_cuboid.spv rename shaders/{geo.spv => geo_cube.spv} (100%) create mode 100644 shaders/geo_cuboid.spv rename shaders/{vert.spv => vert_cube.spv} (100%) create mode 100644 shaders/vert_cuboid.spv delete mode 100644 src/primitives.rs create mode 100644 src/primitives/drawable.rs create mode 100644 src/primitives/mod.rs create mode 100644 src/primitives/rec_cuboid.rs diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..413ecb6 --- /dev/null +++ b/build.rs @@ -0,0 +1,41 @@ +use std::process::Command; +use std::io::{self, Write}; +use std::path::Path; + +fn main() { + println!("cargo::rerun-if-changed=shaders/cube.frag"); + println!("cargo::rerun-if-changed=shaders/cube.geom"); + println!("cargo::rerun-if-changed=shaders/cube.vert"); + println!("cargo::rerun-if-changed=shaders/geo_cube.spv"); + println!("cargo::rerun-if-changed=shaders/frag_cube.spv"); + println!("cargo::rerun-if-changed=shaders/vert_cube.spv"); + + println!("cargo::rerun-if-changed=shaders/cuboid.frag"); + println!("cargo::rerun-if-changed=shaders/cuboid.geom"); + println!("cargo::rerun-if-changed=shaders/cuboid.vert"); + println!("cargo::rerun-if-changed=shaders/geo_cuboid.spv"); + println!("cargo::rerun-if-changed=shaders/frag_cuboid.spv"); + println!("cargo::rerun-if-changed=shaders/vert_cuboid.spv"); + + std::fs::remove_file("shaders/geo_cube.spv"); + std::fs::remove_file("shaders/frag_cube.spv"); + std::fs::remove_file("shaders/vert_cube.spv"); + std::fs::remove_file("shaders/geo_cuboid.spv"); + std::fs::remove_file("shaders/frag_cuboid.spv"); + std::fs::remove_file("shaders/vert_cuboid.spv"); + // probably need to check the os and have different versions + let mut command = Command::new("./shaders/compile.bat"); + let output = command.output().expect("Failed to execute command"); + println!("status: {}", output.status); + io::stdout().write_all(&output.stdout).unwrap(); + io::stderr().write_all(&output.stderr).unwrap(); + + assert!(output.status.success()); + + assert!(Path::new("shaders/geo_cube.spv").exists()); + assert!(Path::new("shaders/frag_cube.spv").exists()); + assert!(Path::new("shaders/vert_cube.spv").exists()); + assert!(Path::new("shaders/geo_cuboid.spv").exists()); + assert!(Path::new("shaders/frag_cuboid.spv").exists()); + assert!(Path::new("shaders/vert_cuboid.spv").exists()); +} \ No newline at end of file diff --git a/shaders/compile.bat b/shaders/compile.bat index 39e1fb0..27ac9c4 100644 --- a/shaders/compile.bat +++ b/shaders/compile.bat @@ -1,3 +1,7 @@ -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.vert -o shaders/vert.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.frag -o shaders/frag.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/shader.geom -o shaders/geo.spv \ No newline at end of file +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.vert -o shaders/vert_cube.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.frag -o shaders/frag_cube.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.geom -o shaders/geo_cube.spv + +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.vert -o shaders/vert_cuboid.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.frag -o shaders/frag_cuboid.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/geo_cuboid.spv \ No newline at end of file diff --git a/shaders/shader.frag b/shaders/cube.frag similarity index 100% rename from shaders/shader.frag rename to shaders/cube.frag diff --git a/shaders/shader.geom b/shaders/cube.geom similarity index 100% rename from shaders/shader.geom rename to shaders/cube.geom diff --git a/shaders/shader.vert b/shaders/cube.vert similarity index 100% rename from shaders/shader.vert rename to shaders/cube.vert diff --git a/shaders/cuboid.frag b/shaders/cuboid.frag new file mode 100644 index 0000000..f53c648 --- /dev/null +++ b/shaders/cuboid.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 fragColor; +layout(location = 1) in vec2 fragTexCoord; + +layout(location = 0) out vec4 outColor; +layout(binding = 1) uniform sampler2D texSampler; + +void main() { + outColor = vec4(fragColor, 1); //texture(texSampler, fragTexCoord); +} \ No newline at end of file diff --git a/shaders/cuboid.geom b/shaders/cuboid.geom new file mode 100644 index 0000000..6419b62 --- /dev/null +++ b/shaders/cuboid.geom @@ -0,0 +1,181 @@ +#version 450 + +layout(points) in; +layout(triangle_strip, max_vertices=12) out; + +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; + bool[16] use_geom_shader; +} ubo; + +layout(location = 0) in vec3 geoColor[]; +layout(location = 1) in vec2 geoTexCoord[]; +layout(location = 2) in vec3 geoSize[]; + +layout(location = 0) out vec3 fragColor; +layout(location = 1) out vec2 fragTexCoord; + +bool ignore_scalars = false; + +void main () { + mat4 geom_rotation = ubo.geom_rot; + //back + vec4 normal_back = geom_rotation * vec4(0, 0, -1, 0); + float scalar_back = dot(normal_back, vec4(1, 0, 0, 0)); + + if (scalar_back <= 0 || ignore_scalars){ + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } + + //front + vec4 normal_front = geom_rotation * vec4(0, 0, 1, 0); + float scalar_front = dot(normal_front, vec4(1, 0, 0, 0)); + if (scalar_front <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } + //up + vec4 normal_up = geom_rotation * vec4(0, 1, 0, 0); + float scalar_up = dot(normal_up, vec4(1, 0, 0, 0)); + + if (scalar_up <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } + //down + vec4 normal_down = geom_rotation * vec4(0, -1, 0, 0); + float scalar_down = dot(normal_down, vec4(1, 0, 0, 0)); + + if (scalar_down <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } + //left + vec4 normal_left = geom_rotation * vec4(-1, 0, 0, 0); + float scalar_left = dot(normal_left, vec4(1, 0, 0, 0)); + + if (scalar_left <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } + //right + vec4 normal_right = geom_rotation * vec4(1, 0, 0, 0); + float scalar_right = dot(normal_right, vec4(1, 0, 0, 0)); + + if (scalar_right <= 0 || ignore_scalars) { + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, -geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + + gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(geoSize[0].x, geoSize[0].y, -geoSize[0].z, 0)); + fragColor = geoColor[0]; + fragTexCoord = geoTexCoord[0]; + EmitVertex(); + EndPrimitive(); + } +} \ No newline at end of file diff --git a/shaders/cuboid.vert b/shaders/cuboid.vert new file mode 100644 index 0000000..99c6ccf --- /dev/null +++ b/shaders/cuboid.vert @@ -0,0 +1,30 @@ +#version 450 + +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; + bool[16] use_geom_shader; +} ubo; + + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inColor; +layout(location = 2) in vec2 inTexCoord; +layout(location = 3) in vec3 inSize; + +layout(location = 0) out vec3 geoColor; +layout(location = 1) out vec2 geoTexCoord; +layout(location = 2) out vec3 geoSize; + +void main() { + if (ubo.use_geom_shader[0]) { + gl_Position = ubo.geom_rot * ubo.model * vec4(inPosition, 1.0); + } else { + gl_Position = ubo.proj * ubo.view * ubo.geom_rot * ubo.model * vec4(inPosition, 1.0); + } + geoColor = inColor; + geoTexCoord = inTexCoord; + geoSize = inSize; +} \ No newline at end of file diff --git a/shaders/frag.spv b/shaders/frag_cube.spv similarity index 100% rename from shaders/frag.spv rename to shaders/frag_cube.spv diff --git a/shaders/frag_cuboid.spv b/shaders/frag_cuboid.spv new file mode 100644 index 0000000000000000000000000000000000000000..1ebe14020d9b8fcd611df7ae9387f181d318fae3 GIT binary patch literal 796 zcmYk3OH0F05QWFq)cWW{>#GXV>QX2!R0L5MBH0wG)O{#zlt9{)HWl6Z+x%5-1kV=} z$%V<>bLQN6rC2ywF$5DyWM`bGml4|^NTYSRVyY!G&L*RvOG2( z1QPp z_x@l!4Si*BRe_m~5a@uJFOSIuW+%kSaV+CxxUDS+Q~*Nx$o*;64#RL={@@b zGh0jFvOHUdzfLhd!J%K1M-N87E>A6Z^k901I~7J-m6?6s@xGxO9DVVATOKVu@4?In z*VHz4<2OH kpR1=FJ!HDglq3J6w#WXqWV}aDoITvCD*Gh%qp7ZBzwPNg3jhEB literal 0 HcmV?d00001 diff --git a/shaders/geo.spv b/shaders/geo_cube.spv similarity index 100% rename from shaders/geo.spv rename to shaders/geo_cube.spv diff --git a/shaders/geo_cuboid.spv b/shaders/geo_cuboid.spv new file mode 100644 index 0000000000000000000000000000000000000000..8e45c97e3d0c86cdcb43847efce8e545b71cdf14 GIT binary patch literal 16684 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 literal 0 HcmV?d00001 diff --git a/shaders/vert.spv b/shaders/vert_cube.spv similarity index 100% rename from shaders/vert.spv rename to shaders/vert_cube.spv diff --git a/shaders/vert_cuboid.spv b/shaders/vert_cuboid.spv new file mode 100644 index 0000000000000000000000000000000000000000..e4f35031f142b9c04db55e28b96d2d349cfd3c48 GIT binary patch literal 2656 zcmZ9NYjYGu6o!W+n;@u&TvZGk;w6g48z726Lcm>hHHksLZiVawhuX}fW;cj_;xFjm z@K0F&DKAx4`8+ezYeT2b_Bn6A=hEl&!1UDOT#_70jwa6~cawS@Po_W;u-R(w^tO7- zqw!$*(&hJMJfBQgL^;RsbIl-o+gYwYk1Qcw3&-5^~++6I^kOH!z}$V#_Ym=Sv;t* zI-fNhjM9D;WAwxJAT7x@P0zsZ73j0cIrRI({zh7UpO)kFQSD#j>Yf#&Y@8K2?750x z)g_+gKXQT0UzLQSQtkJWB;c#+hJ=FL>I%<>x2&$+_6n?71AigHl-Ip-{&KwvY~+~HMaYx@SWyuL*T`zZD-@&eMu zb`Gu<(&abUixv7L#^Zg$&pyR|+WM^^A(q(Fe)cf-)7I}X68yxT_OrjSpSFI#Bf(GX zf4}-Zz7u&qxDNC1j>fkizLg7zE7%LQS;h4Ixa^zDJYwEU%spVn6tjkasf$^Ix%CaX zeGB1jnA>*{+kVg5=J4D%5ZlgQJH+#wk8NkKZ4D=2$y>nERzHpATWBL^h;QGtt@SLw zhuOunPx1QYmjrTv7LpOxsI{7kwb{N zw9R8J!9I@eGTw{q`kMbF+9~!><7sqPuwOrQ4aPRX z-f1xV5qR%5n7!Fx($0Dr(O)CsV`Q=!%Z{!2ScWKQx=!dqvzq!A?u@Ckm z-0>2+cl0fVK3ql@51fzD<@mk==PJ5*=)))I`iTd>Pto;@dwdOBJotTvuCI9TyN<43 z-1i&U;=%7Gy1q4D_k9IB?)xgXm@D-77WxVj_kFFw;=bPo(_g;lao_J?o4@ANeg7Og x?z^_UxbOBqypb=_{r;R$mtEU4zo!kvZ^<*iIql%Lh3 Result<()> { - let vert = include_bytes!("../shaders/vert.spv"); - let geo = include_bytes!("../shaders/geo.spv"); - let frag = include_bytes!("../shaders/frag.spv"); + let vert = include_bytes!("../shaders/vert_cube.spv"); + let geo = include_bytes!("../shaders/geo_cube.spv"); + let frag = include_bytes!("../shaders/frag_cube.spv"); let vert_shader_module = create_shader_module(device, &vert[..])?; let geo_shader_module = create_shader_module(device, &geo[..])?; diff --git a/src/primitives.rs b/src/primitives.rs deleted file mode 100644 index 887bbb1..0000000 --- a/src/primitives.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod cube; \ No newline at end of file diff --git a/src/primitives/cube.rs b/src/primitives/cube.rs index 53afd86..f7fba65 100644 --- a/src/primitives/cube.rs +++ b/src/primitives/cube.rs @@ -2,6 +2,7 @@ use vulkanalia::prelude::v1_0::*; use cgmath::vec3; use crate::vertex; use crate::scene::Scene; +use crate::primitives::drawable::Drawable; #[derive(Clone, Debug)] pub struct Cube{ @@ -10,8 +11,8 @@ pub struct Cube{ pub tex_coord: vertex::Vec2 } -impl Cube { - pub fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) { +impl Drawable for Cube { + fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) { if *topology == vk::PrimitiveTopology::TRIANGLE_LIST { // 0 top left far scene.vertices.push(vertex::Vertex::new( diff --git a/src/primitives/drawable.rs b/src/primitives/drawable.rs new file mode 100644 index 0000000..cb8cfae --- /dev/null +++ b/src/primitives/drawable.rs @@ -0,0 +1,6 @@ +use vulkanalia::prelude::v1_0::*; +use crate::scene::Scene; + +pub trait Drawable { + fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene); +} \ No newline at end of file diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs new file mode 100644 index 0000000..7b1f5d3 --- /dev/null +++ b/src/primitives/mod.rs @@ -0,0 +1,3 @@ +pub mod cube; +pub mod rec_cuboid; +pub mod drawable; \ No newline at end of file diff --git a/src/primitives/rec_cuboid.rs b/src/primitives/rec_cuboid.rs new file mode 100644 index 0000000..ffdd4e5 --- /dev/null +++ b/src/primitives/rec_cuboid.rs @@ -0,0 +1,133 @@ +use vulkanalia::prelude::v1_0::*; +use cgmath::vec3; +use crate::vertex; +use crate::scene::Scene; +use crate::primitives::drawable::Drawable; + +#[derive(Clone, Debug)] +pub struct Cuboid{ + pub pos: vertex::Vec3, + pub color: vertex::Vec3, + pub tex_coord: vertex::Vec2, + pub size: vertex::Vec3, +} + +impl Drawable for Cuboid { + fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) { + if *topology == vk::PrimitiveTopology::TRIANGLE_LIST { + // 0 top left far + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 - 0.5 * self.size.x, self.pos.y as f32 + 0.5 * self.size.y, self.pos.z as f32 + 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 1 top right far + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 + 0.5 * self.size.x, self.pos.y as f32 + 0.5 * self.size.y, self.pos.z as f32 + 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 2 top left near + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 - 0.5 * self.size.x, self.pos.y as f32 - 0.5 * self.size.y, self.pos.z as f32 + 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 3 top right near + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 + 0.5 * self.size.x, self.pos.y as f32 - 0.5 * self.size.y, self.pos.z as f32 + 0.5 * self.size.z), + self.color, + self.tex_coord + )); + + // 4 bottom left far + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 - 0.5 * self.size.x, self.pos.y as f32 + 0.5 * self.size.y, self.pos.z as f32 - 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 5 bottom right far + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 + 0.5 * self.size.x, self.pos.y as f32 + 0.5 * self.size.y, self.pos.z as f32 - 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 6 bottom left near + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 - 0.5 * self.size.x, self.pos.y as f32 - 0.5 * self.size.y, self.pos.z as f32 - 0.5 * self.size.z), + self.color, + self.tex_coord + )); + // 7 bottom right near + scene.vertices.push(vertex::Vertex::new( + vec3(self.pos.x as f32 + 0.5 * self.size.x, self.pos.y as f32 - 0.5 * self.size.y, self.pos.z as f32 - 0.5 * self.size.z), + self.color, + self.tex_coord + )); + + + // top + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 0); + scene.indices.push(start_index as u32 + 2); + + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 1); + scene.indices.push(start_index as u32 + 0); + + // bottom + scene.indices.push(start_index as u32 + 6); + scene.indices.push(start_index as u32 + 4); + scene.indices.push(start_index as u32 + 7); + + scene.indices.push(start_index as u32 + 4); + scene.indices.push(start_index as u32 + 5); + scene.indices.push(start_index as u32 + 7); + + // left + scene.indices.push(start_index as u32 + 0); + scene.indices.push(start_index as u32 + 4); + scene.indices.push(start_index as u32 + 2); + + scene.indices.push(start_index as u32 + 6); + scene.indices.push(start_index as u32 + 2); + scene.indices.push(start_index as u32 + 4); + + // right + scene.indices.push(start_index as u32 + 1); + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 5); + + scene.indices.push(start_index as u32 + 5); + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 7); + + // near + scene.indices.push(start_index as u32 + 6); + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 2); + + scene.indices.push(start_index as u32 + 3); + scene.indices.push(start_index as u32 + 6); + scene.indices.push(start_index as u32 + 7); + + // far + scene.indices.push(start_index as u32 + 0); + scene.indices.push(start_index as u32 + 1); + scene.indices.push(start_index as u32 + 4); + + scene.indices.push(start_index as u32 + 5); + scene.indices.push(start_index as u32 + 4); + scene.indices.push(start_index as u32 + 1); + } + if *topology == vk::PrimitiveTopology::POINT_LIST { + scene.sized_vertices.push(vertex::SizedVertex::new( + self.pos, + self.color, + self.tex_coord, + self.size, + )); + scene.indices.push(start_index as u32); + } + } +} \ No newline at end of file diff --git a/src/scene.rs b/src/scene.rs index d77c898..032e299 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -1,24 +1,33 @@ +use anyhow::Ok; use vulkanalia::prelude::v1_0::*; use anyhow::Result; -use cgmath::{vec2, vec3}; +use cgmath::{vec2, vec3, Vector3}; +use std::cell::RefCell; use std::collections::HashMap; +use std::rc::Rc; use rustc_hash::FxHashMap; use crate::app_data::AppData; use crate::buffer; +use crate::primitives::rec_cuboid::Cuboid; use crate::vertex; use crate::primitives::cube::Cube; +use crate::primitives::drawable::Drawable; extern crate rand; use rand::Rng; -const CHUNK_SIZE: usize = 500; +const CHUNK_SIZE_EXPONENT: u32 = 10; +const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT); +const MAX_TREE_DEPTH: usize = 8; +const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32); #[derive(Clone, Debug, Default)] pub struct Scene { pub vertices: Vec, + pub sized_vertices: Vec, pub indices: Vec, pub vertex_buffer: vk::Buffer, @@ -34,7 +43,7 @@ impl Scene { let grid_size = CHUNK_SIZE as i32; // todo store the chunks somewhere (or only use them as intermediary for neighbouthood calculation idc) - let mut chunks = vec![Chunk::create()?]; + let mut oct_tree = OctTree::create(CHUNK_SIZE)?; //todo use the 14 vertice box method. Not using geometry shaders seems to be faster... make this a setting? // have cube elements with a method asking for vertices, while giving a primitive type -> method for preferred primitive type as well as one collecting all primitives @@ -46,17 +55,25 @@ impl Scene { color: vec3(shade, 1.0, shade), tex_coord: vec2(0.0, 0.0) }; - chunks[0].set_cube(cube); + + oct_tree.set_cube(cube.clone()); } } - let chunk = &chunks[0]; - let chunk_iter = ChunkIter::create(chunk)?; - for item in chunk_iter { + let oct_tree_iter = OctTreeIter::create(&oct_tree)?; + for item in oct_tree_iter { let index = self.vertices.len(); match item { Some(cube) => { + /*let cuboid = Cuboid { + pos: cube.pos, + color: cube.color, + tex_coord: cube.tex_coord, + size: Vector3 {x: 1.0, y: 1.0, z: 1.0}, + }; + cuboid.draw(&data.topology, index, self);*/ cube.draw(&data.topology, index, self); + } None => {} } @@ -79,16 +96,47 @@ impl Scene { } #[derive(Clone, Debug)] -struct Chunk { - //todo change to hashmap? - blocks: HashMap, Cube, rustc_hash::FxBuildHasher>, +struct OctTree { + pub child_XYZ: Option>>, + pub child_xYZ: Option>>, + pub child_xyZ: Option>>, + pub child_XyZ: Option>>, + pub child_XYz: Option>>, + pub child_xYz: Option>>, + pub child_xyz: Option>>, + pub child_Xyz: Option>>, + + pub blocks: Vec>, + + size: usize, } -impl Chunk { - pub fn create() -> Result { - let mut map: HashMap, Cube, rustc_hash::FxBuildHasher> = FxHashMap::default(); +impl OctTree { + pub fn create(size: usize) -> Result { + let mut blocks: Vec> = vec![]; + if size == MIN_CHUNK_SIZE { + for _ in 0..MIN_CHUNK_SIZE { + for _ in 0..MIN_CHUNK_SIZE { + for _ in 0..MIN_CHUNK_SIZE { + blocks.push(None); + } + } + } + } + Ok(Self { - blocks: map + child_XYZ: None, + child_xYZ: None, + child_xyZ: None, + child_XyZ: None, + child_XYz: None, + child_xYz: None, + child_xyz: None, + child_Xyz: None, + + blocks: blocks, + + size, }) } @@ -96,62 +144,335 @@ impl Chunk { let x = cube.pos.x as usize; let y = cube.pos.y as usize; let z = cube.pos.z as usize; - assert!(x < CHUNK_SIZE, "x value out of range!"); - assert!(y < CHUNK_SIZE, "y value out of range!"); - assert!(z < CHUNK_SIZE, "z value out of range!"); - self.blocks.insert(vec3(x as u32, y as u32, z as u32), cube); + assert!(x < self.size, "x value out of range!"); + assert!(y < self.size, "y value out of range!"); + assert!(z < self.size, "z value out of range!"); + self.set_cube_internal(cube, x, y, z); + } + + fn set_cube_internal(&mut self, cube: Cube, x: usize, y: usize, z: usize) { + if self.size > MIN_CHUNK_SIZE { + let mid_point = self.size / 2; + if x >= mid_point { + if y >= mid_point { + if z >= mid_point { + match &self.child_XYZ { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x - mid_point, y - mid_point, z - mid_point); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x - mid_point, y - mid_point, z - mid_point); + self.child_XYZ = Some(Rc::new(RefCell::new(child))); + } + } + } + else { + match &self.child_XYz { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x - mid_point, y - mid_point, z); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x - mid_point, y - mid_point, z); + self.child_XYz = Some(Rc::new(RefCell::new(child))); + } + } + } + } + else { + if z >= mid_point { + match &self.child_XyZ { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x - mid_point, y, z - mid_point); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x - mid_point, y, z - mid_point); + self.child_XyZ = Some(Rc::new(RefCell::new(child))); + } + } + } + else { + match &self.child_Xyz { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x - mid_point, y, z); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x - mid_point, y, z); + self.child_Xyz = Some(Rc::new(RefCell::new(child))); + } + } + } + } + } + else { + if y >= mid_point { + if z >= mid_point { + match &self.child_xYZ { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x, y - mid_point, z - mid_point); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x, y - mid_point, z - mid_point); + self.child_xYZ = Some(Rc::new(RefCell::new(child))); + } + } + } + else { + match &self.child_xYz { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x, y - mid_point, z); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x, y - mid_point, z); + self.child_xYz = Some(Rc::new(RefCell::new(child))); + } + } + } + } + else { + if z >= mid_point { + match &self.child_xyZ { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x, y, z - mid_point); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x, y, z - mid_point); + self.child_xyZ = Some(Rc::new(RefCell::new(child))); + } + } + } + else { + match &self.child_xyz { + Some(child) => { + child.borrow_mut().set_cube_internal(cube, x, y, z); + }, + None => { + let mut child = OctTree::create(self.size / 2).unwrap(); + child.set_cube_internal(cube, x, y, z); + self.child_xyz = Some(Rc::new(RefCell::new(child))); + } + } + } + } + } + } + else { + self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] = Some(cube); + } } pub fn clear_cube(&mut self, x: usize, y: usize, z: usize) { - assert!(x < CHUNK_SIZE, "x value out of range!"); - assert!(y < CHUNK_SIZE, "y value out of range!"); - assert!(z < CHUNK_SIZE, "z value out of range!"); - self.blocks.remove(&vec3(x as u32, y as u32, z as u32)); + assert!(x < self.size, "x value out of range!"); + assert!(y < self.size, "y value out of range!"); + assert!(z < self.size, "z value out of range!"); + //self.blocks.remove(&vec3(x as u32, y as u32, z as u32)); + + self.clear_cube_internal(x, y, z) } + fn clear_cube_internal(&mut self, x: usize, y: usize, z: usize) { + if self.size > MIN_CHUNK_SIZE { + let mid_point = self.size / 2; + if x >= mid_point { + if y >= mid_point { + if z >= mid_point { + match &self.child_XYZ { + Some(child) => { + child.borrow_mut().clear_cube_internal(x - mid_point, y - mid_point, z - mid_point); + }, + None => {} + } + } + else { + match &self.child_XYz { + Some(child) => { + child.borrow_mut().clear_cube_internal(x - mid_point, y - mid_point, z); + }, + None => {} + } + } + } + else { + if z >= mid_point { + match &self.child_XyZ { + Some(child) => { + child.borrow_mut().clear_cube_internal(x - mid_point, y, z - mid_point); + }, + None => {} + } + } + else { + match &self.child_Xyz { + Some(child) => { + child.borrow_mut().clear_cube_internal(x - mid_point, y, z); + }, + None => {} + } + } + } + } + else { + if y >= mid_point { + if z >= mid_point { + match &self.child_xYZ { + Some(child) => { + child.borrow_mut().clear_cube_internal(x, y - mid_point, z - mid_point); + }, + None => {} + } + } + else { + match &self.child_xYz { + Some(child) => { + child.borrow_mut().clear_cube_internal(x, y - mid_point, z); + }, + None => {} + } + } + } + else { + if z >= mid_point { + match &self.child_xyZ { + Some(child) => { + child.borrow_mut().clear_cube_internal(x, y, z - mid_point); + }, + None => {} + } + } + else { + match &self.child_xyz { + Some(child) => { + child.borrow_mut().clear_cube_internal(x, y, z); + }, + None => {} + } + } + } + } + } + else { + self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] = None; + } + } } -struct ChunkIter<'a> { +struct OctTreeIter<'a> { iter_x: usize, iter_y: usize, iter_z: usize, - chunk: &'a Chunk + todo: Vec>>, + chunk: &'a OctTree } -impl<'a> ChunkIter<'a> { - pub fn create(chunk: &'a Chunk) -> Result { - - Ok(Self { +impl<'a> OctTreeIter<'a> { + pub fn create(chunk: &'a OctTree) -> Result { + let mut out = Self { iter_x: 0, iter_y: 0, iter_z: 0, + todo: vec![], chunk - }) + }; + out.add_todo(&chunk); + Ok(out) + } + + fn add_todo(&mut self, oct_tree: &OctTree) { + match &oct_tree.child_XYZ { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_xYZ { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_xyZ { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_XyZ { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_XYz { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_xYz { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_xyz { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; + match &oct_tree.child_Xyz { + Some(child) => { + self.todo.push(child.clone()); + }, + None => {}, + }; } } -impl<'a> Iterator for ChunkIter<'a> { - type Item = Option<&'a Cube>; +impl<'a> Iterator for OctTreeIter<'a> { + type Item = Option; fn next(&mut self) -> Option { - if self.iter_x < CHUNK_SIZE && self.iter_y < CHUNK_SIZE && self.iter_z < CHUNK_SIZE { - let result = self.chunk.blocks.get(&vec3(self.iter_x as u32, self.iter_y as u32, self.iter_z as u32)); + if self.todo.len() != 0 { + while self.todo.last().unwrap().borrow().blocks.len() == 0 { + let oct_tree = self.todo.pop().unwrap(); + self.add_todo(&oct_tree.borrow()); + } - self.iter_x += 1; - if self.iter_x >= CHUNK_SIZE { - self.iter_x = 0; - self.iter_y += 1; + if self.iter_x < MIN_CHUNK_SIZE && self.iter_y < MIN_CHUNK_SIZE && self.iter_z < MIN_CHUNK_SIZE { + let result = self.todo.last().unwrap().borrow().blocks[self.iter_x + self.iter_y * MIN_CHUNK_SIZE + self.iter_z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE].clone(); + + self.iter_x += 1; + if self.iter_x >= MIN_CHUNK_SIZE { + self.iter_x = 0; + self.iter_y += 1; + } + if self.iter_y >= MIN_CHUNK_SIZE { + self.iter_y = 0; + self.iter_z += 1; + } + + if self.iter_z == MIN_CHUNK_SIZE { + self.todo.pop(); + self.iter_x = 0; + self.iter_y = 0; + self.iter_z = 0; + } + + return Some(result) } - if self.iter_y >= CHUNK_SIZE { - self.iter_y = 0; - self.iter_z += 1; - } - return Some(result.clone()) } + self.iter_x = 0; self.iter_y = 0; self.iter_z = 0; + self.add_todo(&self.chunk); None } -} - +} \ No newline at end of file diff --git a/src/vertex.rs b/src/vertex.rs index 78c8465..6be4883 100644 --- a/src/vertex.rs +++ b/src/vertex.rs @@ -76,4 +76,75 @@ impl Hash for Vertex { self.tex_coord[0].to_bits().hash(state); self.tex_coord[1].to_bits().hash(state); } +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct SizedVertex { + pub pos: Vec3, + pub color: Vec3, + pub tex_coord: Vec2, + pub size: Vec3, +} + +impl SizedVertex { + pub const fn new(pos: Vec3, color: Vec3, tex_coord: Vec2, size: Vec3) -> Self { + Self { pos, color, tex_coord, size } + } + + pub fn binding_description() -> vk::VertexInputBindingDescription { + vk::VertexInputBindingDescription::builder() + .binding(0) + .stride(size_of::() as u32) + .input_rate(vk::VertexInputRate::VERTEX) + .build() + } + + pub fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] { + let pos = vk::VertexInputAttributeDescription::builder() + .binding(0) + .location(0) + .format(vk::Format::R32G32B32_SFLOAT) + .offset(0) + .build(); + + let color = vk::VertexInputAttributeDescription::builder() + .binding(0) + .location(1) + .format(vk::Format::R32G32B32_SFLOAT) + .offset(size_of::() as u32) + .build(); + + let tex_coord = vk::VertexInputAttributeDescription::builder() + .binding(0) + .location(2) + .format(vk::Format::R32G32_SFLOAT) + .offset((size_of::() + size_of::()) as u32) + .build(); + [pos, color, tex_coord] + } +} + + +impl PartialEq for SizedVertex { + fn eq(&self, other: &Self) -> bool { + self.pos == other.pos + && self.color == other.color + && self.tex_coord == other.tex_coord + } +} + +impl Eq for SizedVertex {} + +impl Hash for SizedVertex { + fn hash(&self, state: &mut H) { + self.pos[0].to_bits().hash(state); + self.pos[1].to_bits().hash(state); + self.pos[2].to_bits().hash(state); + self.color[0].to_bits().hash(state); + self.color[1].to_bits().hash(state); + self.color[2].to_bits().hash(state); + self.tex_coord[0].to_bits().hash(state); + self.tex_coord[1].to_bits().hash(state); + } } \ No newline at end of file