Geommetry shader and start of rotation&movement

This commit is contained in:
zomseffen 2024-05-04 15:24:42 +02:00
parent fdac5a97a1
commit 9ad743cfa2
10 changed files with 240 additions and 26 deletions

View file

@ -1,2 +1,3 @@
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

Binary file not shown.

BIN
shaders/geo.spv Normal file

Binary file not shown.

View file

@ -7,5 +7,5 @@ layout(location = 0) out vec4 outColor;
layout(binding = 1) uniform sampler2D texSampler;
void main() {
outColor = texture(texSampler, fragTexCoord);
outColor = vec4(fragColor, 1); //texture(texSampler, fragTexCoord);
}

152
shaders/shader.geom Normal file
View file

@ -0,0 +1,152 @@
#version 450
layout(points) in;
layout(triangle_strip, max_vertices=24) out;
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 geom_rot;
mat4 view;
mat4 proj;
} ubo;
layout(location = 0) in vec3 geoColor[];
layout(location = 1) in vec2 geoTexCoord[];
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
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();
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();
//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();
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();
//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();
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();
//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();
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();
//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();
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();
//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();
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();
}

View file

@ -2,6 +2,7 @@
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 geom_rot;
mat4 view;
mat4 proj;
} ubo;
@ -11,11 +12,11 @@ layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
layout(location = 0) out vec3 geoColor;
layout(location = 1) out vec2 geoTexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor;
fragTexCoord = inTexCoord;
gl_Position = ubo.geom_rot * ubo.model * vec4(inPosition, 1.0);
geoColor = inColor;
geoTexCoord = inTexCoord;
}

Binary file not shown.

View file

@ -176,6 +176,7 @@ pub unsafe fn create_index_buffer(
#[derive(Copy, Clone, Debug)]
pub struct UniformBufferObject {
pub model: Mat4,
pub geom_rot: Mat4,
pub view: Mat4,
pub proj: Mat4,
}
@ -188,7 +189,7 @@ pub unsafe fn create_descriptor_set_layout(
.binding(0)
.descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
.descriptor_count(1)
.stage_flags(vk::ShaderStageFlags::VERTEX);
.stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY);
let sampler_binding = vk::DescriptorSetLayoutBinding::builder()
.binding(1)

View file

@ -7,7 +7,7 @@
use anyhow::{anyhow, Result};
use log::*;
use winit::dpi::LogicalSize;
use winit::dpi::{LogicalSize, LogicalPosition, PhysicalPosition};
use winit::event::{Event, WindowEvent};
use winit::event_loop::EventLoop;
use winit::window::{Window, WindowBuilder};
@ -27,7 +27,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension;
use vulkanalia::vk::KhrSurfaceExtension;
use vulkanalia::vk::KhrSwapchainExtension;
use cgmath::vec3;
use cgmath::{vec2, vec3, SquareMatrix};
use std::mem::size_of;
use std::ptr::copy_nonoverlapping as memcpy;
@ -64,6 +64,7 @@ fn main() -> Result<()> {
.with_title("Vulkan Tutorial (Rust)")
.with_inner_size(LogicalSize::new(1024, 768))
.build(&event_loop)?;
//window.set_cursor_visible(false);
// App
@ -88,7 +89,30 @@ fn main() -> Result<()> {
app.minimized = false;
app.resized = true;
}
},
WindowEvent::CursorMoved { device_id, position } => {
let log_pos: LogicalPosition<f32> = position.to_logical(window.scale_factor());
if app.last_pos.x != -1.0 {
app.cam_angle_x += ((log_pos.x - (window.inner_size().width as f32 / 2.0)) / (window.inner_size().width as f32)) * 180.0;
app.cam_angle_y += ((log_pos.y - (window.inner_size().height as f32 / 2.0)) / (window.inner_size().height as f32)) * 180.0;
if app.cam_angle_x >= 360.0 {
app.cam_angle_x -= 360.0;
}
if app.cam_angle_x <= -360.0 {
app.cam_angle_x += 360.0;
}
app.cam_angle_y = app.cam_angle_y.max(-90.0).min(90.0);
}
window.set_cursor_position(LogicalPosition::new(window.inner_size().width / 2, window.inner_size().height / 2)).expect("Cannot set Cursor!");
app.last_pos = LogicalPosition::new(window.inner_size().width as f32 / 2 as f32, window.inner_size().height as f32 / 2 as f32);
},
WindowEvent::KeyboardInput { device_id, event, is_synthetic } => {
if event.logical_key == "w" {
app.cur_pos += app.view_direction * 0.1;
}
},
_ => {}
}
_ => {}
@ -109,6 +133,11 @@ struct App {
resized: bool,
minimized: bool,
start: Instant,
cam_angle_x: f32,
cam_angle_y: f32,
last_pos: LogicalPosition<f32>,
view_direction: vertex::Vec3,
cur_pos: cgmath::Point3<f32>,
}
impl App {
@ -117,7 +146,17 @@ impl App {
let loader = LibloadingLoader::new(LIBRARY)?;
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
let mut data = app_data::AppData::default();
load_model::load_model(&mut data)?;
//load_model::load_model(&mut data)?;
data.vertices.push(
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);
let instance = create_instance(window, &entry, &mut data)?;
data.surface = vk_window::create_surface(&instance, &window, &window)?;
pick_physical_device(&instance, &mut data)?;
@ -151,7 +190,12 @@ impl App {
create_sync_objects(&device, &mut data)?;
Ok(Self { entry, instance, data, device, frame: 0 , resized: false, minimized: false, start: Instant::now()})
Ok(Self { entry, instance, data, device, frame: 0 , resized: false, minimized: false, start: Instant::now(),
cam_angle_x: 0.0, cam_angle_y: 0.0,
last_pos: LogicalPosition::new(-1 as f32, -1 as f32),
view_direction: vertex::Vec3::new(0.0, 0.0, 0.0),
cur_pos: cgmath::point3(0.0, 0.0, 0.0),
})
}
/// Renders a frame for our Vulkan app.
@ -308,19 +352,25 @@ impl App {
}
unsafe fn update_uniform_buffer(&self, image_index: usize) -> Result<()> {
unsafe fn update_uniform_buffer(&mut self, image_index: usize) -> Result<()> {
let time = self.start.elapsed().as_secs_f32();
let model = buffer::Mat4::from_axis_angle(
vec3(0.0, 0.0, 1.0),
/*let model = buffer::Mat4::from_axis_angle(
vec3(0.0, 1.0, 0.0),
cgmath::Deg(90.0) * 0.0 //time
);*/
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);
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(
cgmath::point3(0.0, 0.0, 0.0),
vertex::Vec3::new(1.0, 0.0, 0.0),
vertex::Vec3::new(0.0, 0.0, 1.0)
);
let view = buffer::Mat4::look_at_rh(
cgmath::point3(2.0, 2.0, 2.0),
cgmath::point3(0.0, 0.0, 0.0),
vec3(0.0, 0.0, 1.0),
);
let correction = buffer::Mat4::new( //column major order, matrix looks transposed
1.0, 0.0, 0.0, 0.0,
@ -338,7 +388,7 @@ impl App {
10.0,
);
let ubo = buffer::UniformBufferObject { model, view, proj };
let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj };
let memory = self.device.map_memory(
self.data.uniform_buffers_memory[image_index],
@ -546,7 +596,8 @@ unsafe fn create_logical_device(
};
let features = vk::PhysicalDeviceFeatures::builder()
.sampler_anisotropy(true);
.sampler_anisotropy(true)
.geometry_shader(true);
let indices = queue_family_indices::QueueFamilyIndices::get(instance, data, data.physical_device)?;
@ -580,9 +631,11 @@ unsafe fn create_logical_device(
unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Result<()> {
let vert = include_bytes!("../shaders/vert.spv");
let geo = include_bytes!("../shaders/geo.spv");
let frag = include_bytes!("../shaders/frag.spv");
let vert_shader_module = create_shader_module(device, &vert[..])?;
let geo_shader_module = create_shader_module(device, &geo[..])?;
let frag_shader_module = create_shader_module(device, &frag[..])?;
let vert_stage = vk::PipelineShaderStageCreateInfo::builder()
@ -590,6 +643,11 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
.module(vert_shader_module)
.name(b"main\0");
let geo_stage = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::GEOMETRY)
.module(geo_shader_module)
.name(b"main\0");
let frag_stage = vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::FRAGMENT)
.module(frag_shader_module)
@ -602,7 +660,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
.vertex_attribute_descriptions(&attribute_descriptions);
let input_assembly_state = vk::PipelineInputAssemblyStateCreateInfo::builder()
.topology(vk::PrimitiveTopology::TRIANGLE_LIST)
.topology(vk::PrimitiveTopology::POINT_LIST)
.primitive_restart_enable(false);
let viewport = vk::Viewport::builder()
@ -668,7 +726,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?;
let stages = &[vert_stage, frag_stage];
let stages = &[vert_stage, geo_stage, frag_stage];
let info = vk::GraphicsPipelineCreateInfo::builder()
.stages(stages)
.vertex_input_state(&vertex_input_state)
@ -686,6 +744,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
vk::PipelineCache::null(), &[info], None)?.0[0];
device.destroy_shader_module(vert_shader_module, None);
device.destroy_shader_module(geo_shader_module, None);
device.destroy_shader_module(frag_shader_module, None);
Ok(())

View file

@ -5,8 +5,8 @@ use std::mem::size_of;
use cgmath;
type Vec2 = cgmath::Vector2<f32>;
type Vec3 = cgmath::Vector3<f32>;
pub type Vec2 = cgmath::Vector2<f32>;
pub type Vec3 = cgmath::Vector3<f32>;
#[repr(C)]
#[derive(Copy, Clone, Debug)]