diff --git a/shaders/text.frag b/shaders/text.frag index 06185fb..3050a76 100644 --- a/shaders/text.frag +++ b/shaders/text.frag @@ -8,6 +8,7 @@ layout(push_constant) uniform PushConstants { layout(binding = 0) uniform ObjectUniformData { mat4 view; mat4 projection; + mat4 ortho_projection; float time; vec3 light_position; vec3 light_directional_rotation; diff --git a/shaders/text.frag.spv b/shaders/text.frag.spv index 53ed97b..d4aa6e8 100644 Binary files a/shaders/text.frag.spv and b/shaders/text.frag.spv differ diff --git a/shaders/text.vert b/shaders/text.vert index f358b1b..0858bf9 100644 --- a/shaders/text.vert +++ b/shaders/text.vert @@ -8,6 +8,7 @@ layout(push_constant) uniform PushConstants { layout(binding = 0) uniform ObjectUniformData { mat4 view; mat4 projection; + mat4 ortho_projection; float time; vec3 light_position; vec3 light_directional_rotation; @@ -16,7 +17,6 @@ layout(binding = 0) uniform ObjectUniformData { 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; @@ -25,15 +25,16 @@ out gl_PerVertex { }; void main() { + float scale = 0.01; mat4 invert = mat4( - 1., 0., 0., 0., - 0., -1., 0., 0., - 0., 0., 1., 0., - 0., 0., 0., 1. + scale, 0., 0., 0., + 0., scale, 0., 0., + 0., 0., scale, 0., + 0., 0., 0., 1. ); // Vertex position in camera - gl_Position = ubo.projection * ubo.view * invert * push.model * vec4(position, 1.0); + gl_Position = ubo.ortho_projection * vec4(position, 1.0); // Just interpolate UV coords, no transformation needed tex_coords = uv; diff --git a/shaders/text.vert.spv b/shaders/text.vert.spv index b925dcd..d27da4f 100644 Binary files a/shaders/text.vert.spv and b/shaders/text.vert.spv differ diff --git a/shaders/triangle.frag b/shaders/triangle.frag index cc264b4..1a717f9 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -9,6 +9,7 @@ layout(push_constant) uniform PushConstants { layout(binding = 0) uniform ObjectUniformData { mat4 view; mat4 projection; + mat4 ortho_projection; float time; vec3 light_position; vec3 light_directional_rotation; diff --git a/shaders/triangle.frag.spv b/shaders/triangle.frag.spv index 779b42d..6507898 100644 Binary files a/shaders/triangle.frag.spv and b/shaders/triangle.frag.spv differ diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 90cdd93..999ae1e 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -9,6 +9,7 @@ layout(push_constant) uniform PushConstants { layout(binding = 0) uniform ObjectUniformData { mat4 view; mat4 projection; + mat4 ortho_projection; float time; vec3 light_position; vec3 light_directional_rotation; diff --git a/shaders/triangle.vert.spv b/shaders/triangle.vert.spv index 083bb83..10448f7 100644 Binary files a/shaders/triangle.vert.spv and b/shaders/triangle.vert.spv differ diff --git a/src/game/mod.rs b/src/game/mod.rs index 9aa664b..810e257 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -3,7 +3,7 @@ use cgmath::{Deg, Euler, Quaternion, vec3}; use glyph_brush::{BrushAction, BrushError, GlyphBrushBuilder, Section, Text}; use glyph_brush::ab_glyph::FontArc; use vulkano::format::Format; -use vulkano::sampler::Filter; +use vulkano::sampler::{Filter, SamplerAddressMode}; use winit::event::Event; use level::{load_level, save_level}; @@ -89,6 +89,7 @@ impl Game for TestGame { ObjectUniformData { view: self.player.camera.view.into(), projection: self.player.camera.proj.into(), + ortho_projection: self.player.camera.ortho_proj.into(), time, light_position: light_pos.into(), light_directional_rotation: [45.0, 45.0, 0.0], @@ -120,27 +121,32 @@ impl TestGame { let font = FontArc::try_from_slice(include_bytes!("../../models/OverpassRegular.ttf")).unwrap(); let mut glyph_brush = GlyphBrushBuilder::using_font(font).build(); - glyph_brush.queue(Section::default().add_text(Text::new("penis lol"))); + + let mut tex_min_size = None; + let mut tex_max_size = None; + + glyph_brush.queue(Section::default().add_text(Text::new("penis lol").with_scale(100.))); match glyph_brush.process_queued(|rect, text_data| { - renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Unorm, Filter::Nearest, renderer.device.clone()); + renderer.upload_texture(text_data, rect.width(), rect.height(), Format::R8Unorm, Filter::Nearest, SamplerAddressMode::ClampToEdge, renderer.device.clone()); self.texture_index_counter += 1; + tex_max_size = Some(u32::max(rect.width(), rect.height())); + tex_min_size = Some(u32::min(rect.width(), rect.height())); }, |vertex_data| { - println!("vd: {:?}", vertex_data); + println!("VD: {:?}", vertex_data); let result = vec![ - 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.] }, + 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] }, + 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] }, + 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] }, + 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] }, ]; result }) { Ok(BrushAction::Draw(quads)) => { - let mut final_vertices = vec![]; let mut final_indices: Vec = vec![]; let mut index_offset = 0; for quad in quads { - final_vertices.append(&mut quad.iter().map(|v| CPUVertex::VertexText(v.clone())).collect()); + final_vertices.append(&mut quad.iter().map(|v| CPUVertex::VertexText(TextVertex { position: v.position, uv: [v.uv[0], v.uv[1] * (tex_max_size.unwrap() as f32) / (tex_min_size.unwrap() as f32) ] })).collect()); final_indices.append(&mut [0, 2, 3, 0, 3, 1].iter().map(|x| *x + index_offset).collect()); index_offset += quad.len() as u32; } diff --git a/src/game/player.rs b/src/game/player.rs index 4b0d490..31b60da 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -17,6 +17,7 @@ pub struct Camera { pub rotation: Quaternion, pub view: Matrix4, pub proj: Matrix4, + pub ortho_proj: Matrix4, } impl Camera { @@ -27,6 +28,7 @@ impl Camera { rotation: Quaternion::one(), view: Matrix4::identity(), proj: Matrix4::identity(), + ortho_proj: Matrix4::identity(), } } @@ -38,15 +40,20 @@ impl Camera { // Create matrices self.view = Matrix4::from(self.rotation) * Matrix4::from_translation(self.position * -1.); + let width = renderer.game_data.dimensions[0] as f32; + let height = renderer.game_data.dimensions[1] as f32; + self.proj = cgmath::perspective( Rad::from(Deg(self.fov_y)), - renderer.game_data.dimensions[0] as f32 / renderer.game_data.dimensions[1] as f32, + width / height, 0.1, 100.0 ); // Why? self.proj.y.y *= -1.0; + self.ortho_proj = cgmath::ortho(-width / 2., width / 2., -height / 2., height / 2., -1., 1.); + // Upload renderer.game_data.line_push_constants.view = self.view.into(); renderer.game_data.line_push_constants.projection = self.proj.into(); diff --git a/src/vulkan/dds.rs b/src/vulkan/dds.rs index 4354483..5cdcb3e 100644 --- a/src/vulkan/dds.rs +++ b/src/vulkan/dds.rs @@ -1,6 +1,6 @@ use std::{convert::TryInto, io::Read}; -use vulkano::{format::Format, sampler::Filter}; +use vulkano::{format::Format, sampler::{Filter, SamplerAddressMode}}; use super::VulkanRenderer; @@ -26,14 +26,14 @@ pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Re if is_dxt1 { - renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGBUnormBlock, Filter::Linear, renderer.device.clone()); + renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGBUnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone()); } 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, renderer.device.clone()); + renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5UnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone()); } Ok(()) diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 32d213f..18d769f 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -65,9 +65,12 @@ vulkano::impl_vertex!(LinePoint, position); pub struct TextVertex { pub position: [f32; 3], pub uv: [f32; 2], - pub normal: [f32; 3], } -vulkano::impl_vertex!(TextVertex, position, uv, normal); +vulkano::impl_vertex!(TextVertex, position, uv); + +#[derive(Default, Debug, Clone)] +pub struct TextInstanceData {} +vulkano::impl_vertex!(TextInstanceData); pub trait Game { /// Returns true if event should be ignored by the vulkan handler @@ -271,6 +274,7 @@ impl VulkanRenderer { let uniform_buffer = vs::ty::ObjectUniformData { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), + ortho_projection: Matrix4::identity().into(), time: 0.0, light_position: [0.0, 0.0, 0.0], light_directional_rotation: [0.0, 0.0, 0.0], @@ -448,6 +452,7 @@ impl VulkanRenderer { 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 @@ -455,7 +460,7 @@ impl VulkanRenderer { } } - pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, device: Arc) { + pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc) { let dimensions = Dimensions::Dim2d { width, height }; let usage = ImageUsage { @@ -540,8 +545,8 @@ impl VulkanRenderer { future.flush().unwrap(); let sampler = Sampler::new(device.clone(), filter, filter, - MipmapMode::Linear, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, - SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, (image_view.mipmap_levels() - 1) as f32).unwrap(); + MipmapMode::Linear, wrap, wrap, wrap, + 0.0, 1.0, 0.0, (image_view.mipmap_levels() - 1) as f32).unwrap(); self.game_data.textures.push(Texture { image: image_view, sampler }); } diff --git a/src/vulkan/pipelines.rs b/src/vulkan/pipelines.rs index 66fb3f0..4937f2e 100644 --- a/src/vulkan/pipelines.rs +++ b/src/vulkan/pipelines.rs @@ -1,6 +1,6 @@ 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::device::Device; use vulkano::framebuffer::RenderPassAbstract; @@ -9,7 +9,7 @@ use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipelineAbstract; use vulkano::pipeline::shader::GraphicsShaderType; -use crate::{GameObject, vulkan::TextVertex}; +use crate::{GameObject, vulkan::{TextVertex}}; use crate::vulkan::{LinePoint, Vertex}; use crate::vulkan::GameData; use crate::VulkanRenderer; @@ -230,7 +230,7 @@ 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, _fb_index: usize, _game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) { builder.draw(self.pipeline.clone(), &dynamic_state, vec![self.vertex_buffer.clone()], @@ -302,7 +302,7 @@ 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 gp = Arc::new(GraphicsPipeline::start() .vertex_input_single_buffer::() .vertex_shader(vs_entry, ()) @@ -311,7 +311,7 @@ impl TextShader { .depth_stencil_simple_depth() .fragment_shader(fs_entry, ()) .blend_alpha_blending() - .cull_mode_back() + .cull_mode_disabled() .render_pass(sub_pass.clone()) .build(device.clone()) .unwrap());