vulkano reeeeeeeeeeee
This commit is contained in:
26
Cargo.toml
26
Cargo.toml
@@ -6,20 +6,20 @@ edition = "2018"
|
||||
default-run = "rust-engine"
|
||||
|
||||
[dependencies]
|
||||
vulkano-shaders = "0.20"
|
||||
vulkano = "0.20"
|
||||
vulkano-win = "0.20"
|
||||
cgmath = "0.17.0"
|
||||
winit = "0.24"
|
||||
image = "0.23.6"
|
||||
serde = "1.0.114"
|
||||
serde_json = "1.0.59"
|
||||
serde_derive = "1.0.114"
|
||||
toml = "0.5.6"
|
||||
gilrs = "0.7.4"
|
||||
gltf = "0.15.2"
|
||||
vulkano-shaders = "0.26"
|
||||
vulkano = "0.26"
|
||||
vulkano-win = "0.26"
|
||||
cgmath = "0.18.0"
|
||||
winit = "0.25"
|
||||
image = "0.23"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde_derive = "1.0"
|
||||
toml = "0.5"
|
||||
gilrs = "0.7"
|
||||
gltf = "0.15"
|
||||
glyph_brush = "0.7"
|
||||
winapi = "0.3.9"
|
||||
winapi = "0.3"
|
||||
|
||||
[profile.release]
|
||||
debug = 1
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::fs;
|
||||
use std::{convert::TryInto, fs};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use toml;
|
||||
use vulkano::image::SampleCount;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct LogConfigInput {
|
||||
@@ -33,4 +34,8 @@ impl RenderConfig {
|
||||
pub fn from_file(path: &str) -> Self {
|
||||
toml::from_slice(&fs::read(path).expect("Failed to read render config!")).expect("Failed to parse render config!")
|
||||
}
|
||||
|
||||
pub fn get_msaa(&self) -> Option<SampleCount> {
|
||||
if self.msaa_samples > 0 { self.msaa_samples.try_into().ok() } else { None }
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ impl UiQuad {
|
||||
}
|
||||
|
||||
impl Updatable for UiQuad {
|
||||
fn update(&mut self, delta_time: f32, input: &InputState, game_state: &mut GameState, game_objects: &mut Vec<GameObject>, renderer: &mut VulkanRenderer) {
|
||||
fn update(&mut self, _delta_time: f32, _input: &InputState, _game_state: &mut GameState, _game_objects: &mut Vec<GameObject>, _renderer: &mut VulkanRenderer) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -55,10 +55,6 @@ impl Camera {
|
||||
self.proj.y.y *= -1.0;
|
||||
|
||||
self.ortho_proj = cgmath::ortho(0., width, 0., height, -1., 1.);
|
||||
|
||||
// Upload
|
||||
renderer.game_data.line_push_constants.view = self.view.into();
|
||||
renderer.game_data.line_push_constants.projection = self.proj.into();
|
||||
}
|
||||
|
||||
pub fn viewport_pos_to_ray_direction(&self, viewport_pos: Vector2<f64>, viewport_dimensions: [u32; 2]) -> Option<Vector3<f32>> {
|
||||
@@ -135,9 +131,9 @@ pub fn intersection_distance(ray_origin: Vector3<f32>, ray_direction: Vector3<f3
|
||||
let index_lock = mesh.index_buffer.read().unwrap();
|
||||
let vertex_lock = mesh.vertex_buffer.read().unwrap();
|
||||
(0..mesh.index_buffer.len() / 3).map(|tri_idx| {
|
||||
let vtx_a = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx * 3 ] as usize].position);
|
||||
let vtx_b = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx * 3 + 1] as usize].position);
|
||||
let vtx_c = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx * 3 + 2] as usize].position);
|
||||
let vtx_a = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx as usize * 3 ] as usize].position);
|
||||
let vtx_b = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx as usize * 3 + 1] as usize].position);
|
||||
let vtx_c = game_object.get_model_matrix() * vec4_from_pos(vertex_lock[index_lock[tri_idx as usize * 3 + 2] as usize].position);
|
||||
intersect_triangle(ray_origin, ray_direction, vtx_a.truncate().into(), vtx_b.truncate().into(), vtx_c.truncate().into())
|
||||
}).fold(None, |acc, x| {
|
||||
if let Some(smallest) = acc {
|
||||
|
||||
12
src/main.rs
12
src/main.rs
@@ -4,7 +4,7 @@ use vulkan::gameobject::GameObject;
|
||||
|
||||
use crate::config::{LogConfig, RenderConfig};
|
||||
use crate::game::TestGame;
|
||||
use crate::vulkan::{LinePoint, VulkanRenderer};
|
||||
use crate::vulkan::VulkanRenderer;
|
||||
|
||||
mod vulkan;
|
||||
mod input;
|
||||
@@ -18,17 +18,7 @@ fn main() {
|
||||
|
||||
let mut game = TestGame::new("config/input.toml", log_config);
|
||||
|
||||
let line_count = 30;
|
||||
let line_vertices = (-line_count..=line_count)
|
||||
.flat_map(|it| vec![
|
||||
LinePoint { position: [it as f32, 0., -line_count as f32] },
|
||||
LinePoint { position: [it as f32, 0., line_count as f32] },
|
||||
LinePoint { position: [-line_count as f32, 0., it as f32] },
|
||||
LinePoint { position: [line_count as f32, 0., it as f32] },
|
||||
]).collect();
|
||||
|
||||
let (mut renderer, event_loop) = VulkanRenderer::init(
|
||||
line_vertices,
|
||||
log_config.vulkan_validation_layers,
|
||||
RenderConfig::from_file("config/graphics.toml")
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use glyph_brush::{BrushAction, BrushError, GlyphBrush, GlyphBrushBuilder, GlyphVertex, Rectangle, Section, Text, ab_glyph::FontArc};
|
||||
use vulkano::{format::Format, image::Dimensions, sampler::{Filter, SamplerAddressMode}};
|
||||
use vulkano::{format::Format, image::ImageDimensions, sampler::{Filter, SamplerAddressMode}};
|
||||
|
||||
use crate::vulkan::{MeshHandle, TextVertex, TextureHandle, VulkanRenderer, gameobject::{GameObject, GameObjectHandle}, mesh::{CPUMesh, CPUVertexList}};
|
||||
|
||||
@@ -20,7 +20,7 @@ pub fn update_text(game_object_handle: GameObjectHandle, new_text: &str, new_siz
|
||||
},
|
||||
Ok(BrushAction::ReDraw) => {},
|
||||
Err(BrushError::TextureTooSmall { suggested }) => {
|
||||
let size = Dimensions::Dim2d { width: suggested.0, height: suggested.1 };
|
||||
let size = ImageDimensions::Dim2d { width: suggested.0, height: suggested.1, array_layers: 1 };
|
||||
debug_assert!(go.textures.len() == 1);
|
||||
renderer.resize_texture(go, go.textures[0], size);
|
||||
brush.resize_texture(suggested.0, suggested.1);
|
||||
@@ -70,7 +70,7 @@ pub fn update_text_texture(old_texture: Option<TextureHandle>, renderer: &mut Vu
|
||||
renderer.update_texture(tex_handle, text_data, [rect.width(), rect.height(), 1], [rect.min[0], rect.min[1], 0], renderer.device.clone());
|
||||
None
|
||||
} else {
|
||||
let tex = renderer.upload_texture(text_data, size, size, Format::R8Unorm, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone());
|
||||
let tex = renderer.upload_texture(text_data, size, size, Format::R8_UNORM, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone());
|
||||
renderer.game_data.textures.push(tex.clone());
|
||||
Some(renderer.game_data.textures.len() - 1)
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Re
|
||||
println!("Texture width: {}, height: {}, bytes: {}", tex_width, tex_height, tex_byte_count);
|
||||
|
||||
let texture = if is_dxt1 {
|
||||
renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGBUnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
|
||||
renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGB_UNORM_BLOCK, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
|
||||
} else if is_dx10 {
|
||||
let dxgi_type = u32::from_ne_bytes(tex_bytes[128..132].try_into()?);
|
||||
assert!(dxgi_type == 83); // BC5 Unorm Typeless
|
||||
|
||||
renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5UnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
|
||||
renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5_UNORM_BLOCK, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
|
||||
} else {
|
||||
panic!("Unknown texture type!");
|
||||
};
|
||||
@@ -40,8 +40,8 @@ pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Re
|
||||
|
||||
pub fn get_block_size(format: Format) -> Option<u32> {
|
||||
match format {
|
||||
Format::BC1_RGBUnormBlock => Some(8),
|
||||
Format::BC5UnormBlock => Some(16),
|
||||
Format::BC1_RGB_UNORM_BLOCK => Some(8),
|
||||
Format::BC5_UNORM_BLOCK => Some(16),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::format::Format;
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract};
|
||||
use vulkano::image::{AttachmentImage, ImageUsage, SwapchainImage};
|
||||
use vulkano::image::view::ImageView;
|
||||
use vulkano::image::{AttachmentImage, ImageUsage, SampleCount, SwapchainImage};
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::render_pass::{Framebuffer, FramebufferAbstract, RenderPass};
|
||||
use winit::window::Window;
|
||||
use vulkano::swapchain::Swapchain;
|
||||
|
||||
@@ -13,29 +13,21 @@ use vulkano::swapchain::Swapchain;
|
||||
pub fn create_framebuffers(device: Arc<Device>,
|
||||
swapchain: &Arc<Swapchain<Window>>,
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
msaa_sample_count: u32,
|
||||
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
||||
dynamic_state: &mut DynamicState)
|
||||
msaa_sample_count: Option<SampleCount>,
|
||||
render_pass: Arc<RenderPass>)
|
||||
-> Vec<Arc<dyn FramebufferAbstract + Send + Sync>> {
|
||||
|
||||
let dim_array = images[0].dimensions();
|
||||
let dim_array_f32 = [dim_array[0] as f32, dim_array[1] as f32];
|
||||
|
||||
let viewport = Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: dim_array_f32,
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
dynamic_state.viewports = Some(vec!(viewport));
|
||||
|
||||
let depth_image = if msaa_sample_count > 0 {
|
||||
AttachmentImage::multisampled_with_usage(device.clone(), dim_array, msaa_sample_count, Format::D16Unorm, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
let depth_image = if let Some(sample_count) = msaa_sample_count {
|
||||
AttachmentImage::multisampled_with_usage(device.clone(), dim_array, sample_count, Format::D16_UNORM, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
} else {
|
||||
AttachmentImage::with_usage(device.clone(), dim_array, Format::D16Unorm, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
AttachmentImage::with_usage(device.clone(), dim_array, Format::D16_UNORM, ImageUsage { depth_stencil_attachment: true, ..ImageUsage::none() }).unwrap()
|
||||
};
|
||||
let depth_image_view = ImageView::new(depth_image.clone()).unwrap();
|
||||
|
||||
let msaa_buffers = if msaa_sample_count > 0 {
|
||||
Some(create_msaa_buffers(device.clone(), dim_array, swapchain, msaa_sample_count))
|
||||
let msaa_buffers = if let Some(sample_count) = msaa_sample_count {
|
||||
Some(create_msaa_buffers(device.clone(), dim_array, swapchain, sample_count))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -44,18 +36,21 @@ pub fn create_framebuffers(device: Arc<Device>,
|
||||
|
||||
for i in 0..images.len() {
|
||||
let image_buffer = &images[i];
|
||||
let view = ImageView::new(image_buffer.clone()).unwrap();
|
||||
|
||||
if let Some(msaa_buffers_exist) = &msaa_buffers {
|
||||
let msaa_view = ImageView::new((&msaa_buffers_exist[i]).clone()).unwrap();
|
||||
|
||||
framebuffers.push(Arc::new(Framebuffer::start(render_pass.clone())
|
||||
.add(image_buffer.clone()).unwrap()
|
||||
.add((&msaa_buffers_exist[i]).clone()).unwrap()
|
||||
.add(depth_image.clone()).unwrap()
|
||||
.add(view).unwrap()
|
||||
.add(msaa_view).unwrap()
|
||||
.add(depth_image_view.clone()).unwrap()
|
||||
.build().unwrap()
|
||||
) as Arc<dyn FramebufferAbstract + Send + Sync>);
|
||||
} else {
|
||||
framebuffers.push(Arc::new(Framebuffer::start(render_pass.clone())
|
||||
.add(image_buffer.clone()).unwrap()
|
||||
.add(depth_image.clone()).unwrap()
|
||||
.add(view).unwrap()
|
||||
.add(depth_image_view.clone()).unwrap()
|
||||
.build().unwrap()
|
||||
) as Arc<dyn FramebufferAbstract + Send + Sync>);
|
||||
}
|
||||
@@ -64,7 +59,7 @@ pub fn create_framebuffers(device: Arc<Device>,
|
||||
framebuffers
|
||||
}
|
||||
|
||||
fn create_msaa_buffers(device: Arc<Device>, dimensions: [u32; 2], swapchain: &Arc<Swapchain<Window>>, sample_count: u32) -> Vec<Arc<AttachmentImage>> {
|
||||
fn create_msaa_buffers(device: Arc<Device>, dimensions: [u32; 2], swapchain: &Arc<Swapchain<Window>>, sample_count: SampleCount) -> Vec<Arc<AttachmentImage>> {
|
||||
let mut msaa_attachments = vec![];
|
||||
for _ in 0..swapchain.num_images() {
|
||||
msaa_attachments.push(AttachmentImage::transient_multisampled(device.clone(), dimensions, sample_count, swapchain.format()).unwrap());
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use cgmath::{Deg, Euler, Matrix4, Quaternion, Vector3};
|
||||
use vulkano::descriptor_set::PersistentDescriptorSet;
|
||||
|
||||
use crate::game::GameState;
|
||||
use crate::input::InputState;
|
||||
use crate::vulkan::{RendererDescriptorSets, TextureHandle};
|
||||
use crate::vulkan::TextureHandle;
|
||||
use crate::vulkan::{MeshHandle, VulkanRenderer};
|
||||
|
||||
use super::pipelines::vs;
|
||||
use super::pipelines::{vs, vs_text};
|
||||
|
||||
pub trait PushConstant {}
|
||||
impl PushConstant for vs::ty::PushConstants {}
|
||||
impl PushConstant for vs_text::ty::PushConstants {}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GameObject {
|
||||
@@ -17,7 +22,7 @@ pub struct GameObject {
|
||||
pub rotation: Quaternion<f32>,
|
||||
pub scale: Vector3<f32>,
|
||||
pub children: Vec<GameObject>,
|
||||
pub descriptor_sets: Vec<Vec<Arc<RendererDescriptorSets>>>,
|
||||
pub descriptor_sets: Vec<Vec<Arc<PersistentDescriptorSet>>>,
|
||||
pub is_selected: bool,
|
||||
pub pipeline_index: usize,
|
||||
pub visible: bool,
|
||||
@@ -60,11 +65,11 @@ impl GameObject {
|
||||
self.rotation = self.rotation * Quaternion::from(Euler::new(Deg(x), Deg(y), Deg(z)));
|
||||
}
|
||||
|
||||
pub fn get_push_constants(&self) -> vs::ty::PushConstants {
|
||||
vs::ty::PushConstants {
|
||||
pub fn get_push_constants(&self) -> Box<dyn PushConstant> {
|
||||
Box::new(vs::ty::PushConstants {
|
||||
model: self.get_model_matrix().into(),
|
||||
is_selected: if self.is_selected { 1 } else { 0 },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_model_matrix(&self) -> Matrix4<f32> {
|
||||
|
||||
@@ -3,14 +3,15 @@ use std::time::SystemTime;
|
||||
|
||||
use cgmath::{Matrix4, SquareMatrix};
|
||||
use dds::get_block_size;
|
||||
use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::{CommandBuffer, SubpassContents}, image::{ImageAccess, ImageLayout, ImageUsage, MipmapsCount, immutable::SubImage}};
|
||||
use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState};
|
||||
use vulkano::descriptor::DescriptorSet;
|
||||
use vulkano::device::{Device, DeviceExtensions, Queue};
|
||||
use vulkano::device::physical::PhysicalDevice;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::render_pass::{FramebufferAbstract, RenderPass};
|
||||
use vulkano::{buffer::{BufferUsage, CpuAccessibleBuffer}, command_buffer::SubpassContents, image::{ImageAccess, ImageLayout, ImageUsage, MipmapsCount, immutable::SubImage}};
|
||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, PrimaryCommandBuffer};
|
||||
use vulkano::device::{Device, DeviceExtensions, Features, Queue};
|
||||
use vulkano::format::{ClearValue, Format};
|
||||
use vulkano::framebuffer::{RenderPassAbstract, FramebufferAbstract};
|
||||
use vulkano::image::{Dimensions, ImmutableImage};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, PhysicalDevice, Version};
|
||||
use vulkano::image::{ImageCreateFlags, ImageDimensions, ImmutableImage};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, Version};
|
||||
use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{AcquireError, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
@@ -20,13 +21,12 @@ use vulkano::sync;
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
|
||||
use mesh::CPUMesh;
|
||||
use pipelines::{Drawcall};
|
||||
use pipelines::line_vs::ty::LinePushConstants;
|
||||
use pipelines::{DefaultShader, TextShader};
|
||||
use pipelines::vs;
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
|
||||
use crate::config::RenderConfig;
|
||||
use crate::vulkan::gameobject::GameObject;
|
||||
@@ -100,14 +100,12 @@ pub struct MeshHandle {
|
||||
pub(crate) type TextureHandle = usize;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Texture {
|
||||
pub image: Arc<ImmutableImage<Format>>,
|
||||
pub image: Arc<ImmutableImage>,
|
||||
pub sampler: Arc<Sampler>
|
||||
}
|
||||
|
||||
pub struct GameData {
|
||||
pub start_time: SystemTime,
|
||||
pub line_vertices: Vec<LinePoint>,
|
||||
pub line_push_constants: LinePushConstants,
|
||||
pub recreate_pipeline: bool,
|
||||
pub dimensions: [u32; 2],
|
||||
pub shutdown: bool,
|
||||
@@ -121,38 +119,30 @@ pub struct GameData {
|
||||
pub performance_counter_index: usize,
|
||||
}
|
||||
|
||||
pub(crate) type RendererDescriptorSets = dyn DescriptorSet + Send + Sync;
|
||||
|
||||
pub struct VulkanRenderer {
|
||||
pub game_data: GameData,
|
||||
pub device: Arc<Device>,
|
||||
pub framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
||||
pub dynamic_state: DynamicState,
|
||||
pub pipelines: Vec<Box<dyn Drawcall>>,
|
||||
pub surface: Arc<Surface<Window>>,
|
||||
pub swapchain: Arc<Swapchain<Window>>,
|
||||
pub render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
||||
pub render_pass: Arc<RenderPass>,
|
||||
pub queue: Arc<Queue>,
|
||||
pub recreate_swapchain: bool,
|
||||
pub debug_callback: Option<DebugCallback>,
|
||||
pub previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::ObjectUniformData>>>,
|
||||
pub render_config: RenderConfig
|
||||
pub render_config: RenderConfig,
|
||||
pub viewport: Viewport
|
||||
}
|
||||
|
||||
impl VulkanRenderer {
|
||||
pub fn init(line_vertices: Vec<LinePoint>, enable_validation_layers: bool, render_config: RenderConfig) -> (VulkanRenderer, EventLoop<()>) {
|
||||
pub fn init(enable_validation_layers: bool, render_config: RenderConfig) -> (VulkanRenderer, EventLoop<()>) {
|
||||
// Create empty game data struct to be filled
|
||||
let mut data = GameData {
|
||||
line_push_constants: LinePushConstants {
|
||||
model: Matrix4::identity().into(),
|
||||
view: Matrix4::identity().into(),
|
||||
projection: Matrix4::identity().into(),
|
||||
},
|
||||
start_time: SystemTime::now(),
|
||||
recreate_pipeline: false,
|
||||
shutdown: false,
|
||||
line_vertices,
|
||||
dimensions: [0, 0],
|
||||
meshes: vec![],
|
||||
meshes_text: vec![],
|
||||
@@ -190,9 +180,9 @@ impl VulkanRenderer {
|
||||
}
|
||||
});
|
||||
|
||||
Instance::new(Some(&app_info), &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
|
||||
Instance::new(Some(&app_info), Version::V1_1, &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
|
||||
} else {
|
||||
Instance::new(Some(&app_info), &extensions, None).expect("failed to create Vulkan instance")
|
||||
Instance::new(Some(&app_info), Version::V1_1, &extensions, None).expect("failed to create Vulkan instance")
|
||||
}
|
||||
};
|
||||
|
||||
@@ -224,13 +214,12 @@ impl VulkanRenderer {
|
||||
|
||||
let layer_str = msg.layer_prefix;
|
||||
|
||||
println!("[{}][{}]: {}", type_str, layer_str, msg.description);
|
||||
println!("[{}][{}]: {}", type_str, layer_str.unwrap_or(""), msg.description);
|
||||
}).ok();
|
||||
}
|
||||
|
||||
// TODO: Create device selector
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let events_loop = EventLoop::new();
|
||||
let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
@@ -242,7 +231,7 @@ impl VulkanRenderer {
|
||||
}).unwrap();
|
||||
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, ..DeviceExtensions::none() };
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
|
||||
let (device, mut queues) = Device::new(physical, &Features::none(), &device_ext,
|
||||
[(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
@@ -255,9 +244,27 @@ impl VulkanRenderer {
|
||||
let inner_size = window.inner_size();
|
||||
data.dimensions = [inner_size.width, inner_size.height];
|
||||
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
|
||||
data.dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
|
||||
PresentMode::Fifo, FullscreenExclusive::Default, true, color_space).unwrap()
|
||||
Swapchain::start(device.clone(), surface.clone())
|
||||
.num_images(caps.min_image_count)
|
||||
.format(format)
|
||||
.dimensions(data.dimensions)
|
||||
.layers(1)
|
||||
.usage(usage)
|
||||
.sharing_mode(&queue)
|
||||
.transform(SurfaceTransform::Identity)
|
||||
.composite_alpha(alpha)
|
||||
.present_mode(PresentMode::Fifo)
|
||||
.fullscreen_exclusive(FullscreenExclusive::Default)
|
||||
.clipped(true)
|
||||
.color_space(color_space)
|
||||
.build().unwrap()
|
||||
};
|
||||
|
||||
let size = images[0].dimensions().width_height();
|
||||
let viewport = Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [size[0] as f32, size[1] as f32],
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
|
||||
// Render pass
|
||||
@@ -269,15 +276,9 @@ impl VulkanRenderer {
|
||||
Box::new(TextShader::new(device.clone(), render_pass_text.clone())),
|
||||
];
|
||||
|
||||
// Dynamic viewports allow us to recreate just the viewport when the window is resized
|
||||
// Otherwise we would have to recreate the whole pipeline.
|
||||
let mut dynamic_state = DynamicState { line_width: None, viewports: None, scissors: None, compare_mask: None, write_mask: None, reference: None };
|
||||
|
||||
|
||||
|
||||
// The render pass we created above only describes the layout of our framebuffers. Before we
|
||||
// can draw we also need to create the actual framebuffers.
|
||||
let framebuffers = framebuffers::create_framebuffers(device.clone(), &swapchain, &images, render_config.msaa_samples, render_pass.clone(), &mut dynamic_state);
|
||||
let framebuffers = framebuffers::create_framebuffers(device.clone(), &swapchain, &images, render_config.get_msaa(), render_pass.clone());
|
||||
|
||||
let mut uniform_buffers = Vec::new();
|
||||
let uniform_buffer = vs::ty::ObjectUniformData {
|
||||
@@ -311,28 +312,30 @@ impl VulkanRenderer {
|
||||
let previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<dyn GpuFuture>);
|
||||
|
||||
(VulkanRenderer { game_data: data, device, framebuffers,
|
||||
dynamic_state, pipelines, uniform_buffers,
|
||||
pipelines, uniform_buffers,
|
||||
surface, swapchain, render_pass, queue,
|
||||
recreate_swapchain: false, debug_callback, previous_frame_end,
|
||||
render_config,
|
||||
render_config, viewport
|
||||
}, events_loop)
|
||||
}
|
||||
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) -> Arc<AutoCommandBuffer> {
|
||||
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) -> Arc<PrimaryAutoCommandBuffer> {
|
||||
// General setup
|
||||
let mut builder = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap();
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), uniform_buffer_data).unwrap();
|
||||
let mut builder = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
|
||||
// builder.update_buffer(self.uniform_buffers[fb_index].clone(), uniform_buffer_data).unwrap();
|
||||
if self.render_config.msaa_samples > 0 {
|
||||
builder.begin_render_pass(self.framebuffers[fb_index].clone(), SubpassContents::Inline, vec![ClearValue::None, ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||
} else {
|
||||
builder.begin_render_pass(self.framebuffers[fb_index].clone(), SubpassContents::Inline, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||
}
|
||||
|
||||
builder.set_viewport(0, [self.viewport.clone()]);
|
||||
|
||||
// Draw meshes etc.
|
||||
let mut index = 0;
|
||||
for pipeline in &self.pipelines {
|
||||
let objects = game_objects.iter().filter(|go| go.visible && go.pipeline_index == index).collect();
|
||||
pipeline.draw(&mut builder, fb_index, objects, &self.game_data, &self.dynamic_state);
|
||||
pipeline.draw(&mut builder, fb_index, objects, &self.game_data);
|
||||
index += 1;
|
||||
}
|
||||
|
||||
@@ -353,7 +356,7 @@ impl VulkanRenderer {
|
||||
let inner_size = window.inner_size();
|
||||
self.game_data.dimensions = [inner_size.width, inner_size.height];
|
||||
|
||||
let (new_swapchain, new_images) = match self.swapchain.recreate_with_dimensions(self.game_data.dimensions) {
|
||||
let (new_swapchain, new_images) = match self.swapchain.recreate().dimensions(self.game_data.dimensions).build() {
|
||||
Ok(r) => r,
|
||||
// This error tends to happen when the user is manually resizing the window.
|
||||
// Simply restarting the loop is the easiest way to fix this issue.
|
||||
@@ -364,6 +367,14 @@ impl VulkanRenderer {
|
||||
Err(err) => panic!("{:?}", err),
|
||||
};
|
||||
|
||||
let size = new_images[0].dimensions().width_height();
|
||||
|
||||
self.viewport = Viewport {
|
||||
origin: [0.0, 0.0],
|
||||
dimensions: [size[0] as f32, size[1] as f32],
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
|
||||
self.render_pass = renderpass::create_render_pass(self.device.clone(), &self.render_config, new_swapchain.format());
|
||||
|
||||
self.pipelines = vec![
|
||||
@@ -374,7 +385,7 @@ impl VulkanRenderer {
|
||||
self.swapchain = new_swapchain;
|
||||
// Because framebuffers contains an Arc on the old swapchain, we need to
|
||||
// recreate framebuffers as well.
|
||||
self.framebuffers = framebuffers::create_framebuffers(self.device.clone(), &self.swapchain, &new_images, self.render_config.msaa_samples, self.render_pass.clone(), &mut self.dynamic_state);
|
||||
self.framebuffers = framebuffers::create_framebuffers(self.device.clone(), &self.swapchain, &new_images, self.render_config.get_msaa(), self.render_pass.clone());
|
||||
|
||||
self.recreate_swapchain = false;
|
||||
}
|
||||
@@ -473,7 +484,7 @@ impl VulkanRenderer {
|
||||
}
|
||||
|
||||
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc<Device>) -> Texture {
|
||||
let dimensions = Dimensions::Dim2d { width, height };
|
||||
let dimensions = ImageDimensions::Dim2d { width, height, array_layers: 1 };
|
||||
|
||||
let usage = ImageUsage {
|
||||
transfer_destination: true,
|
||||
@@ -482,7 +493,7 @@ impl VulkanRenderer {
|
||||
..ImageUsage::none()
|
||||
};
|
||||
|
||||
let mip_maps = if format == Format::R8Uint { MipmapsCount::One } else { MipmapsCount::Log2 };
|
||||
let mip_maps = if format == Format::R8_UINT { MipmapsCount::One } else { MipmapsCount::Log2 };
|
||||
|
||||
let (image_view, initializer) = ImmutableImage::uninitialized(
|
||||
device.clone(),
|
||||
@@ -490,6 +501,7 @@ impl VulkanRenderer {
|
||||
format,
|
||||
mip_maps,
|
||||
usage,
|
||||
ImageCreateFlags::default(),
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
device.active_queue_families(),
|
||||
).unwrap();
|
||||
@@ -503,7 +515,7 @@ impl VulkanRenderer {
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
);
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap();
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
|
||||
|
||||
let mut offset = 0;
|
||||
|
||||
@@ -523,7 +535,7 @@ impl VulkanRenderer {
|
||||
[0, 0, 0],
|
||||
mip_size,
|
||||
0,
|
||||
dimensions.array_layers_with_cube(),
|
||||
dimensions.array_layers(),
|
||||
mip_index,
|
||||
).unwrap();
|
||||
};
|
||||
@@ -531,7 +543,7 @@ impl VulkanRenderer {
|
||||
if let Some(block_byte_size) = block_bytes {
|
||||
for i in 0..image_view.mipmap_levels() {
|
||||
|
||||
let mip_size = dimensions.to_image_dimensions().mipmap_dimensions(i).unwrap().width_height_depth();
|
||||
let mip_size = dimensions.mipmap_dimensions(i).unwrap().width_height_depth();
|
||||
|
||||
let mip_byte_size = (
|
||||
(u32::max(4, mip_size[0]) / 4)
|
||||
@@ -545,7 +557,7 @@ impl VulkanRenderer {
|
||||
} else {
|
||||
let mut texture_bytes: Vec<u8> = bytes.to_vec();
|
||||
texture_bytes.resize((width * height) as usize, 0u8);
|
||||
upload_bytes(&texture_bytes, 0, dimensions.to_image_dimensions().width_height_depth());
|
||||
upload_bytes(&texture_bytes, 0, dimensions.width_height_depth());
|
||||
}
|
||||
|
||||
let cb = cbb.build().unwrap();
|
||||
@@ -576,7 +588,7 @@ impl VulkanRenderer {
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
);
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap();
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
|
||||
|
||||
let upload_source = CpuAccessibleBuffer::from_iter(
|
||||
device.clone(),
|
||||
@@ -602,7 +614,7 @@ impl VulkanRenderer {
|
||||
future.flush().unwrap();
|
||||
}
|
||||
|
||||
pub fn resize_texture(&mut self, game_object: &mut GameObject, texture_handle: TextureHandle, new_size: Dimensions) {
|
||||
pub fn resize_texture(&mut self, game_object: &mut GameObject, texture_handle: TextureHandle, new_size: ImageDimensions) {
|
||||
let mut texture = &mut self.game_data.textures[texture_handle];
|
||||
|
||||
let new_image_usage = ImageUsage {
|
||||
@@ -618,6 +630,7 @@ impl VulkanRenderer {
|
||||
texture.image.format(),
|
||||
texture.image.mipmap_levels(),
|
||||
new_image_usage,
|
||||
ImageCreateFlags::default(),
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
self.device.active_queue_families(),
|
||||
).unwrap();
|
||||
@@ -640,7 +653,7 @@ impl VulkanRenderer {
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
);
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::new(self.device.clone(), self.queue.family()).unwrap();
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
|
||||
|
||||
cbb.copy_image(
|
||||
old_sub_image.clone(),
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
|
||||
|
||||
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{DescriptorSet, descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet, pipeline_layout::PipelineLayoutDesc}, pipeline::{shader::{ShaderModule}}};
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::{buffer::TypedBufferAccess, command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}, descriptor_set::PersistentDescriptorSet, image::view::ImageView, pipeline::{PipelineBindPoint, shader::ShaderModule}, render_pass::{RenderPass, Subpass}};
|
||||
use vulkano::device::Device;
|
||||
use vulkano::framebuffer::RenderPassAbstract;
|
||||
use vulkano::framebuffer::Subpass;
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::GraphicsPipelineAbstract;
|
||||
use vulkano::pipeline::shader::GraphicsShaderType;
|
||||
|
||||
use crate::{GameObject, vulkan::{TextVertex}};
|
||||
use crate::vulkan::{LinePoint, Vertex};
|
||||
use crate::{GameObject, vulkan::TextVertex};
|
||||
use crate::vulkan::Vertex;
|
||||
use crate::vulkan::GameData;
|
||||
use crate::VulkanRenderer;
|
||||
|
||||
use super::TextureHandle;
|
||||
|
||||
type RP = Arc<dyn RenderPassAbstract + Send + Sync>;
|
||||
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
|
||||
type DS = Arc<dyn DescriptorSet + Send + Sync>;
|
||||
type RP = Arc<RenderPass>;
|
||||
type GP = Arc<GraphicsPipeline>;
|
||||
type DS = Arc<PersistentDescriptorSet>;
|
||||
|
||||
pub trait Drawcall {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState);
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData);
|
||||
fn create_descriptor_sets(self: &Self, textures: &Vec<TextureHandle>, renderer: &VulkanRenderer) -> Vec<Vec<DS>>;
|
||||
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
|
||||
fn get_pipeline(self: &Self) -> &GP;
|
||||
@@ -46,7 +41,7 @@ pub struct DefaultShader {
|
||||
pipeline: GP,
|
||||
}
|
||||
|
||||
fn shader_module_from_file(device: Arc<Device>, path: &str) -> Arc<ShaderModule> {
|
||||
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();
|
||||
@@ -105,11 +100,12 @@ impl DefaultShader {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
/*
|
||||
static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
||||
let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
|
||||
|
||||
let fs_module = shader_module_from_file(device.clone(), "shaders/triangle.frag.spv");
|
||||
let fs_layout = fs::Layout(ShaderStages {
|
||||
let fs_layout = fs::MainLayout(ShaderStages {
|
||||
fragment: true,
|
||||
..ShaderStages::none()
|
||||
});
|
||||
@@ -121,14 +117,17 @@ impl DefaultShader {
|
||||
..ShaderStages::none()
|
||||
});
|
||||
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs::MainInput, vs::MainOutput, vs_layout, GraphicsShaderType::Vertex);
|
||||
*/
|
||||
let vs = vs::Shader::load(device.clone()).unwrap();
|
||||
let fs = fs::Shader::load(device.clone()).unwrap();
|
||||
|
||||
Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<Vertex>()
|
||||
.vertex_shader(vs_entry, ())
|
||||
.vertex_shader(vs.main_entry_point(), ())
|
||||
.triangle_list()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.depth_stencil_simple_depth()
|
||||
.fragment_shader(fs_entry, ())
|
||||
.fragment_shader(fs.main_entry_point(), ())
|
||||
.blend_alpha_blending()
|
||||
.cull_mode_back()
|
||||
.render_pass(sub_pass.clone())
|
||||
@@ -139,39 +138,39 @@ impl DefaultShader {
|
||||
}
|
||||
|
||||
impl Drawcall for DefaultShader {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData) {
|
||||
for i in 0..game_objects.len() {
|
||||
let game_object = &game_objects[i];
|
||||
let mesh = &game_data.meshes[game_object.mesh_index];
|
||||
let push_constants = game_object.get_push_constants();
|
||||
|
||||
builder.draw_indexed(
|
||||
self.pipeline.clone(),
|
||||
dynamic_state,
|
||||
vec![mesh.vertex_buffer.clone()],
|
||||
mesh.index_buffer.clone(),
|
||||
game_object.descriptor_sets[fb_index].clone(),
|
||||
push_constants).unwrap();
|
||||
builder
|
||||
.bind_pipeline_graphics(self.pipeline.clone())
|
||||
.bind_descriptor_sets(PipelineBindPoint::Graphics, self.pipeline.layout().clone(), 0, game_object.descriptor_sets[fb_index].clone())
|
||||
.bind_vertex_buffers(0, mesh.vertex_buffer.clone())
|
||||
.bind_index_buffer(mesh.index_buffer.clone())
|
||||
.push_constants(self.pipeline.layout().clone(), 0, push_constants)
|
||||
.draw_indexed(mesh.index_buffer.len() as u32, 1, 0, 0, 0).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn create_descriptor_sets(self: &Self, textures: &Vec<TextureHandle>, renderer: &VulkanRenderer) -> Vec<Vec<DS>> {
|
||||
let descriptor_set_layout_0 = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
|
||||
let descriptor_set_layout_0 = self.get_pipeline().layout().descriptor_set_layouts().get(0).unwrap().clone();
|
||||
|
||||
renderer.uniform_buffers.iter().map(|uniform_buffer| {
|
||||
let descriptor_set_0: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>;
|
||||
|
||||
debug_assert!(textures.len() == 2, "Expected diffuse and normal map for object shader!");
|
||||
let diffuse = &renderer.game_data.textures[textures[0]];
|
||||
let diffuse_view = ImageView::new(diffuse.image.clone()).unwrap();
|
||||
let normal_map = &renderer.game_data.textures[textures[1]];
|
||||
let normal_view = ImageView::new(normal_map.image.clone()).unwrap();
|
||||
|
||||
descriptor_set_0 = Arc::new(PersistentDescriptorSet::start(descriptor_set_layout_0.clone())
|
||||
let mut builder = PersistentDescriptorSet::start(descriptor_set_layout_0.clone());
|
||||
builder
|
||||
.add_buffer(uniform_buffer.clone()).unwrap()
|
||||
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap()
|
||||
.add_sampled_image(normal_map.image.clone(), normal_map.sampler.clone()).unwrap()
|
||||
.build().unwrap());
|
||||
.add_sampled_image(diffuse_view, diffuse.sampler.clone()).unwrap()
|
||||
.add_sampled_image(normal_view, normal_map.sampler.clone()).unwrap();
|
||||
|
||||
vec![descriptor_set_0]
|
||||
vec![Arc::new(builder.build().unwrap())]
|
||||
}).collect()
|
||||
}
|
||||
|
||||
@@ -184,6 +183,7 @@ impl Drawcall for DefaultShader {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub mod line_vs {
|
||||
vulkano_shaders::shader!{
|
||||
ty: "vertex",
|
||||
@@ -231,9 +231,8 @@ impl LineShader {
|
||||
}
|
||||
|
||||
impl Drawcall for LineShader {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, _game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, _fb_index: usize, _game_objects: Vec<&GameObject>, game_data: &GameData) {
|
||||
builder.draw(self.pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vec![self.vertex_buffer.clone()],
|
||||
(),
|
||||
game_data.line_push_constants.clone()).unwrap();
|
||||
@@ -251,6 +250,7 @@ impl Drawcall for LineShader {
|
||||
&self.pipeline
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub mod vs_text {
|
||||
vulkano_shaders::shader!{
|
||||
@@ -287,6 +287,7 @@ impl TextShader {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
/*
|
||||
static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
|
||||
let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
|
||||
|
||||
@@ -303,23 +304,27 @@ impl TextShader {
|
||||
..ShaderStages::none()
|
||||
});
|
||||
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs_text::MainInput, vs_text::MainOutput, vs_layout, GraphicsShaderType::Vertex);
|
||||
*/
|
||||
|
||||
let vs = vs_text::Shader::load(device.clone()).unwrap();
|
||||
let fs = fs_text::Shader::load(device.clone()).unwrap();
|
||||
|
||||
let gp = Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<TextVertex>()
|
||||
.vertex_shader(vs_entry, ())
|
||||
.vertex_shader(vs.main_entry_point(), ())
|
||||
.triangle_list()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.depth_stencil_simple_depth()
|
||||
.fragment_shader(fs_entry, ())
|
||||
.fragment_shader(fs.main_entry_point(), ())
|
||||
.blend_alpha_blending()
|
||||
.cull_mode_disabled()
|
||||
.render_pass(sub_pass.clone())
|
||||
.build(device.clone())
|
||||
.unwrap());
|
||||
|
||||
println!("{:?}", gp.descriptor(0, 0).unwrap().ty);
|
||||
println!("{:?}", gp.descriptor(0, 1).unwrap().ty);
|
||||
println!("{:?}", gp.descriptor(0, 2).unwrap().ty); // TODO: Why does this exist?
|
||||
// println!("{:?}", gp.descriptor(0, 0).unwrap().ty);
|
||||
// println!("{:?}", gp.descriptor(0, 1).unwrap().ty);
|
||||
// println!("{:?}", gp.descriptor(0, 2).unwrap().ty); // TODO: Why does this exist?
|
||||
|
||||
gp
|
||||
}
|
||||
@@ -327,43 +332,37 @@ impl TextShader {
|
||||
}
|
||||
|
||||
impl Drawcall for TextShader {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData) {
|
||||
for i in 0..game_objects.len() {
|
||||
let game_object = &game_objects[i];
|
||||
let mesh = &game_data.meshes_text[game_object.mesh_index];
|
||||
let push_constants = game_object.get_push_constants();
|
||||
|
||||
builder.draw_indexed(
|
||||
self.pipeline.clone(),
|
||||
dynamic_state,
|
||||
vec![mesh.vertex_buffer.clone()],
|
||||
mesh.index_buffer.clone(),
|
||||
game_object.descriptor_sets[fb_index].clone(),
|
||||
push_constants).unwrap();
|
||||
builder.bind_pipeline_graphics(self.pipeline.clone())
|
||||
.bind_descriptor_sets(PipelineBindPoint::Graphics, self.pipeline.layout().clone(), 0, game_object.descriptor_sets[fb_index].clone())
|
||||
.bind_vertex_buffers(0, mesh.vertex_buffer.clone())
|
||||
.bind_index_buffer(mesh.index_buffer.clone())
|
||||
.push_constants(self.pipeline.layout().clone(), 0, game_object.get_push_constants())
|
||||
.draw_indexed(mesh.index_buffer.len() as u32, 1, 0, 0, 0).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn create_descriptor_sets(self: &Self, textures: &Vec<TextureHandle>, renderer: &VulkanRenderer) -> Vec<Vec<DS>> {
|
||||
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
|
||||
let descriptor_set_layout = self.get_pipeline().layout().descriptor_set_layouts().get(0).unwrap().clone();
|
||||
|
||||
renderer.uniform_buffers.iter().map(|uniform_buffer| {
|
||||
let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>;
|
||||
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
|
||||
|
||||
let diffuse_index = match textures.len() {
|
||||
0 => 0,
|
||||
1 => textures[0],
|
||||
_ => panic!("Expected only diffuse map for text shader!"),
|
||||
};
|
||||
let diffuse = &renderer.game_data.textures[diffuse_index];
|
||||
let diffuse_view = ImageView::new(diffuse.image.clone()).unwrap();
|
||||
|
||||
descriptor_set = Arc::new(builder
|
||||
.add_buffer(uniform_buffer.clone()).unwrap()
|
||||
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap()
|
||||
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap() // TODO: delet this
|
||||
.build().unwrap());
|
||||
let mut builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
|
||||
builder.add_buffer(uniform_buffer.clone()).unwrap()
|
||||
.add_sampled_image(diffuse_view.clone(), diffuse.sampler.clone()).unwrap();
|
||||
|
||||
vec![descriptor_set]
|
||||
vec![Arc::new(builder.build().unwrap())]
|
||||
}).collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::RenderConfig;
|
||||
use std::sync::Arc;
|
||||
use vulkano::framebuffer::RenderPassAbstract;
|
||||
use vulkano::format::Format;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::{device::Device, format::Format, render_pass::RenderPass};
|
||||
|
||||
pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swapchain_format: Format) -> Arc<dyn RenderPassAbstract + Send + Sync> {
|
||||
pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swapchain_format: Format) -> Arc<RenderPass> {
|
||||
if render_config.msaa_samples > 0 {
|
||||
Arc::new(vulkano::single_pass_renderpass!(
|
||||
device.clone(),
|
||||
@@ -24,7 +22,7 @@ pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swa
|
||||
depth: {
|
||||
load: Clear,
|
||||
store: Store,
|
||||
format: Format::D16Unorm,
|
||||
format: Format::D16_UNORM,
|
||||
samples: render_config.msaa_samples,
|
||||
initial_layout: ImageLayout::Undefined,
|
||||
final_layout: ImageLayout::DepthStencilAttachmentOptimal,
|
||||
@@ -49,7 +47,7 @@ pub fn create_render_pass(device: Arc<Device>, render_config: &RenderConfig, swa
|
||||
depth: {
|
||||
load: Clear,
|
||||
store: Store,
|
||||
format: Format::D16Unorm,
|
||||
format: Format::D16_UNORM,
|
||||
samples: 1,
|
||||
initial_layout: ImageLayout::Undefined,
|
||||
final_layout: ImageLayout::DepthStencilAttachmentOptimal,
|
||||
|
||||
Reference in New Issue
Block a user