hotload shader + directional light
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
# Scan codes are in decimal
|
||||||
|
# See here: https://www.millisecond.com/support/docs/v6/html/language/scancodes.htm
|
||||||
|
|
||||||
[[button]]
|
[[button]]
|
||||||
name = "quit"
|
name = "quit"
|
||||||
scan_code = 1
|
scan_code = 1
|
||||||
@@ -8,8 +11,7 @@ scan_code = 59
|
|||||||
|
|
||||||
[[button]]
|
[[button]]
|
||||||
name = "reload_shaders"
|
name = "reload_shaders"
|
||||||
scan_code = 19
|
scan_code = 63
|
||||||
ctrl = true
|
|
||||||
|
|
||||||
[[button]]
|
[[button]]
|
||||||
name = "print_framerate"
|
name = "print_framerate"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ layout(binding = 0) uniform ObjectUniformData {
|
|||||||
mat4 projection;
|
mat4 projection;
|
||||||
float time;
|
float time;
|
||||||
vec3 light_position;
|
vec3 light_position;
|
||||||
|
vec3 light_directional_rotation;
|
||||||
vec3 camera_position;
|
vec3 camera_position;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
@@ -23,7 +24,9 @@ void main() {
|
|||||||
vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb;
|
vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb;
|
||||||
normal_cam_u = normal_cam_u * 2.0 - 1.0;
|
normal_cam_u = normal_cam_u * 2.0 - 1.0;
|
||||||
normal_cam_u = normalize(tbn * normal_cam_u);
|
normal_cam_u = normalize(tbn * normal_cam_u);
|
||||||
vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld);
|
|
||||||
|
// vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld);
|
||||||
|
vec3 light_direction_cam_u = normalize(vec3(sin(ubo.time), 1.0, cos(ubo.time)));
|
||||||
|
|
||||||
float ambient_strength = 0.1;
|
float ambient_strength = 0.1;
|
||||||
vec3 light_color = vec3(1.0, 1.0, 1.0);
|
vec3 light_color = vec3(1.0, 1.0, 1.0);
|
||||||
|
|||||||
Binary file not shown.
@@ -10,6 +10,7 @@ layout(binding = 0) uniform ObjectUniformData {
|
|||||||
mat4 projection;
|
mat4 projection;
|
||||||
float time;
|
float time;
|
||||||
vec3 light_position;
|
vec3 light_position;
|
||||||
|
vec3 light_directional_rotation;
|
||||||
vec3 camera_position;
|
vec3 camera_position;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
|
use cgmath::{Deg, InnerSpace, Quaternion, Rotation3};
|
||||||
use winit::event::Event;
|
use winit::event::Event;
|
||||||
|
|
||||||
use level::{load_level, save_level};
|
use level::{load_level, save_level};
|
||||||
use player::Player;
|
use player::Player;
|
||||||
|
|
||||||
use crate::config::{LogConfig};
|
use crate::config::LogConfig;
|
||||||
use crate::input::InputState;
|
use crate::input::InputState;
|
||||||
use crate::vulkan::{Game, MeshHandle, VulkanRenderer};
|
use crate::vulkan::{Game, MeshHandle, VulkanRenderer};
|
||||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
||||||
@@ -22,6 +23,7 @@ pub struct TestGame {
|
|||||||
pub texture_index_counter: usize,
|
pub texture_index_counter: usize,
|
||||||
pub last_time: f32,
|
pub last_time: f32,
|
||||||
pub components: Vec<Box<dyn Updatable>>,
|
pub components: Vec<Box<dyn Updatable>>,
|
||||||
|
pub paused: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game for TestGame {
|
impl Game for TestGame {
|
||||||
@@ -48,7 +50,7 @@ impl Game for TestGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.input.button_just_pressed("reload_shaders") {
|
if self.input.button_just_pressed("reload_shaders") {
|
||||||
renderer.game_data.recreate_pipeline = true;
|
renderer.recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.input.button_just_pressed("quicksave") {
|
if self.input.button_just_pressed("quicksave") {
|
||||||
@@ -65,17 +67,15 @@ impl Game for TestGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.input.button_just_pressed("test") {
|
if self.input.button_just_pressed("test") {
|
||||||
if renderer.render_config.msaa_samples > 0 {
|
self.paused = !self.paused;
|
||||||
renderer.render_config.msaa_samples = 0;
|
|
||||||
} else {
|
|
||||||
renderer.render_config.msaa_samples = 8;
|
|
||||||
}
|
|
||||||
renderer.recreate_swapchain = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom game object stuff
|
// Custom game object stuff
|
||||||
let light_pos = self.player.camera.position * -1.0;
|
let light_pos = self.player.camera.position * -1.0;
|
||||||
|
if !self.paused {
|
||||||
self.player.update(frame_time, &self.input, renderer);
|
self.player.update(frame_time, &self.input, renderer);
|
||||||
|
}
|
||||||
|
self.game_objects[1].get_game_object_mut(renderer).unwrap().rotation = Quaternion::from_angle_y(Deg(time * -20.)).normalize();
|
||||||
|
|
||||||
// End frame
|
// End frame
|
||||||
self.last_time = time;
|
self.last_time = time;
|
||||||
@@ -86,9 +86,11 @@ impl Game for TestGame {
|
|||||||
projection: self.player.camera.proj.into(),
|
projection: self.player.camera.proj.into(),
|
||||||
time,
|
time,
|
||||||
light_position: light_pos.into(),
|
light_position: light_pos.into(),
|
||||||
|
light_directional_rotation: [45.0, 45.0, 0.0],
|
||||||
camera_position: self.player.camera.position.into(),
|
camera_position: self.player.camera.position.into(),
|
||||||
_dummy0: [0; 12],
|
_dummy0: [0; 12],
|
||||||
_dummy1: [0; 4],
|
_dummy1: [0; 4],
|
||||||
|
_dummy2: [0; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +105,7 @@ impl TestGame {
|
|||||||
texture_index_counter: 0,
|
texture_index_counter: 0,
|
||||||
last_time: 0.0,
|
last_time: 0.0,
|
||||||
components: vec![],
|
components: vec![],
|
||||||
|
paused: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
let pipelines: Vec<Box<dyn Drawcall>> = vec![
|
let pipelines: Vec<Box<dyn Drawcall>> = vec![
|
||||||
Box::new(DefaultShader::new(device.clone(), render_pass.clone())),
|
Box::new(DefaultShader::new(device.clone(), render_pass.clone())),
|
||||||
// Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())),
|
Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer.clone())),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Dynamic viewports allow us to recreate just the viewport when the window is resized
|
// Dynamic viewports allow us to recreate just the viewport when the window is resized
|
||||||
@@ -269,9 +269,11 @@ impl VulkanRenderer {
|
|||||||
projection: Matrix4::identity().into(),
|
projection: Matrix4::identity().into(),
|
||||||
time: 0.0,
|
time: 0.0,
|
||||||
light_position: [0.0, 0.0, 0.0],
|
light_position: [0.0, 0.0, 0.0],
|
||||||
|
light_directional_rotation: [0.0, 0.0, 0.0],
|
||||||
camera_position: [0.0, 0.0, 0.0],
|
camera_position: [0.0, 0.0, 0.0],
|
||||||
_dummy0: [0; 12],
|
_dummy0: [0; 12],
|
||||||
_dummy1: [0; 4],
|
_dummy1: [0; 4],
|
||||||
|
_dummy2: [0; 4],
|
||||||
};
|
};
|
||||||
|
|
||||||
for _ in 0..swapchain.num_images() {
|
for _ in 0..swapchain.num_images() {
|
||||||
@@ -347,7 +349,7 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
self.pipelines = vec![
|
self.pipelines = vec![
|
||||||
Box::new(DefaultShader::new(self.device.clone(), self.render_pass.clone())),
|
Box::new(DefaultShader::new(self.device.clone(), self.render_pass.clone())),
|
||||||
// Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())),
|
Box::new(LineShader::new(self.device.clone(), self.render_pass.clone(), self.line_vertex_buffer.clone())),
|
||||||
];
|
];
|
||||||
|
|
||||||
self.swapchain = new_swapchain;
|
self.swapchain = new_swapchain;
|
||||||
@@ -473,6 +475,11 @@ impl VulkanRenderer {
|
|||||||
pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, event_loop: EventLoop<()>) {
|
pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, event_loop: EventLoop<()>) {
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
game.on_window_event(&event);
|
game.on_window_event(&event);
|
||||||
|
|
||||||
|
if renderer.game_data.shutdown {
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use std::{convert::TryInto, io::{Read, Write}, sync::Arc};
|
use std::{convert::TryInto, io::{Read, Write}, sync::Arc};
|
||||||
|
|
||||||
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}};
|
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::ShaderModule};
|
||||||
use vulkano::command_buffer::DynamicState;
|
use vulkano::command_buffer::DynamicState;
|
||||||
use vulkano::device::Device;
|
use vulkano::device::Device;
|
||||||
use vulkano::framebuffer::RenderPassAbstract;
|
use vulkano::framebuffer::RenderPassAbstract;
|
||||||
use vulkano::framebuffer::Subpass;
|
use vulkano::framebuffer::Subpass;
|
||||||
use vulkano::pipeline::GraphicsPipeline;
|
use vulkano::pipeline::GraphicsPipeline;
|
||||||
use vulkano::pipeline::GraphicsPipelineAbstract;
|
use vulkano::pipeline::GraphicsPipelineAbstract;
|
||||||
|
use vulkano::pipeline::shader::GraphicsShaderType;
|
||||||
|
|
||||||
use crate::GameObject;
|
use crate::GameObject;
|
||||||
use crate::vulkan::{LinePoint, Vertex};
|
use crate::vulkan::{LinePoint, Vertex};
|
||||||
@@ -42,6 +43,16 @@ pub struct DefaultShader {
|
|||||||
pipeline: GP,
|
pipeline: GP,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn shader_module_from_file(device: Arc<Device>, path: &str) -> Arc<ShaderModule> {
|
||||||
|
let mut file = std::fs::File::open(path).unwrap();
|
||||||
|
let mut buffer = vec![];
|
||||||
|
file.read_to_end(&mut buffer).unwrap();
|
||||||
|
let words: Vec<u32> = buffer.chunks_exact(4).map(|c| u32::from_ne_bytes(c.try_into().unwrap())).collect();
|
||||||
|
unsafe {
|
||||||
|
ShaderModule::from_words(device.clone(), &words).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DefaultShader {
|
impl DefaultShader {
|
||||||
pub fn new(device: Arc<Device>, render_pass: RP) -> Self {
|
pub fn new(device: Arc<Device>, render_pass: RP) -> Self {
|
||||||
DefaultShader {
|
DefaultShader {
|
||||||
@@ -51,7 +62,6 @@ impl DefaultShader {
|
|||||||
|
|
||||||
fn create_pipeline(device: Arc<Device>, render_pass: RP) -> GP {
|
fn create_pipeline(device: Arc<Device>, render_pass: RP) -> GP {
|
||||||
let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap();
|
let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||||
let vertex_shader = vs::Shader::load(device.clone()).unwrap();
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
@@ -65,22 +75,26 @@ impl DefaultShader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut fs_file = std::fs::File::open("shaders/triangle.frag.spv").unwrap();
|
static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
||||||
let mut fs_buf = vec![];
|
let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
|
||||||
fs_file.read_to_end(&mut fs_buf).unwrap();
|
|
||||||
let fs_words: Vec<u32> = fs_buf.chunks_exact(4).map(|c| u32::from_ne_bytes(c.try_into().unwrap())).collect();
|
let fs_module = shader_module_from_file(device.clone(), "shaders/triangle.frag.spv");
|
||||||
let fs_module = vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &fs_words).unwrap();
|
|
||||||
let fs_layout = fs::Layout(ShaderStages {
|
let fs_layout = fs::Layout(ShaderStages {
|
||||||
fragment: true,
|
fragment: true,
|
||||||
..ShaderStages::none()
|
..ShaderStages::none()
|
||||||
});
|
});
|
||||||
static FS_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
let fs_entry = fs_module.graphics_entry_point(entry_name_c, fs::MainInput, fs::MainOutput, fs_layout, GraphicsShaderType::Fragment);
|
||||||
let fs_name_c = std::ffi::CStr::from_ptr(FS_NAME.as_ptr() as *const _);
|
|
||||||
let fs_entry = fs_module.graphics_entry_point(fs_name_c, fs::MainInput, fs::MainOutput, fs_layout, vulkano::pipeline::shader::GraphicsShaderType::Fragment);
|
let vs_module = shader_module_from_file(device.clone(), "shaders/triangle.vert.spv");
|
||||||
|
let vs_layout = vs::Layout(ShaderStages {
|
||||||
|
vertex: true,
|
||||||
|
..ShaderStages::none()
|
||||||
|
});
|
||||||
|
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs::MainInput, vs::MainOutput, vs_layout, GraphicsShaderType::Vertex);
|
||||||
|
|
||||||
Arc::new(GraphicsPipeline::start()
|
Arc::new(GraphicsPipeline::start()
|
||||||
.vertex_input_single_buffer::<Vertex>()
|
.vertex_input_single_buffer::<Vertex>()
|
||||||
.vertex_shader(vertex_shader.main_entry_point(), ())
|
.vertex_shader(vs_entry, ())
|
||||||
.triangle_list()
|
.triangle_list()
|
||||||
.viewports_dynamic_scissors_irrelevant(1)
|
.viewports_dynamic_scissors_irrelevant(1)
|
||||||
.depth_stencil_simple_depth()
|
.depth_stencil_simple_depth()
|
||||||
|
|||||||
Reference in New Issue
Block a user