This commit is contained in:
2019-07-23 21:55:02 +02:00
parent 7d50d00ab6
commit 1f980e7c12
4 changed files with 91 additions and 38 deletions

View File

@@ -1,7 +1,9 @@
#version 450
layout(location = 0) in vec3 pos;
layout(location = 0) out vec4 f_color;
void main() {
f_color = vec4(0.0, 1.0, 0.0, 1.0);
f_color = vec4(pos, 1.0);
}

View File

@@ -2,10 +2,13 @@
layout(location = 0) in vec3 position;
layout(location = 0) out vec3 pos;
layout(push_constant) uniform push_constants {
float time;
} push;
void main() {
gl_Position = vec4(position + vec3(sin(push.time / 10.), 0., 0.), 1.0);
pos = gl_Position.xyz;
}

View File

@@ -1,6 +1,7 @@
use crate::vulkan::{Vertex, GameData};
use winit::{DeviceId, KeyboardInput, ElementState, VirtualKeyCode};
use winit::{Event, WindowEvent};
use std::time::SystemTime;
use std::iter::FromIterator;
mod vulkan;
@@ -9,11 +10,26 @@ impl GameData<'_> {
}
fn on_keyboard_event(self: &Self, _: DeviceId, input: KeyboardInput) {
if input.state == ElementState::Pressed && input.virtual_keycode == Some(VirtualKeyCode::F) {
println!("doot");
/// Returns true if event should be ignored by the vulkan handler
fn on_window_event(self: &Self, event: &Event) -> bool {
match event {
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => {
let mods = String::from_iter(
vec!["shift", "ctrl", "alt", "logo"].iter()
.zip(vec![input.modifiers.shift, input.modifiers.ctrl, input.modifiers.alt, input.modifiers.logo])
.filter(|(&_name, state)| *state)
.map(|(&name, _state)| name));
if mods.len() > 0 {
println!("Keyboard {:?} input {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode)
} else {
println!("Keyboard {:?} input {:?} {:?}", device_id, input.state, input.scancode)
}
}
_ => {}
}
return false;
}
fn update_push_constants(self: &mut Self) {
self.push_constants.time = self.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;
}
@@ -36,8 +52,8 @@ fn main() {
Vertex { position: [0.2, 0.2, 0.3] }
],
line_vertices: vec![
Vertex { position: [-1., 0., 0.] },
Vertex { position: [1., 0., 0.] },
Vertex { position: [-0.9, 1., 0.] },
Vertex { position: [0.9, 0., 0.] },
],
push_constants: &mut pc,
start_time: SystemTime::now()

View File

@@ -3,7 +3,7 @@ use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::SwapchainImage;
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::instance::{Instance, PhysicalDevice, ApplicationInfo, Version, RawInstanceExtensions};
use vulkano::pipeline::{GraphicsPipeline};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule};
use vulkano::pipeline::viewport::Viewport;
@@ -11,6 +11,8 @@ use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain,
use vulkano::swapchain;
use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use vulkano::pipeline::vertex::SingleBufferDefinition;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano_win::VkSurfaceBuild;
@@ -19,15 +21,14 @@ use winit::{EventsLoop, Window, WindowBuilder, Event, WindowEvent};
use std::sync::Arc;
use std::time::SystemTime;
use std::path::PathBuf;
use std::ffi::CStr;
use std::ffi::{CStr, CString};
use shade_runner;
use shade_runner::{CompiledShaders, Entry};
use shaderc;
use vulkano::pipeline::vertex::SingleBufferDefinition;
use vulkano::descriptor::PipelineLayoutAbstract;
use crate::PushConstants;
use vulkano::instance::debug::{DebugCallback, MessageTypes};
const VALIDATION_LAYERS: &[&str] = &[
"VK_LAYER_LUNARG_standard_validation"
@@ -52,15 +53,45 @@ pub struct GameData<'a> {
}
pub fn init(mut game: GameData) {
if ENABLE_VALIDATION_LAYERS {
println!("Enabling validation layers...");
}
let instance = {
let extensions = vulkano_win::required_extensions();
// let mut extensions = RawInstanceExtensions::from(&vulkano_win::required_extensions());
let mut extensions = vulkano_win::required_extensions();
let app_info = ApplicationInfo {
application_name: Some("Asuro Editor".into()),
application_version: Some(Version { major: 0, minor: 1, patch: 0 }),
engine_name: Some("Asuro Rust Engine".into()),
engine_version: Some(Version { major: 0, minor: 1, patch: 0 })
};
if ENABLE_VALIDATION_LAYERS {
Instance::new(None, &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
let available_layers = vulkano::instance::layers_list().unwrap().map(|layer| String::from(layer.name())).collect::<Vec<String>>();
VALIDATION_LAYERS.iter().for_each(|wanted_layer_name| {
if !available_layers.iter().any(|available_layer_name| available_layer_name == wanted_layer_name) {
panic!("Validation layer not found: {:?}. Available layers: {:?}", wanted_layer_name, &available_layers.join(", "));
}
});
extensions.ext_debug_report = true;
// extensions.insert(CString::new("VK_EXT_debug_utils").unwrap());
Instance::new(Some(&app_info), &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
} else {
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
Instance::new(Some(&app_info), &extensions, None).expect("failed to create Vulkan instance")
}
};
if ENABLE_VALIDATION_LAYERS {
let debug_callback = setup_debug_callback(&instance);
assert!(debug_callback.is_some());
println!("Debug callback created.");
}
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
@@ -155,24 +186,8 @@ pub fn init(mut game: GameData) {
};
let mesh_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.mesh_vertices.iter().cloned()).unwrap();
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.mesh_vertices.iter().cloned()).unwrap();
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.line_vertices.iter().cloned()).unwrap();
// The next step is to create the shaders.
//
// The raw shader creation API provided by the vulkano library is unsafe, for various reasons.
//
// An overview of what the `vulkano_shaders::shader!` macro generates can be found in the
// `vulkano-shaders` crate docs. You can view them at https://docs.rs/vulkano-shaders/
//
// TODO: explain this in details
// At this point, OpenGL initialization would be finished. However in Vulkan it is not. OpenGL
// implicitly does a lot of computation whenever you draw. In Vulkan, you have to do all this
// manually.
// The next step is to create a *render pass*, which is an object that describes where the
// output of the graphics pipeline will go. It describes the layout of the images
// where the colors, depth and/or stencil information will be written.
let render_pass = Arc::new(vulkano::single_pass_renderpass!(
device.clone(),
attachments: {
@@ -394,13 +409,12 @@ pub fn init(mut game: GameData) {
// it.
let mut done = false;
events_loop.poll_events(|ev| {
match ev {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => {
game.on_keyboard_event(device_id, input);
if !game.on_window_event(&ev) {
match ev {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => {}
}
_ => {}
}
});
if done { return; }
@@ -499,4 +513,22 @@ fn read_shader(vert_path_relative: &str, frag_path_relative: &str) -> (CompiledS
}
Err(error) => panic!("Shader compilation error: {:?}", error)
}
}
}
fn setup_debug_callback(instance: &Arc<Instance>) -> Option<DebugCallback> {
if !ENABLE_VALIDATION_LAYERS {
return None;
}
let msg_types = MessageTypes {
error: true,
warning: true,
performance_warning: true,
information: true,
debug: true,
};
DebugCallback::new(&instance, msg_types, |msg| {
println!("validation layer: {:?}", msg.description);
}).ok()
}