fancy text
This commit is contained in:
@@ -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<u32> = 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;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct Camera {
|
||||
pub rotation: Quaternion<f32>,
|
||||
pub view: Matrix4<f32>,
|
||||
pub proj: Matrix4<f32>,
|
||||
pub ortho_proj: Matrix4<f32>,
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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<Device>) {
|
||||
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc<Device>) {
|
||||
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 });
|
||||
}
|
||||
|
||||
@@ -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::<TextVertex>()
|
||||
.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());
|
||||
|
||||
Reference in New Issue
Block a user