1M vertices 30 fps geom shader

This commit is contained in:
zomseffen 2024-05-18 10:52:47 +02:00
parent 9ad743cfa2
commit 0b3be29525
5 changed files with 188 additions and 114 deletions

9
Cargo.lock generated
View file

@ -961,18 +961,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
dependencies = [
"proc-macro2",
"quote",
@ -1181,6 +1181,7 @@ dependencies = [
"log",
"png",
"pretty_env_logger",
"serde",
"thiserror",
"tobj",
"vulkanalia",

View file

@ -14,4 +14,5 @@ pretty_env_logger = "0.5"
thiserror = "1"
tobj = { version = "3", features = ["log"] }
vulkanalia = { version = "=0.23.0", features = ["libloading", "provisional", "window"] }
winit = "0.29"
winit = "0.29"
serde = { version = "1.0", features = ["derive"] }

Binary file not shown.

View file

@ -1,7 +1,7 @@
#version 450
layout(points) in;
layout(triangle_strip, max_vertices=24) out;
layout(triangle_strip, max_vertices=12) out;
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
@ -16,137 +16,164 @@ layout(location = 1) in vec2 geoTexCoord[];
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
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
vec4 normal_back = geom_rotation * vec4(0, 0, -1, 0);
float scalar_back = dot(normal_back, vec4(1, 0, 0, 0));
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
if (scalar_back <= 0 || ignore_scalars){
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
//front
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
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(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
//up
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
vec4 normal_up = geom_rotation * vec4(0, 1, 0, 0);
float scalar_up = dot(normal_up, vec4(1, 0, 0, 0));
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
if (scalar_up <= 0 || ignore_scalars) {
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
//down
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
vec4 normal_down = geom_rotation * vec4(0, -1, 0, 0);
float scalar_down = dot(normal_down, vec4(1, 0, 0, 0));
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
if (scalar_down <= 0 || ignore_scalars) {
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
//left
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
vec4 normal_left = geom_rotation * vec4(-1, 0, 0, 0);
float scalar_left = dot(normal_left, vec4(1, 0, 0, 0));
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
if (scalar_left <= 0 || ignore_scalars) {
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(-0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
//right
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
vec4 normal_right = geom_rotation * vec4(1, 0, 0, 0);
float scalar_right = dot(normal_right, vec4(1, 0, 0, 0));
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
if (scalar_right <= 0 || ignore_scalars) {
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, -0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, 0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
gl_Position = ubo.proj * ubo.view * (gl_in[0].gl_Position + geom_rotation * vec4(0.5, 0.5, -0.5, 0));
fragColor = geoColor[0];
fragTexCoord = geoTexCoord[0];
EmitVertex();
EndPrimitive();
}
}

View file

@ -18,6 +18,7 @@ use vulkanalia::prelude::v1_0::*;
use vulkanalia::Version;
use vulkanalia::bytecode::Bytecode;
use core::time;
use std::collections::HashSet;
use std::ffi::CStr;
use std::os::raw::c_void;
@ -27,7 +28,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension;
use vulkanalia::vk::KhrSurfaceExtension;
use vulkanalia::vk::KhrSwapchainExtension;
use cgmath::{vec2, vec3, SquareMatrix};
use cgmath::{vec2, vec3, Matrix, SquareMatrix};
use std::mem::size_of;
use std::ptr::copy_nonoverlapping as memcpy;
@ -50,7 +51,9 @@ const VALIDATION_ENABLED: bool =
const VALIDATION_LAYER: vk::ExtensionName =
vk::ExtensionName::from_bytes(b"VK_LAYER_KHRONOS_validation");
const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSION.name];
const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[
vk::KHR_SWAPCHAIN_EXTENSION.name
];
const MAX_FRAMES_IN_FLIGHT: usize = 2;
@ -112,6 +115,15 @@ fn main() -> Result<()> {
if event.logical_key == "w" {
app.cur_pos += app.view_direction * 0.1;
}
if event.logical_key == "s" {
app.cur_pos -= app.view_direction * 0.1;
}
if event.logical_key == "a" {
app.cur_pos -= app.view_direction.cross(vertex::Vec3::new(0.0, 0.0, 1.0)) * 0.1;
}
if event.logical_key == "d" {
app.cur_pos += app.view_direction.cross(vertex::Vec3::new(0.0, 0.0, 1.0)) * 0.1;
}
},
_ => {}
}
@ -152,11 +164,38 @@ impl App {
vertex::Vertex::new(vec3(8.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec2(0.0, 0.0))
);
data.indices.push(0);
data.vertices.push(
vertex::Vertex::new(vec3(-8.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec2(0.0, 0.0))
);
data.indices.push(1);
data.vertices.push(
vertex::Vertex::new(vec3(0.0, 8.0, 0.0), vec3(1.0, 1.0, 0.0), vec2(0.0, 0.0))
);
data.indices.push(2);
data.vertices.push(
vertex::Vertex::new(vec3(0.0, -8.0, 0.0), vec3(0.0, 1.0, 1.0), vec2(0.0, 0.0))
);
data.indices.push(3);
let grid_size = 1000;
for x_index in -grid_size..grid_size {
for y_index in -grid_size..grid_size {
if !(((x_index as i32).abs() == 8 && y_index == 0) || (x_index == 0 && (y_index as i32).abs() == 8)){
let index = data.indices.len();
let vert = vertex::Vertex::new(
vec3(x_index as f32, y_index as f32, 0.0),
vec3(0.0, 1.0, 0.0),
vec2(0.0, 0.0)
);
data.vertices.push(vert);
data.indices.push(index as u32);
}
}
}
let instance = create_instance(window, &entry, &mut data)?;
data.surface = vk_window::create_surface(&instance, &window, &window)?;
pick_physical_device(&instance, &mut data)?;
@ -200,6 +239,7 @@ impl App {
/// Renders a frame for our Vulkan app.
unsafe fn render(&mut self, window: &Window) -> Result<()> {
let start_time = Instant::now();
let in_flight_fence = self.data.in_flight_fences[self.frame];
self.device.wait_for_fences(&[in_flight_fence], true, u64::MAX)?;
@ -259,6 +299,7 @@ impl App {
self.frame = (self.frame + 1) % MAX_FRAMES_IN_FLIGHT;
println!("{}", 1000000.0 / start_time.elapsed().as_micros() as f32);
Ok(())
}
@ -362,7 +403,7 @@ impl App {
let rot_mat = cgmath::Matrix3::from_angle_y(cgmath::Deg(-self.cam_angle_y)) * cgmath::Matrix3::from_angle_z(cgmath::Deg(self.cam_angle_x));
let rot_mat4 = cgmath::Matrix4::from_angle_y(cgmath::Deg(-self.cam_angle_y)) * cgmath::Matrix4::from_angle_z(cgmath::Deg(self.cam_angle_x));
self.view_direction = rot_mat * vertex::Vec3::new(1.0, 0.0, 0.0);
self.view_direction = rot_mat.transpose() * vertex::Vec3::new(1.0, 0.0, 0.0);
let model = cgmath::Matrix4::from_translation( cgmath::Point3::new(0.0, 0.0, 0.0) - self.cur_pos );
let view = buffer::Mat4::look_to_rh(
@ -385,7 +426,7 @@ impl App {
cgmath::Deg(45.0),
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
0.1,
10.0,
10000.0,
);
let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj };
@ -415,7 +456,7 @@ unsafe fn create_instance(window: &Window, entry: &Entry, data: &mut app_data::A
.application_version(vk::make_version(1, 0, 0))
.engine_name(b"No Engine\0")
.engine_version(vk::make_version(1, 0, 0))
.api_version(vk::make_version(1, 0, 0));
.api_version(vk::make_version(1, 1, 0));
// Validation layers
@ -562,6 +603,10 @@ unsafe fn check_physical_device_extensions(
if DEVICE_EXTENSIONS.iter().all(|e| extensions.contains(e)) {
Ok(())
} else {
let missing = DEVICE_EXTENSIONS.iter().filter(|e| !extensions.contains(e)).collect::<Vec<&vk::ExtensionName>>();
for missing_extension in missing {
println!("Missing extension: {}", missing_extension);
}
Err(anyhow!(errors::SuitabilityError("Missing required device extensions.")))
}
}