reee
This commit is contained in:
BIN
build/debug.rdbg
BIN
build/debug.rdbg
Binary file not shown.
26
shaders/text.frag
Normal file
26
shaders/text.frag
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(push_constant) uniform PushConstants {
|
||||||
|
mat4 model;
|
||||||
|
} push;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform ObjectUniformData {
|
||||||
|
mat4 view;
|
||||||
|
mat4 projection;
|
||||||
|
float time;
|
||||||
|
vec3 light_position;
|
||||||
|
vec3 light_directional_rotation;
|
||||||
|
vec3 camera_position;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(binding = 1) uniform sampler2D diffuse_tex;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 tex_coords;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
out_color = vec4(1., 1., 1., 1.);
|
||||||
|
// out_color = vec4(1., 1., 1., texture(diffuse_tex, tex_coords).r);
|
||||||
|
}
|
||||||
BIN
shaders/text.frag.spv
Normal file
BIN
shaders/text.frag.spv
Normal file
Binary file not shown.
33
shaders/text.vert
Normal file
33
shaders/text.vert
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(push_constant) uniform PushConstants {
|
||||||
|
mat4 model;
|
||||||
|
} push;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform ObjectUniformData {
|
||||||
|
mat4 view;
|
||||||
|
mat4 projection;
|
||||||
|
float time;
|
||||||
|
vec3 light_position;
|
||||||
|
vec3 light_directional_rotation;
|
||||||
|
vec3 camera_position;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 position;
|
||||||
|
layout(location = 1) in vec2 uv;
|
||||||
|
layout(location = 2) in vec3 normal;
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 tex_coords;
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
vec4 gl_Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Vertex position in camera
|
||||||
|
gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0);
|
||||||
|
|
||||||
|
// Just interpolate UV coords, no transformation needed
|
||||||
|
tex_coords = uv;
|
||||||
|
}
|
||||||
BIN
shaders/text.vert.spv
Normal file
BIN
shaders/text.vert.spv
Normal file
Binary file not shown.
@@ -10,9 +10,9 @@ use player::Player;
|
|||||||
|
|
||||||
use crate::{config::LogConfig, vulkan};
|
use crate::{config::LogConfig, vulkan};
|
||||||
use crate::input::InputState;
|
use crate::input::InputState;
|
||||||
use crate::vulkan::{Game, MeshHandle, TextureHandle, Vertex, VulkanRenderer};
|
use crate::vulkan::{Game, MeshHandle, TextVertex, Vertex, VulkanRenderer};
|
||||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
|
||||||
use crate::vulkan::mesh::{self, CPUMesh};
|
use crate::vulkan::mesh::{self, CPUMesh, CPUVertex};
|
||||||
use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
|
use crate::vulkan::pipelines::vs::ty::ObjectUniformData;
|
||||||
|
|
||||||
pub mod player;
|
pub mod player;
|
||||||
@@ -119,30 +119,30 @@ impl TestGame {
|
|||||||
|
|
||||||
let font = FontArc::try_from_slice(include_bytes!("../../models/OverpassRegular.ttf")).unwrap();
|
let font = FontArc::try_from_slice(include_bytes!("../../models/OverpassRegular.ttf")).unwrap();
|
||||||
let mut glyph_brush = GlyphBrushBuilder::using_font(font).build();
|
let mut glyph_brush = GlyphBrushBuilder::using_font(font).build();
|
||||||
glyph_brush.queue(Section::default().add_text(Text::new("rRRRRRRRRRRRRRr")));
|
glyph_brush.queue(Section::default().add_text(Text::new("penis lol")));
|
||||||
match glyph_brush.process_queued(|rect, text_data| {
|
match glyph_brush.process_queued(|rect, text_data| {
|
||||||
renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Srgb, renderer.device.clone());
|
renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Unorm, renderer.device.clone());
|
||||||
self.texture_index_counter += 1;
|
self.texture_index_counter += 1;
|
||||||
}, |vertex_data| {
|
}, |vertex_data| {
|
||||||
vec![
|
println!("vd: {:?}", vertex_data);
|
||||||
Vertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.min.y], normal: [0., 0., 1.], ..Default::default() },
|
let result = vec![
|
||||||
Vertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.max.y], normal: [0., 0., 1.], ..Default::default() },
|
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.min.y * 256. / 10.], normal: [0., 0., 1.] },
|
||||||
]
|
TextVertex { position: [vertex_data.pixel_coords.min.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.min.x, vertex_data.tex_coords.max.y * 256. / 10.], normal: [0., 0., 1.] },
|
||||||
|
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.min.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.min.y * 256. / 10.], normal: [0., 0., 1.] },
|
||||||
|
TextVertex { position: [vertex_data.pixel_coords.max.x, vertex_data.pixel_coords.max.y, 0.], uv: [vertex_data.tex_coords.max.x, vertex_data.tex_coords.max.y * 256. / 10.], normal: [0., 0., 1.] },
|
||||||
|
];
|
||||||
|
result
|
||||||
}) {
|
}) {
|
||||||
Ok(BrushAction::Draw(quads)) => {
|
Ok(BrushAction::Draw(quads)) => {
|
||||||
|
|
||||||
let mut final_vertices = vec![];
|
let mut final_vertices = vec![];
|
||||||
let mut final_indices = vec![];
|
let mut final_indices: Vec<u32> = vec![];
|
||||||
let mut height = 0.2;
|
let mut index_offset = 0;
|
||||||
let mut index_offset = 2;
|
|
||||||
final_vertices.push(Vertex { position: [0., 0., 0.], uv: [0., 0.], normal: [0., 0., 1.], ..Default::default() });
|
|
||||||
final_vertices.push(Vertex { position: [0., height, 0.], uv: [0., 1.], normal: [0., 0., 1.], ..Default::default() });
|
|
||||||
for quad in quads {
|
for quad in quads {
|
||||||
final_vertices.append(&mut quad.clone());
|
final_vertices.append(&mut quad.iter().map(|v| CPUVertex::VertexText(v.clone())).collect());
|
||||||
final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset - 2).collect());
|
final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect());
|
||||||
index_offset += quad.len() as u32;
|
index_offset += quad.len() as u32;
|
||||||
}
|
}
|
||||||
println!("v: {:?}", final_vertices);
|
|
||||||
println!("i: {:?}", final_indices);
|
|
||||||
let mesh = CPUMesh {
|
let mesh = CPUMesh {
|
||||||
vertices: final_vertices,
|
vertices: final_vertices,
|
||||||
indices: final_indices,
|
indices: final_indices,
|
||||||
@@ -156,9 +156,10 @@ impl TestGame {
|
|||||||
diffuse_handle: self.texture_index_counter - 1,
|
diffuse_handle: self.texture_index_counter - 1,
|
||||||
normal_handle: None,
|
normal_handle: None,
|
||||||
original_path: None,
|
original_path: None,
|
||||||
|
pipeline_index: 1
|
||||||
};
|
};
|
||||||
let mut game_object_handle = self.add_game_object(renderer, mesh_handle);
|
let mut game_object_handle = self.add_game_object(renderer, mesh_handle);
|
||||||
game_object_handle.get_game_object_mut(renderer).unwrap().scale = vec3(10., 10., 10.);
|
game_object_handle.get_game_object_mut(renderer).unwrap().scale = vec3(0.1, 0.1, 0.1);
|
||||||
self.game_objects.push(game_object_handle);
|
self.game_objects.push(game_object_handle);
|
||||||
},
|
},
|
||||||
Ok(BrushAction::ReDraw) => {},
|
Ok(BrushAction::ReDraw) => {},
|
||||||
@@ -178,7 +179,7 @@ impl TestGame {
|
|||||||
let mut mesh_handles = Vec::new();
|
let mut mesh_handles = Vec::new();
|
||||||
|
|
||||||
// Load file
|
// Load file
|
||||||
let (meshes, document) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap();
|
let (meshes, document) = mesh::load_mesh::<Vertex>(gltf_path, self.log_config.mesh_load_info).unwrap();
|
||||||
|
|
||||||
for cpu_mesh in meshes.into_iter() {
|
for cpu_mesh in meshes.into_iter() {
|
||||||
// Convert file texture id to game texture id
|
// Convert file texture id to game texture id
|
||||||
@@ -191,7 +192,8 @@ impl TestGame {
|
|||||||
index: mesh_id,
|
index: mesh_id,
|
||||||
diffuse_handle: diffuse_id,
|
diffuse_handle: diffuse_id,
|
||||||
normal_handle: Some(normal_id),
|
normal_handle: Some(normal_id),
|
||||||
original_path: Some(gltf_path.to_string())
|
original_path: Some(gltf_path.to_string()),
|
||||||
|
pipeline_index: 0
|
||||||
};
|
};
|
||||||
mesh_handles.push(mesh_handle);
|
mesh_handles.push(mesh_handle);
|
||||||
}
|
}
|
||||||
@@ -211,7 +213,7 @@ impl TestGame {
|
|||||||
|
|
||||||
pub fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle) -> GameObjectHandle {
|
pub fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle) -> GameObjectHandle {
|
||||||
let obj = GameObject::new(mesh);
|
let obj = GameObject::new(mesh);
|
||||||
let obj_handle = renderer.add_game_object(obj, 0);
|
let obj_handle = renderer.add_game_object(obj);
|
||||||
self.game_objects.push(obj_handle);
|
self.game_objects.push(obj_handle);
|
||||||
self.game_objects.last().unwrap().clone()
|
self.game_objects.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ pub fn vec4_from_pos(pos: [f32; 3]) -> Vector4<f32> {
|
|||||||
vec4(pos[0], pos[1], pos[2], 1.0)
|
vec4(pos[0], pos[1], pos[2], 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersection_distance(ray_origin: Vector3<f32>, ray_direction: Vector3<f32>, mesh: &Mesh, game_object: &GameObject) -> Option<f32> {
|
pub fn intersection_distance(ray_origin: Vector3<f32>, ray_direction: Vector3<f32>, mesh: &Mesh<crate::vulkan::Vertex>, game_object: &GameObject) -> Option<f32> {
|
||||||
let index_lock = mesh.index_buffer.read().unwrap();
|
let index_lock = mesh.index_buffer.read().unwrap();
|
||||||
let vertex_lock = mesh.vertex_buffer.read().unwrap();
|
let vertex_lock = mesh.vertex_buffer.read().unwrap();
|
||||||
(0..mesh.index_buffer.len() / 3).map(|tri_idx| {
|
(0..mesh.index_buffer.len() / 3).map(|tri_idx| {
|
||||||
|
|||||||
@@ -18,14 +18,15 @@ pub struct GameObject {
|
|||||||
pub scale: Vector3<f32>,
|
pub scale: Vector3<f32>,
|
||||||
pub children: Vec<GameObject>,
|
pub children: Vec<GameObject>,
|
||||||
pub descriptor_sets: Vec<Arc<RendererDescriptorSets>>,
|
pub descriptor_sets: Vec<Arc<RendererDescriptorSets>>,
|
||||||
pub is_selected: bool
|
pub is_selected: bool,
|
||||||
|
pub pipeline_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameObject {
|
impl GameObject {
|
||||||
pub fn new(mesh: MeshHandle) -> GameObject {
|
pub fn new(mesh: MeshHandle) -> GameObject {
|
||||||
GameObject { mesh_index: mesh.index, texture_index: mesh.diffuse_handle, normal_map_index: mesh.normal_handle.unwrap_or(0), position: Vector3::new(0.0, 0.0, 0.0),
|
GameObject { mesh_index: mesh.index, texture_index: mesh.diffuse_handle, normal_map_index: mesh.normal_handle.unwrap_or(0), position: Vector3::new(0.0, 0.0, 0.0),
|
||||||
rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0), scale: Vector3::new(1.0, 1.0, 1.0), children: vec![],
|
rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0), scale: Vector3::new(1.0, 1.0, 1.0), children: vec![],
|
||||||
descriptor_sets: vec![], is_selected: false }
|
descriptor_sets: vec![], is_selected: false, pipeline_index: mesh.pipeline_index }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _set_position(&mut self, x: f32, y: f32, z: f32) {
|
pub fn _set_position(&mut self, x: f32, y: f32, z: f32) {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use gltf::mesh::util::{ReadJoints, ReadNormals, ReadPositions, ReadTangents, Rea
|
|||||||
use crate::vulkan::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices};
|
use crate::vulkan::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices};
|
||||||
use crate::vulkan::Vertex;
|
use crate::vulkan::Vertex;
|
||||||
|
|
||||||
|
use super::TextVertex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LoadError {
|
pub enum LoadError {
|
||||||
GltfError(gltf::Error),
|
GltfError(gltf::Error),
|
||||||
@@ -25,9 +27,15 @@ impl From<String> for LoadError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CPUVertex {
|
||||||
|
Vertex3D(Vertex),
|
||||||
|
VertexText(TextVertex)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CPUMesh {
|
pub struct CPUMesh {
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<CPUVertex>,
|
||||||
pub indices: Vec<u32>,
|
pub indices: Vec<u32>,
|
||||||
pub local_texture_index: Option<usize>,
|
pub local_texture_index: Option<usize>,
|
||||||
pub local_normal_map_index: Option<usize>,
|
pub local_normal_map_index: Option<usize>,
|
||||||
@@ -41,7 +49,7 @@ fn read_file(path: &str) -> Vec<u8> {
|
|||||||
glb_bytes
|
glb_bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec<CPUMesh>, Document), LoadError> {
|
pub fn load_mesh<V>(mesh_path: &str, print_status: bool) -> Result<(Vec<CPUMesh>, Document), LoadError> {
|
||||||
let mut start_time = None;
|
let mut start_time = None;
|
||||||
let mut total_vertices = 0;
|
let mut total_vertices = 0;
|
||||||
let mut total_indices = 0;
|
let mut total_indices = 0;
|
||||||
@@ -80,7 +88,7 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec<CPUMesh>, D
|
|||||||
reader.read_tangents(),
|
reader.read_tangents(),
|
||||||
reader.read_joints(0),
|
reader.read_joints(0),
|
||||||
reader.read_weights(0));
|
reader.read_weights(0));
|
||||||
let vertices = vertices_result?;
|
let vertices = vertices_result?.iter().map(|v| CPUVertex::Vertex3D(v.clone())).collect();
|
||||||
let cpu_mesh = CPUMesh {
|
let cpu_mesh = CPUMesh {
|
||||||
vertices,
|
vertices,
|
||||||
indices: indices.into_u32().collect(),
|
indices: indices.into_u32().collect(),
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ use winit::window::{Window, WindowBuilder};
|
|||||||
use mesh::CPUMesh;
|
use mesh::CPUMesh;
|
||||||
use pipelines::{Drawcall};
|
use pipelines::{Drawcall};
|
||||||
use pipelines::line_vs::ty::LinePushConstants;
|
use pipelines::line_vs::ty::LinePushConstants;
|
||||||
use pipelines::DefaultShader;
|
use pipelines::{DefaultShader, TextShader};
|
||||||
use pipelines::vs;
|
use pipelines::vs;
|
||||||
|
|
||||||
use crate::config::RenderConfig;
|
use crate::config::RenderConfig;
|
||||||
use crate::vulkan::gameobject::{GameObject, GameObjectHandle};
|
use crate::vulkan::gameobject::{GameObject, GameObjectHandle};
|
||||||
|
|
||||||
|
use self::mesh::CPUVertex;
|
||||||
|
|
||||||
pub mod pipelines;
|
pub mod pipelines;
|
||||||
pub mod gameobject;
|
pub mod gameobject;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
@@ -39,7 +41,7 @@ mod renderpass;
|
|||||||
mod framebuffers;
|
mod framebuffers;
|
||||||
|
|
||||||
const VALIDATION_LAYERS: &[&str] = &[
|
const VALIDATION_LAYERS: &[&str] = &[
|
||||||
"VK_LAYER_KHRONOS_validation"
|
"VK_LAYER_KHRONOS_validation",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
@@ -59,6 +61,14 @@ pub struct LinePoint {
|
|||||||
}
|
}
|
||||||
vulkano::impl_vertex!(LinePoint, position);
|
vulkano::impl_vertex!(LinePoint, position);
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
|
pub struct TextVertex {
|
||||||
|
pub position: [f32; 3],
|
||||||
|
pub uv: [f32; 2],
|
||||||
|
pub normal: [f32; 3],
|
||||||
|
}
|
||||||
|
vulkano::impl_vertex!(TextVertex, position, uv, normal);
|
||||||
|
|
||||||
pub trait Game {
|
pub trait Game {
|
||||||
/// Returns true if event should be ignored by the vulkan handler
|
/// Returns true if event should be ignored by the vulkan handler
|
||||||
fn on_window_event(self: &mut Self, event: &Event<()>);
|
fn on_window_event(self: &mut Self, event: &Event<()>);
|
||||||
@@ -66,8 +76,8 @@ pub trait Game {
|
|||||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> vs::ty::ObjectUniformData;
|
fn update(self: &mut Self, renderer: &mut VulkanRenderer) -> vs::ty::ObjectUniformData;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mesh {
|
pub struct Mesh<V> {
|
||||||
pub vertex_buffer: Arc<CpuAccessibleBuffer<[Vertex]>>,
|
pub vertex_buffer: Arc<CpuAccessibleBuffer<[V]>>,
|
||||||
pub index_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
|
pub index_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
|
||||||
pub original_path: Option<String>,
|
pub original_path: Option<String>,
|
||||||
}
|
}
|
||||||
@@ -77,7 +87,8 @@ pub struct MeshHandle {
|
|||||||
pub index: usize,
|
pub index: usize,
|
||||||
pub diffuse_handle: TextureHandle,
|
pub diffuse_handle: TextureHandle,
|
||||||
pub normal_handle: Option<TextureHandle>,
|
pub normal_handle: Option<TextureHandle>,
|
||||||
pub original_path: Option<String>
|
pub original_path: Option<String>,
|
||||||
|
pub pipeline_index: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type TextureHandle = usize;
|
pub(crate) type TextureHandle = usize;
|
||||||
@@ -94,9 +105,9 @@ pub struct GameData {
|
|||||||
pub dimensions: [u32; 2],
|
pub dimensions: [u32; 2],
|
||||||
pub shutdown: bool,
|
pub shutdown: bool,
|
||||||
pub game_objects: Vec<GameObject>,
|
pub game_objects: Vec<GameObject>,
|
||||||
pub meshes: Vec<Mesh>,
|
pub meshes: Vec<Mesh<Vertex>>,
|
||||||
|
pub meshes_text: Vec<Mesh<TextVertex>>,
|
||||||
pub textures: Vec<Texture>,
|
pub textures: Vec<Texture>,
|
||||||
pub use_line_pipeline: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type RendererDescriptorSets = dyn DescriptorSet + Send + Sync;
|
pub(crate) type RendererDescriptorSets = dyn DescriptorSet + Send + Sync;
|
||||||
@@ -115,7 +126,6 @@ pub struct VulkanRenderer {
|
|||||||
pub debug_callback: Option<DebugCallback>,
|
pub debug_callback: Option<DebugCallback>,
|
||||||
pub previous_frame_end: Option<Box<dyn GpuFuture>>,
|
pub previous_frame_end: Option<Box<dyn GpuFuture>>,
|
||||||
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::ObjectUniformData>>>,
|
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::ObjectUniformData>>>,
|
||||||
pub line_vertex_buffer: Arc<CpuAccessibleBuffer<[LinePoint]>>,
|
|
||||||
pub render_config: RenderConfig
|
pub render_config: RenderConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +144,9 @@ impl VulkanRenderer {
|
|||||||
line_vertices,
|
line_vertices,
|
||||||
dimensions: [0, 0],
|
dimensions: [0, 0],
|
||||||
meshes: vec![],
|
meshes: vec![],
|
||||||
|
meshes_text: vec![],
|
||||||
game_objects: vec![],
|
game_objects: vec![],
|
||||||
textures: vec![],
|
textures: vec![],
|
||||||
use_line_pipeline: true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create basic vulkan instance with layers and info
|
// Create basic vulkan instance with layers and info
|
||||||
@@ -239,12 +249,11 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
// Render pass
|
// Render pass
|
||||||
let render_pass = renderpass::create_render_pass(device.clone(), &render_config, swapchain.format());
|
let render_pass = renderpass::create_render_pass(device.clone(), &render_config, swapchain.format());
|
||||||
|
let render_pass_text = renderpass::create_render_pass(device.clone(), &render_config, swapchain.format());
|
||||||
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), false, data.line_vertices.iter().cloned()).unwrap();
|
|
||||||
|
|
||||||
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(TextShader::new(device.clone(), render_pass_text.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
|
||||||
@@ -292,7 +301,6 @@ impl VulkanRenderer {
|
|||||||
surface, swapchain, render_pass, queue,
|
surface, swapchain, render_pass, queue,
|
||||||
recreate_swapchain: false, debug_callback, previous_frame_end,
|
recreate_swapchain: false, debug_callback, previous_frame_end,
|
||||||
render_config,
|
render_config,
|
||||||
line_vertex_buffer,
|
|
||||||
}, events_loop)
|
}, events_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,8 +315,10 @@ impl VulkanRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw meshes etc.
|
// Draw meshes etc.
|
||||||
|
let mut index = 0;
|
||||||
for pipeline in &self.pipelines {
|
for pipeline in &self.pipelines {
|
||||||
pipeline.draw(&mut builder, fb_index, &self.game_data, &self.dynamic_state);
|
pipeline.draw(&mut builder, fb_index, self.game_data.game_objects.iter().filter(|go| go.pipeline_index == index).collect(), &self.game_data, &self.dynamic_state);
|
||||||
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// General cleanup
|
// General cleanup
|
||||||
@@ -343,7 +353,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(TextShader::new(self.device.clone(), self.render_pass.clone())),
|
||||||
];
|
];
|
||||||
|
|
||||||
self.swapchain = new_swapchain;
|
self.swapchain = new_swapchain;
|
||||||
@@ -420,11 +430,28 @@ impl VulkanRenderer {
|
|||||||
// collision_mesh.push_face((mesh.indices[i] as usize, mesh.indices[i + 1] as usize, mesh.indices[i + 2] as usize));
|
// collision_mesh.push_face((mesh.indices[i] as usize, mesh.indices[i + 1] as usize, mesh.indices[i + 2] as usize));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, mesh.vertices.into_iter()).unwrap();
|
let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap();
|
||||||
let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap();
|
|
||||||
|
|
||||||
self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer, original_path });
|
match mesh.vertices.get(0).unwrap() {
|
||||||
self.game_data.meshes.len() - 1
|
CPUVertex::Vertex3D(_) => {
|
||||||
|
let verts: Vec<Vertex> = mesh.vertices.into_iter().filter_map(|v| match v {
|
||||||
|
CPUVertex::Vertex3D(vert) => Some(vert),
|
||||||
|
CPUVertex::VertexText(_) => None
|
||||||
|
}).collect();
|
||||||
|
let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, verts.into_iter()).unwrap();
|
||||||
|
self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer, original_path });
|
||||||
|
self.game_data.meshes.len() - 1
|
||||||
|
},
|
||||||
|
CPUVertex::VertexText(_) => {
|
||||||
|
let verts: Vec<TextVertex> = mesh.vertices.into_iter().filter_map(|v| match v {
|
||||||
|
CPUVertex::Vertex3D(_) => None,
|
||||||
|
CPUVertex::VertexText(vert) => Some(vert)
|
||||||
|
}).collect();
|
||||||
|
let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, verts.into_iter()).unwrap();
|
||||||
|
self.game_data.meshes_text.push(Mesh { vertex_buffer, index_buffer, original_path });
|
||||||
|
self.game_data.meshes_text.len() - 1
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, device: Arc<Device>) {
|
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, device: Arc<Device>) {
|
||||||
@@ -438,7 +465,7 @@ impl VulkanRenderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let layout = ImageLayout::ShaderReadOnlyOptimal;
|
let layout = ImageLayout::ShaderReadOnlyOptimal;
|
||||||
let mip_maps = if format == Format::R8Srgb { MipmapsCount::One } else { MipmapsCount::Log2 };
|
let mip_maps = if format == Format::R8Uint { MipmapsCount::One } else { MipmapsCount::Log2 };
|
||||||
|
|
||||||
let (image_view, initializer) = ImmutableImage::uninitialized(
|
let (image_view, initializer) = ImmutableImage::uninitialized(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
@@ -518,8 +545,8 @@ impl VulkanRenderer {
|
|||||||
self.game_data.textures.push(Texture { image: image_view, sampler });
|
self.game_data.textures.push(Texture { image: image_view, sampler });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_game_object(self: &mut Self, mut game_object: GameObject, pipeline_index: usize) -> GameObjectHandle {
|
pub fn add_game_object(self: &mut Self, mut game_object: GameObject) -> GameObjectHandle {
|
||||||
self.pipelines[pipeline_index].create_descriptor_set(&mut game_object, self);
|
self.pipelines[game_object.pipeline_index].create_descriptor_set(&mut game_object, self);
|
||||||
self.game_data.game_objects.push(game_object);
|
self.game_data.game_objects.push(game_object);
|
||||||
|
|
||||||
GameObjectHandle {
|
GameObjectHandle {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
|
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::ShaderModule};
|
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;
|
||||||
@@ -9,7 +9,7 @@ use vulkano::pipeline::GraphicsPipeline;
|
|||||||
use vulkano::pipeline::GraphicsPipelineAbstract;
|
use vulkano::pipeline::GraphicsPipelineAbstract;
|
||||||
use vulkano::pipeline::shader::GraphicsShaderType;
|
use vulkano::pipeline::shader::GraphicsShaderType;
|
||||||
|
|
||||||
use crate::GameObject;
|
use crate::{GameObject, vulkan::TextVertex};
|
||||||
use crate::vulkan::{LinePoint, Vertex};
|
use crate::vulkan::{LinePoint, Vertex};
|
||||||
use crate::vulkan::GameData;
|
use crate::vulkan::GameData;
|
||||||
use crate::VulkanRenderer;
|
use crate::VulkanRenderer;
|
||||||
@@ -18,7 +18,7 @@ type RP = Arc<dyn RenderPassAbstract + Send + Sync>;
|
|||||||
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
|
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
|
||||||
|
|
||||||
pub trait Drawcall {
|
pub trait Drawcall {
|
||||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState);
|
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState);
|
||||||
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer);
|
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer);
|
||||||
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
|
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
|
||||||
fn get_pipeline(self: &Self) -> &GP;
|
fn get_pipeline(self: &Self) -> &GP;
|
||||||
@@ -136,12 +136,14 @@ impl DefaultShader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Drawcall for DefaultShader {
|
impl Drawcall for DefaultShader {
|
||||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||||
for i in 0..game_data.game_objects.len() {
|
for i in 0..game_objects.len() {
|
||||||
let game_object = &game_data.game_objects[i];
|
let game_object = &game_objects[i];
|
||||||
let mesh = &game_data.meshes[game_object.mesh_index];
|
let mesh = &game_data.meshes[game_object.mesh_index];
|
||||||
let push_constants = game_object.get_push_constants();
|
let push_constants = game_object.get_push_constants();
|
||||||
|
|
||||||
|
println!("default: {:?}", game_object.mesh_index);
|
||||||
|
|
||||||
builder.draw_indexed(
|
builder.draw_indexed(
|
||||||
self.pipeline.clone(),
|
self.pipeline.clone(),
|
||||||
dynamic_state,
|
dynamic_state,
|
||||||
@@ -230,7 +232,7 @@ impl LineShader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Drawcall for LineShader {
|
impl Drawcall for LineShader {
|
||||||
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
|
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||||
builder.draw(self.pipeline.clone(),
|
builder.draw(self.pipeline.clone(),
|
||||||
&dynamic_state,
|
&dynamic_state,
|
||||||
vec![self.vertex_buffer.clone()],
|
vec![self.vertex_buffer.clone()],
|
||||||
@@ -246,6 +248,124 @@ impl Drawcall for LineShader {
|
|||||||
self.pipeline = Self::create_pipeline(device, render_pass);
|
self.pipeline = Self::create_pipeline(device, render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_pipeline(self: &Self) -> &GP {
|
||||||
|
&self.pipeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod vs_text {
|
||||||
|
vulkano_shaders::shader!{
|
||||||
|
ty: "vertex",
|
||||||
|
path: "shaders/text.vert"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod fs_text {
|
||||||
|
vulkano_shaders::shader!{
|
||||||
|
ty: "fragment",
|
||||||
|
path: "shaders/text.frag"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TextShader {
|
||||||
|
pipeline: GP,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextShader {
|
||||||
|
pub fn new(device: Arc<Device>, render_pass: RP) -> Self {
|
||||||
|
TextShader {
|
||||||
|
pipeline: Self::create_pipeline(device, render_pass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_pipeline(device: Arc<Device>, render_pass: RP) -> GP {
|
||||||
|
let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
println!("Compiling shaders...");
|
||||||
|
compile_shaders().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
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/text.frag.spv");
|
||||||
|
let fs_layout = fs::Layout(ShaderStages {
|
||||||
|
fragment: true,
|
||||||
|
..ShaderStages::none()
|
||||||
|
});
|
||||||
|
let fs_entry = fs_module.graphics_entry_point(entry_name_c, fs_text::MainInput, fs_text::MainOutput, fs_layout, GraphicsShaderType::Fragment);
|
||||||
|
|
||||||
|
let vs_module = shader_module_from_file(device.clone(), "shaders/text.vert.spv");
|
||||||
|
let vs_layout = vs::Layout(ShaderStages {
|
||||||
|
vertex: true,
|
||||||
|
..ShaderStages::none()
|
||||||
|
});
|
||||||
|
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs_text::MainInput, vs_text::MainOutput, vs_layout, GraphicsShaderType::Vertex);
|
||||||
|
|
||||||
|
let gp = Arc::new(GraphicsPipeline::start()
|
||||||
|
.vertex_input_single_buffer::<TextVertex>()
|
||||||
|
.vertex_shader(vs_entry, ())
|
||||||
|
.triangle_list()
|
||||||
|
.viewports_dynamic_scissors_irrelevant(1)
|
||||||
|
.depth_stencil_simple_depth()
|
||||||
|
.fragment_shader(fs_entry, ())
|
||||||
|
.blend_alpha_blending()
|
||||||
|
.cull_mode_back()
|
||||||
|
.render_pass(sub_pass.clone())
|
||||||
|
.build(device.clone())
|
||||||
|
.unwrap());
|
||||||
|
|
||||||
|
println!("layout: {:?}", vulkano::descriptor::PipelineLayoutAbstract::descriptor_set_layout(&gp, 0).unwrap().descriptors_count());
|
||||||
|
gp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawcall for TextShader {
|
||||||
|
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
|
||||||
|
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();
|
||||||
|
|
||||||
|
println!("text: {:?}", game_object.mesh_index);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) {
|
||||||
|
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
|
||||||
|
|
||||||
|
game_object.descriptor_sets = 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 = &renderer.game_data.textures[game_object.texture_index];
|
||||||
|
|
||||||
|
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()
|
||||||
|
.build().unwrap());
|
||||||
|
|
||||||
|
descriptor_set
|
||||||
|
}).collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP) {
|
||||||
|
self.pipeline = Self::create_pipeline(device, render_pass);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_pipeline(self: &Self) -> &GP {
|
fn get_pipeline(self: &Self) -> &GP {
|
||||||
&self.pipeline
|
&self.pipeline
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user