progress?
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
layout(location = 0) in vec2 tex_coords;
|
layout(location = 0) in vec2 tex_coords;
|
||||||
|
|
||||||
layout(location = 0) out vec4 f_color;
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler2D tex;
|
layout(binding = 1) uniform sampler2D tex;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
f_color = texture(tex, tex_coords);
|
out_color = texture(tex, tex_coords);
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
#version 450
|
#version 450
|
||||||
#extension GL_ARB_separate_shader_objects : enable
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(binding = 0) uniform UniformBufferObject {
|
||||||
|
mat4 view;
|
||||||
|
mat4 projection;
|
||||||
|
float time;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
layout(location = 0) in vec3 position;
|
layout(location = 0) in vec3 position;
|
||||||
layout(location = 1) in vec2 uv;
|
layout(location = 1) in vec2 uv;
|
||||||
|
|
||||||
layout(location = 0) out vec2 tex_coords;
|
layout(location = 0) out vec2 tex_coords;
|
||||||
|
|
||||||
//layout(binding = 0) uniform UniformBufferObject {
|
|
||||||
// mat4 view;
|
|
||||||
// mat4 projection;
|
|
||||||
// float time;
|
|
||||||
//} ubo;
|
|
||||||
|
|
||||||
layout(push_constant) uniform PushConstants {
|
layout(push_constant) uniform PushConstants {
|
||||||
mat4 model;
|
mat4 model;
|
||||||
mat4 view;
|
mat4 view;
|
||||||
|
|||||||
125
src/vulkan.rs
125
src/vulkan.rs
@@ -1,5 +1,5 @@
|
|||||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, CpuBufferPool};
|
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
|
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, AutoCommandBuffer};
|
||||||
use vulkano::device::{Device, DeviceExtensions, Queue};
|
use vulkano::device::{Device, DeviceExtensions, Queue};
|
||||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
|
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
|
||||||
use vulkano::image::{SwapchainImage, AttachmentImage, ImageUsage, ImmutableImage, Dimensions};
|
use vulkano::image::{SwapchainImage, AttachmentImage, ImageUsage, ImmutableImage, Dimensions};
|
||||||
@@ -14,7 +14,7 @@ use vulkano::sync;
|
|||||||
use vulkano::format::{Format, ClearValue};
|
use vulkano::format::{Format, ClearValue};
|
||||||
use vulkano::instance::debug::{DebugCallback, MessageTypes};
|
use vulkano::instance::debug::{DebugCallback, MessageTypes};
|
||||||
use vulkano::memory::pool::{PotentialDedicatedAllocation, StdMemoryPoolAlloc};
|
use vulkano::memory::pool::{PotentialDedicatedAllocation, StdMemoryPoolAlloc};
|
||||||
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, FixedSizeDescriptorSetsPool, FixedSizeDescriptorSet, PersistentDescriptorSetBuf, PersistentDescriptorSetSampler};
|
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, FixedSizeDescriptorSetsPool, FixedSizeDescriptorSet};
|
||||||
use vulkano::descriptor::DescriptorSet;
|
use vulkano::descriptor::DescriptorSet;
|
||||||
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
|
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
|
||||||
|
|
||||||
@@ -71,14 +71,13 @@ pub struct Mesh {
|
|||||||
pub struct GameObject {
|
pub struct GameObject {
|
||||||
pub mesh_index: usize,
|
pub mesh_index: usize,
|
||||||
pub texture_index: usize,
|
pub texture_index: usize,
|
||||||
pub descriptor_set: Arc<DescriptorSet + Send + Sync>,
|
|
||||||
pub model_matrix: Matrix4<f32>,
|
pub model_matrix: Matrix4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type GameObjectHandle = usize;
|
pub(crate) type GameObjectHandle = usize;
|
||||||
pub(crate) type MeshHandle = usize;
|
pub(crate) type MeshHandle = usize;
|
||||||
|
|
||||||
//type FixedGraphicsDescriptorSet = std::sync::Arc<FixedSizeDescriptorSet<std::sync::Arc<dyn GraphicsPipelineAbstract + std::marker::Send + std::marker::Sync>, (((), PersistentDescriptorSetSampler), PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<vs::ty::UniformBufferObject>>>)>>;
|
type FixedGraphicsDescriptorSet = Arc<FixedSizeDescriptorSet<Arc<GraphicsPipelineAbstract + Send + Sync>, ((), vulkano::descriptor::descriptor_set::PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::CpuAccessibleBuffer<vs::ty::UniformBufferObject>>>)>>;
|
||||||
|
|
||||||
pub struct GameData {
|
pub struct GameData {
|
||||||
pub start_time: SystemTime,
|
pub start_time: SystemTime,
|
||||||
@@ -98,7 +97,6 @@ pub struct VulkanRenderer {
|
|||||||
pub device: Arc<Device>,
|
pub device: Arc<Device>,
|
||||||
pub framebuffers: Vec<Arc<FramebufferAbstract + Send + Sync>>,
|
pub framebuffers: Vec<Arc<FramebufferAbstract + Send + Sync>>,
|
||||||
pub sampler: Arc<Sampler>,
|
pub sampler: Arc<Sampler>,
|
||||||
pub default_descriptor_set: Arc<DescriptorSet + Send + Sync>,
|
|
||||||
pub dynamic_state: DynamicState,
|
pub dynamic_state: DynamicState,
|
||||||
pub pipeline: Arc<GraphicsPipelineAbstract + Send + Sync>,
|
pub pipeline: Arc<GraphicsPipelineAbstract + Send + Sync>,
|
||||||
pub line_pipeline: Arc<GraphicsPipelineAbstract + Send + Sync>,
|
pub line_pipeline: Arc<GraphicsPipelineAbstract + Send + Sync>,
|
||||||
@@ -111,7 +109,8 @@ pub struct VulkanRenderer {
|
|||||||
pub recreate_swapchain: bool,
|
pub recreate_swapchain: bool,
|
||||||
pub debug_callback: Option<DebugCallback>,
|
pub debug_callback: Option<DebugCallback>,
|
||||||
pub previous_frame_end: Option<Box<GpuFuture>>,
|
pub previous_frame_end: Option<Box<GpuFuture>>,
|
||||||
// pub uniform_buffers: CpuBufferPool<vs::ty::UniformBufferObject>,
|
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::UniformBufferObject>>>,
|
||||||
|
pub descriptor_sets: Vec<FixedGraphicsDescriptorSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RenderLoopResult {
|
pub enum RenderLoopResult {
|
||||||
@@ -155,9 +154,9 @@ impl VulkanRenderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let app_info = ApplicationInfo {
|
let app_info = ApplicationInfo {
|
||||||
application_name: Some("Asuro Editor".into()),
|
application_name: Some("Asuro's Editor".into()),
|
||||||
application_version: Some(Version { major: 0, minor: 1, patch: 0 }),
|
application_version: Some(Version { major: 0, minor: 1, patch: 0 }),
|
||||||
engine_name: Some("Asuro Rust Engine".into()),
|
engine_name: Some("Asuro's Rust Engine".into()),
|
||||||
engine_version: Some(Version { major: 0, minor: 1, patch: 0 })
|
engine_version: Some(Version { major: 0, minor: 1, patch: 0 })
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -222,26 +221,9 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
let (swapchain, images) = {
|
let (swapchain, images) = {
|
||||||
let caps = surface.capabilities(physical).unwrap();
|
let caps = surface.capabilities(physical).unwrap();
|
||||||
|
|
||||||
let usage = caps.supported_usage_flags;
|
let usage = caps.supported_usage_flags;
|
||||||
|
|
||||||
// The alpha mode indicates how the alpha value of the final image will behave. For example
|
|
||||||
// you can choose whether the window will be opaque or transparent.
|
|
||||||
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
||||||
|
|
||||||
// Choosing the internal format that the images will have.
|
|
||||||
let format = caps.supported_formats[0].0;
|
let format = caps.supported_formats[0].0;
|
||||||
|
|
||||||
// The dimensions of the window, only used to initially setup the swapchain.
|
|
||||||
// NOTE:
|
|
||||||
// On some drivers the swapchain dimensions are specified by `caps.current_extent` and the
|
|
||||||
// swapchain size must use these dimensions.
|
|
||||||
// These dimensions are always the same as the window dimensions
|
|
||||||
//
|
|
||||||
// However other drivers dont specify a value i.e. `caps.current_extent` is `None`
|
|
||||||
// These drivers will allow anything but the only sensible value is the window dimensions.
|
|
||||||
//
|
|
||||||
// Because for both of these cases, the swapchain needs to be the window dimensions, we just use that.
|
|
||||||
data.dimensions = if let Some(dimensions) = window.get_inner_size() {
|
data.dimensions = if let Some(dimensions) = window.get_inner_size() {
|
||||||
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
|
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
|
||||||
[dimensions.0, dimensions.1]
|
[dimensions.0, dimensions.1]
|
||||||
@@ -304,11 +286,6 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
default_tex_future.flush().unwrap();
|
default_tex_future.flush().unwrap();
|
||||||
|
|
||||||
let default_descriptor_set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
|
||||||
.add_sampled_image(default_tex.clone(), sampler.clone()).unwrap()
|
|
||||||
.build().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
data.textures.push(default_tex);
|
data.textures.push(default_tex);
|
||||||
|
|
||||||
// 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
|
||||||
@@ -319,7 +296,33 @@ impl VulkanRenderer {
|
|||||||
// can draw we also need to create the actual framebuffers.
|
// can draw we also need to create the actual framebuffers.
|
||||||
let framebuffers = window_size_dependent_setup(device.clone(), &images, render_pass.clone(), &mut dynamic_state);
|
let framebuffers = window_size_dependent_setup(device.clone(), &images, render_pass.clone(), &mut dynamic_state);
|
||||||
|
|
||||||
// let uniform_buffers = CpuBufferPool::<vs::ty::UniformBufferObject>::new(device.clone(), BufferUsage::all());
|
let mut uniform_buffers = Vec::new();
|
||||||
|
let uniform_buffer = vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 };
|
||||||
|
|
||||||
|
for _ in 0..swapchain.num_images() {
|
||||||
|
uniform_buffers.push(CpuAccessibleBuffer::from_data(
|
||||||
|
device.clone(),
|
||||||
|
BufferUsage::uniform_buffer_transfer_destination(),
|
||||||
|
uniform_buffer,
|
||||||
|
).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let descriptor_set_pool = Mutex::new(FixedSizeDescriptorSetsPool::new(pipeline.clone(), 0));
|
||||||
|
let descriptor_sets = uniform_buffers
|
||||||
|
.iter()
|
||||||
|
.map(|uniform_buffer|
|
||||||
|
Arc::new(
|
||||||
|
descriptor_set_pool
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.next()
|
||||||
|
.add_buffer(uniform_buffer.clone())
|
||||||
|
.unwrap()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
// In the loop below we are going to submit commands to the GPU. Submitting a command produces
|
// In the loop below we are going to submit commands to the GPU. Submitting a command produces
|
||||||
// an object that implements the `GpuFuture` trait, which holds the resources for as long as
|
// an object that implements the `GpuFuture` trait, which holds the resources for as long as
|
||||||
@@ -330,11 +333,39 @@ impl VulkanRenderer {
|
|||||||
let previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<dyn GpuFuture>);
|
let previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<dyn GpuFuture>);
|
||||||
|
|
||||||
VulkanRenderer { game_data: data, device, framebuffers, sampler,
|
VulkanRenderer { game_data: data, device, framebuffers, sampler,
|
||||||
dynamic_state, pipeline, line_pipeline, default_descriptor_set,
|
dynamic_state, pipeline, line_pipeline, uniform_buffers, descriptor_sets,
|
||||||
surface, swapchain, render_pass, queue, line_vertex_buffer, events_loop,
|
surface, swapchain, render_pass, queue, line_vertex_buffer, events_loop,
|
||||||
recreate_swapchain: false, debug_callback, previous_frame_end }
|
recreate_swapchain: false, debug_callback, previous_frame_end }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_command_buffers(self: &mut Self) -> Vec<Arc<AutoCommandBuffer>> {
|
||||||
|
let mut buffers = Vec::new();
|
||||||
|
for fb_index in 0..self.framebuffers.len() {
|
||||||
|
let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap()
|
||||||
|
.update_buffer(self.uniform_buffers[fb_index].clone(), vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 }).unwrap()
|
||||||
|
.begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||||
|
|
||||||
|
for i in 0..self.game_data.game_objects.len() {
|
||||||
|
let game_object = &self.game_data.game_objects[i];
|
||||||
|
let mesh = &self.game_data.meshes[game_object.mesh_index];
|
||||||
|
self.game_data.push_constants.model = game_object.model_matrix.into();
|
||||||
|
cbb = cbb.draw_indexed(
|
||||||
|
self.pipeline.clone(),
|
||||||
|
&self.dynamic_state,
|
||||||
|
vec![mesh.vertex_buffer.clone()],
|
||||||
|
mesh.index_buffer.clone(),
|
||||||
|
self.descriptor_sets[fb_index].clone(),
|
||||||
|
self.game_data.push_constants.clone()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap()
|
||||||
|
.end_render_pass().unwrap();
|
||||||
|
|
||||||
|
buffers.push(Arc::new(cbb.build().unwrap()));
|
||||||
|
}
|
||||||
|
buffers
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_loop(self: &mut Self, game: &mut dyn Game) -> RenderLoopResult {
|
pub fn render_loop(self: &mut Self, game: &mut dyn Game) -> RenderLoopResult {
|
||||||
// It is important to call this function from time to time, otherwise resources will keep
|
// It is important to call this function from time to time, otherwise resources will keep
|
||||||
// accumulating and you will eventually reach an out of memory error.
|
// accumulating and you will eventually reach an out of memory error.
|
||||||
@@ -396,25 +427,7 @@ impl VulkanRenderer {
|
|||||||
Err(err) => panic!("{:?}", err)
|
Err(err) => panic!("{:?}", err)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()).unwrap()
|
let command_buffer = self.create_command_buffers()[image_num].clone();
|
||||||
.begin_render_pass(self.framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into(), ClearValue::Depth(1.0)]).unwrap();
|
|
||||||
|
|
||||||
for i in 0..self.game_data.game_objects.len() {
|
|
||||||
let game_object = &self.game_data.game_objects[i];
|
|
||||||
let mesh = &self.game_data.meshes[game_object.mesh_index];
|
|
||||||
self.game_data.push_constants.model = game_object.model_matrix.into();
|
|
||||||
cbb = cbb.draw_indexed(self.pipeline.clone(),
|
|
||||||
&self.dynamic_state,
|
|
||||||
vec![mesh.vertex_buffer.clone()],
|
|
||||||
mesh.index_buffer.clone(),
|
|
||||||
game_object.descriptor_set.clone(),
|
|
||||||
self.game_data.push_constants.clone()).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap()
|
|
||||||
.end_render_pass().unwrap();
|
|
||||||
|
|
||||||
let command_buffer = cbb.build().unwrap();
|
|
||||||
|
|
||||||
let future = self.previous_frame_end.take().unwrap().join(acquire_future)
|
let future = self.previous_frame_end.take().unwrap().join(acquire_future)
|
||||||
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
||||||
@@ -599,13 +612,7 @@ fn create_pipeline<V: vulkano::pipeline::vertex::Vertex>(device: Arc<Device>, re
|
|||||||
|
|
||||||
impl GameObject {
|
impl GameObject {
|
||||||
pub fn new(mesh: MeshHandle, texture_index: usize, renderer: &VulkanRenderer) -> GameObject {
|
pub fn new(mesh: MeshHandle, texture_index: usize, renderer: &VulkanRenderer) -> GameObject {
|
||||||
println!("Texid: {}", texture_index);
|
GameObject { mesh_index: mesh, texture_index, model_matrix: Matrix4::identity() }
|
||||||
let descriptor_set = Arc::new(PersistentDescriptorSet::start(renderer.pipeline.clone(), 0)
|
|
||||||
.add_sampled_image(renderer.game_data.textures[texture_index].clone(), renderer.sampler.clone()).unwrap()
|
|
||||||
.build().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
GameObject { mesh_index: mesh, texture_index, descriptor_set, model_matrix: Matrix4::identity() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user