added index buffer for rendering
This commit is contained in:
parent
35083ee148
commit
624e19d84c
|
@ -1,7 +1,5 @@
|
||||||
use eruption::init;
|
mod vulkan;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
init();
|
vulkan::init();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
pub(crate) mod vs {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "vertex",
|
|
||||||
src: r"
|
|
||||||
#version 450
|
|
||||||
layout(location = 0) in vec2 position;
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(position, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) mod fs {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "fragment",
|
|
||||||
src: r"
|
|
||||||
#version 450
|
|
||||||
layout(location = 0) out vec4 f_color;
|
|
||||||
void main() {
|
|
||||||
f_color = vec4(1.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
",
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
mod composit;
|
mod composite;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vulkano::device::Device;
|
use vulkano::device::Device;
|
||||||
|
@ -11,8 +11,8 @@ use crate::Vertex2d;
|
||||||
|
|
||||||
pub fn create_program(render_pass: &Arc<RenderPass>, device: &Arc<Device>) -> Arc<GraphicsPipeline> {
|
pub fn create_program(render_pass: &Arc<RenderPass>, device: &Arc<Device>) -> Arc<GraphicsPipeline> {
|
||||||
|
|
||||||
let vs = composit::vs::load(device.clone()).unwrap();
|
let vs = composite::vs::load(device.clone()).unwrap();
|
||||||
let fs = composit::fs::load(device.clone()).unwrap();
|
let fs = composite::fs::load(device.clone()).unwrap();
|
||||||
|
|
||||||
// Before we draw we have to create what is called a pipeline. This is similar to an OpenGL
|
// Before we draw we have to create what is called a pipeline. This is similar to an OpenGL
|
||||||
// program, but much more specific.
|
// program, but much more specific.
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
#include <pathtracing/pathtracer.glsl>
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 texture_coordinate;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec2 uv = texture_coordinate;
|
||||||
|
|
||||||
|
vec3 color = trace_path(uv);
|
||||||
|
|
||||||
|
frag_color = vec4(color, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 position;
|
||||||
|
layout(location = 1) in vec2 texture;
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 texture_coordinate;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
texture_coordinate = texture;
|
||||||
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
layout(push_constant) uniform Camera {
|
||||||
|
vec3 position;
|
||||||
|
vec3 front;
|
||||||
|
vec3 up;
|
||||||
|
vec3 left;
|
||||||
|
float fov;
|
||||||
|
} camera;
|
||||||
|
|
||||||
|
vec3 generate_view_ray_direction(in vec2 uv) {
|
||||||
|
// convert camera fov from degrees to relative factor for scaling normalized front vector
|
||||||
|
float fov = 1.0 / tan(DegreeToRadians(camera.fov) * 0.5);
|
||||||
|
|
||||||
|
return normalize(camera.front * fov + camera.up * uv.x + camera.left * uv.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray generate_view_ray(in vec2 uv) {
|
||||||
|
Ray view_ray;
|
||||||
|
view_ray.origin = camera.position;
|
||||||
|
view_ray.direction = generate_view_ray_direction(uv);
|
||||||
|
return view_ray;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#define DegreeToRadians(x) (x * 0.01745329251994330)
|
||||||
|
|
||||||
|
struct Ray {
|
||||||
|
vec3 origin;
|
||||||
|
vec3 direction;
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#include <pathtracing/common.glsl>
|
||||||
|
#include <pathtracing/camera.glsl>
|
||||||
|
|
||||||
|
vec3 trace_path(in vec2 uv) {
|
||||||
|
Ray view_ray = generate_view_ray(uv);
|
||||||
|
|
||||||
|
return view_ray.direction;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
pub(crate) mod vs {
|
||||||
|
vulkano_shaders::shader! {
|
||||||
|
ty: "vertex",
|
||||||
|
path: "src/shader/src/composite.vert"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) mod fs {
|
||||||
|
vulkano_shaders::shader! {
|
||||||
|
ty: "fragment",
|
||||||
|
include: ["src/shader/src"],
|
||||||
|
path: "src/shader/src/composite.frag"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
mod shader;
|
mod composite;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Properties, Queue, QueueCreateInfo, QueueFlags};
|
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Properties, Queue, QueueCreateInfo, QueueFlags};
|
||||||
|
@ -11,7 +11,7 @@ use vulkano::{sync, VulkanLibrary};
|
||||||
use vulkano_win::VkSurfaceBuild;
|
use vulkano_win::VkSurfaceBuild;
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
use winit::window::{Window, WindowBuilder};
|
use winit::window::{Window, WindowBuilder};
|
||||||
use vulkano::buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage};
|
use vulkano::buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer};
|
||||||
use vulkano::command_buffer::allocator::StandardCommandBufferAllocator;
|
use vulkano::command_buffer::allocator::StandardCommandBufferAllocator;
|
||||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents};
|
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents};
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
|
@ -29,29 +29,36 @@ use winit::event::{Event, WindowEvent};
|
||||||
struct Vertex2d {
|
struct Vertex2d {
|
||||||
#[format(R32G32_SFLOAT)]
|
#[format(R32G32_SFLOAT)]
|
||||||
position: [f32; 2],
|
position: [f32; 2],
|
||||||
|
#[format(R32G32_SFLOAT)]
|
||||||
|
texture: [f32; 2]
|
||||||
}
|
}
|
||||||
|
|
||||||
const QUAD_VERTICES: [Vertex2d; 6] = [
|
fn textured_quad() -> (Vec<Vertex2d>, Vec<u32>) {
|
||||||
|
(
|
||||||
|
vec![
|
||||||
Vertex2d {
|
Vertex2d {
|
||||||
position: [-1.0, -1.0]
|
position: [-1.0, -1.0],
|
||||||
|
texture: [0.0, 0.0]
|
||||||
},
|
},
|
||||||
Vertex2d {
|
Vertex2d {
|
||||||
position: [1.0, -1.0]
|
position: [1.0, -1.0],
|
||||||
|
texture: [1.0, 0.0]
|
||||||
},
|
},
|
||||||
Vertex2d {
|
Vertex2d {
|
||||||
position: [1.0, 1.0]
|
position: [1.0, 1.0],
|
||||||
},
|
texture: [1.0, 1.0]
|
||||||
|
|
||||||
Vertex2d {
|
|
||||||
position: [-1.0, -1.0]
|
|
||||||
},
|
},
|
||||||
Vertex2d {
|
Vertex2d {
|
||||||
position: [1.0, 1.0]
|
position: [-1.0, 1.0],
|
||||||
},
|
texture: [0.0, 1.0]
|
||||||
Vertex2d {
|
}
|
||||||
position: [-1.0, 1.0]
|
],
|
||||||
|
vec![
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3
|
||||||
|
]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
];
|
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
let lib = VulkanLibrary::new().unwrap();
|
let lib = VulkanLibrary::new().unwrap();
|
||||||
|
@ -96,18 +103,7 @@ pub fn init() {
|
||||||
|
|
||||||
let memory_allocator = StandardMemoryAllocator::new_default(device.clone());
|
let memory_allocator = StandardMemoryAllocator::new_default(device.clone());
|
||||||
|
|
||||||
let vertex_buffer = Buffer::from_iter(
|
let (vertex_buffer, index_buffer) = create_quad_buffer(&memory_allocator);
|
||||||
&memory_allocator,
|
|
||||||
BufferCreateInfo {
|
|
||||||
usage: BufferUsage::VERTEX_BUFFER,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
AllocationCreateInfo {
|
|
||||||
usage: MemoryUsage::Upload,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
QUAD_VERTICES,
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// At this point, OpenGL initialization would be finished. However in Vulkan it is not. OpenGL
|
// 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
|
// implicitly does a lot of computation whenever you draw. In Vulkan, you have to do all this
|
||||||
|
@ -157,7 +153,7 @@ pub fn init() {
|
||||||
// that, we store the submission of the previous frame here.
|
// that, we store the submission of the previous frame here.
|
||||||
let mut previous_frame_end = Some(sync::now(device.clone()).boxed());
|
let mut previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||||
|
|
||||||
let pipeline = shader::create_program(&render_pass, &device);
|
let pipeline = composite::create_program(&render_pass, &device);
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
|
@ -204,7 +200,7 @@ pub fn init() {
|
||||||
// window. Simply restarting the loop is the easiest way to fix this
|
// window. Simply restarting the loop is the easiest way to fix this
|
||||||
// issue.
|
// issue.
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
Err(e) => panic!("failed to recreate swapchain: {}", e),
|
||||||
};
|
};
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
|
@ -234,7 +230,7 @@ pub fn init() {
|
||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(e) => panic!("failed to acquire next image: {e}"),
|
Err(e) => panic!("failed to acquire next image: {}", e),
|
||||||
};
|
};
|
||||||
|
|
||||||
// `acquire_next_image` can be successful, but suboptimal. This means that the
|
// `acquire_next_image` can be successful, but suboptimal. This means that the
|
||||||
|
@ -287,8 +283,9 @@ pub fn init() {
|
||||||
.set_viewport(0, [viewport.clone()])
|
.set_viewport(0, [viewport.clone()])
|
||||||
.bind_pipeline_graphics(pipeline.clone())
|
.bind_pipeline_graphics(pipeline.clone())
|
||||||
.bind_vertex_buffers(0, vertex_buffer.clone())
|
.bind_vertex_buffers(0, vertex_buffer.clone())
|
||||||
|
.bind_index_buffer(index_buffer.clone())
|
||||||
// We add a draw command.
|
// We add a draw command.
|
||||||
.draw(vertex_buffer.len() as u32, 1, 0, 0)
|
.draw_indexed(index_buffer.len() as u32, 1, 0, 0, 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
// We leave the render pass. Note that if we had multiple subpasses we could
|
// We leave the render pass. Note that if we had multiple subpasses we could
|
||||||
// have called `next_subpass` to jump to the next subpass.
|
// have called `next_subpass` to jump to the next subpass.
|
||||||
|
@ -327,7 +324,7 @@ pub fn init() {
|
||||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
panic!("failed to flush future: {e}");
|
panic!("failed to flush future: {}", e);
|
||||||
// previous_frame_end = Some(sync::now(device.clone()).boxed());
|
// previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,6 +334,38 @@ pub fn init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_quad_buffer(memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[Vertex2d]>, Subbuffer<[u32]>) {
|
||||||
|
let (vertices, indices) = textured_quad();
|
||||||
|
|
||||||
|
let vertex_buffer = Buffer::from_iter(
|
||||||
|
memory_allocator,
|
||||||
|
BufferCreateInfo {
|
||||||
|
usage: BufferUsage::VERTEX_BUFFER,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo {
|
||||||
|
usage: MemoryUsage::Upload,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
vertices,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let index_buffer = Buffer::from_iter(
|
||||||
|
memory_allocator,
|
||||||
|
BufferCreateInfo {
|
||||||
|
usage: BufferUsage::INDEX_BUFFER,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo {
|
||||||
|
usage: MemoryUsage::Upload,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
indices,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
(vertex_buffer, index_buffer)
|
||||||
|
}
|
||||||
|
|
||||||
/// This function is called once during initialization, then again whenever the window is resized.
|
/// This function is called once during initialization, then again whenever the window is resized.
|
||||||
fn window_size_dependent_setup(
|
fn window_size_dependent_setup(
|
||||||
images: &[Arc<SwapchainImage>],
|
images: &[Arc<SwapchainImage>],
|
Reference in New Issue