fancy text

This commit is contained in:
2021-08-16 02:27:00 +02:00
parent fb045f210a
commit 00d6d1c5f8
13 changed files with 52 additions and 30 deletions

View File

@@ -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;

Binary file not shown.

View File

@@ -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;

Binary file not shown.

View File

@@ -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;

Binary file not shown.

View File

@@ -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;

Binary file not shown.

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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(())

View File

@@ -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 });
}

View File

@@ -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()],
@@ -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());