Pack attributes slightly

This commit is contained in:
grovesNL 2022-05-09 11:52:38 -02:30
parent f5648e0f94
commit 195374c716
3 changed files with 62 additions and 50 deletions

View file

@ -1,12 +1,14 @@
use fontdue::{ use glyphon::{
fontdue::{
layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle}, layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle},
Font, FontSettings, Font, FontSettings,
},
Resolution, TextRenderer,
}; };
use wgpu::{ use wgpu::{
Color, CommandEncoderDescriptor, LoadOp, Operations, RenderPassColorAttachment, Color, CommandEncoderDescriptor, LoadOp, Operations, RenderPassColorAttachment,
RenderPassDescriptor, TextureViewDescriptor, RenderPassDescriptor, TextureViewDescriptor,
}; };
use glyphon::{Resolution, TextRenderer};
use winit::{ use winit::{
event::{Event, WindowEvent}, event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},

View file

@ -3,7 +3,8 @@ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
error::Error, error::Error,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
iter, mem, iter,
mem::size_of,
num::{NonZeroU32, NonZeroU64}, num::{NonZeroU32, NonZeroU64},
slice, slice,
}; };
@ -25,6 +26,8 @@ use wgpu::{
TextureViewDimension, VertexFormat, VertexState, TextureViewDimension, VertexFormat, VertexState,
}; };
pub use fontdue;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PrepareError { pub enum PrepareError {
AtlasFull, AtlasFull,
@ -53,8 +56,8 @@ enum GpuCache {
} }
struct GlyphDetails { struct GlyphDetails {
width: u32, width: u16,
height: u32, height: u16,
gpu_cache: GpuCache, gpu_cache: GpuCache,
atlas_id: Option<AllocId>, atlas_id: Option<AllocId>,
} }
@ -62,12 +65,9 @@ struct GlyphDetails {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
struct GlyphToRender { struct GlyphToRender {
x: f32, pos: [u32; 2],
y: f32, dim: [u16; 2],
width: f32, uv: [u16; 2],
height: f32,
atlas_x: f32,
atlas_y: f32,
color: [u8; 4], color: [u8; 4],
} }
@ -186,24 +186,29 @@ impl TextRenderer {
}); });
let vertex_buffers = [wgpu::VertexBufferLayout { let vertex_buffers = [wgpu::VertexBufferLayout {
array_stride: mem::size_of::<GlyphToRender>() as wgpu::BufferAddress, array_stride: size_of::<GlyphToRender>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex, step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[ attributes: &[
wgpu::VertexAttribute { wgpu::VertexAttribute {
format: VertexFormat::Float32x4, format: VertexFormat::Uint32x2,
offset: 0, offset: 0,
shader_location: 0, shader_location: 0,
}, },
wgpu::VertexAttribute { wgpu::VertexAttribute {
format: VertexFormat::Float32x2, format: VertexFormat::Uint32,
offset: mem::size_of::<f32>() as u64 * 4, offset: size_of::<u32>() as u64 * 2,
shader_location: 1, shader_location: 1,
}, },
wgpu::VertexAttribute { wgpu::VertexAttribute {
format: VertexFormat::Uint32, format: VertexFormat::Uint32,
offset: mem::size_of::<f32>() as u64 * 6, offset: size_of::<u32>() as u64 * 3,
shader_location: 2, shader_location: 2,
}, },
wgpu::VertexAttribute {
format: VertexFormat::Uint32,
offset: size_of::<u32>() as u64 * 4,
shader_location: 3,
},
], ],
}]; }];
@ -215,7 +220,7 @@ impl TextRenderer {
ty: BindingType::Buffer { ty: BindingType::Buffer {
ty: BufferBindingType::Uniform, ty: BufferBindingType::Uniform,
has_dynamic_offset: false, has_dynamic_offset: false,
min_binding_size: NonZeroU64::new(mem::size_of::<Params>() as u64), min_binding_size: NonZeroU64::new(size_of::<Params>() as u64),
}, },
count: None, count: None,
}, },
@ -242,10 +247,7 @@ impl TextRenderer {
let params = Params { screen_resolution }; let params = Params { screen_resolution };
let params_raw = unsafe { let params_raw = unsafe {
slice::from_raw_parts( slice::from_raw_parts(&params as *const Params as *const u8, size_of::<Params>())
&params as *const Params as *const u8,
mem::size_of::<Params>(),
)
}; };
let params_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let params_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
@ -354,7 +356,7 @@ impl TextRenderer {
queue.write_buffer(&self.params_buffer, 0, unsafe { queue.write_buffer(&self.params_buffer, 0, unsafe {
slice::from_raw_parts( slice::from_raw_parts(
&self.params as *const Params as *const u8, &self.params as *const Params as *const u8,
mem::size_of::<Params>(), size_of::<Params>(),
) )
}); });
} }
@ -432,8 +434,8 @@ impl TextRenderer {
self.glyph_cache.insert( self.glyph_cache.insert(
glyph.key, glyph.key,
GlyphDetails { GlyphDetails {
width: metrics.width as u32, width: metrics.width as u16,
height: metrics.height as u32, height: metrics.height as u16,
gpu_cache, gpu_cache,
atlas_id, atlas_id,
}, },
@ -481,12 +483,11 @@ impl TextRenderer {
glyph_vertices.extend( glyph_vertices.extend(
iter::repeat(GlyphToRender { iter::repeat(GlyphToRender {
x: glyph.x, // Note: subpixel positioning is not currently handled, so we always use
y: glyph.y, // the nearest pixel.
width: details.width as f32, pos: [glyph.x.round() as u32, glyph.y.round() as u32],
height: details.height as f32, dim: [details.width, details.height],
atlas_x: atlas_x as f32, uv: [atlas_x, atlas_y],
atlas_y: atlas_y as f32,
color: [255, 255, 0, 255], color: [255, 255, 0, 255],
}) })
.take(4), .take(4),
@ -511,7 +512,7 @@ impl TextRenderer {
let vertices_raw = unsafe { let vertices_raw = unsafe {
slice::from_raw_parts( slice::from_raw_parts(
vertices as *const _ as *const u8, vertices as *const _ as *const u8,
mem::size_of::<GlyphToRender>() * vertices.len(), size_of::<GlyphToRender>() * vertices.len(),
) )
}; };
@ -531,7 +532,7 @@ impl TextRenderer {
let indices_raw = unsafe { let indices_raw = unsafe {
slice::from_raw_parts( slice::from_raw_parts(
indices as *const _ as *const u8, indices as *const _ as *const u8,
mem::size_of::<u32>() * indices.len(), size_of::<u32>() * indices.len(),
) )
}; };

View file

@ -1,7 +1,15 @@
struct VertexInput {
@builtin(vertex_index) vertex_idx: u32,
@location(0) pos: vec2<u32>,
@location(1) dim: u32,
@location(2) uv: u32,
@location(3) color: u32,
}
struct VertexOutput { struct VertexOutput {
@builtin(position) position: vec4<f32>, @builtin(position) position: vec4<f32>,
@location(0) color: vec4<f32>, @location(0) color: vec4<f32>,
@location(1) tex_coords: vec2<f32>, @location(1) uv: vec2<f32>,
}; };
struct Params { struct Params {
@ -18,17 +26,15 @@ var atlas_texture: texture_2d<f32>;
var atlas_sampler: sampler; var atlas_sampler: sampler;
@vertex @vertex
fn vs_main(@builtin(vertex_index) vertex_idx: u32, @location(0) in_vert: vec4<f32>, @location(1) tex_coords: vec2<f32>, @location(2) color: u32) -> VertexOutput { fn vs_main(in_vert: VertexInput) -> VertexOutput {
let width = in_vert.z; var pos = in_vert.pos;
let height = in_vert.w; let width = in_vert.dim & 0xffffu;
let height = (in_vert.dim & 0xffff0000u) >> 16u;
let v = vertex_idx % 4u; let color = in_vert.color;
var pos = in_vert.xy; var uv = vec2<u32>(in_vert.uv & 0xffffu, (in_vert.uv & 0xffff0000u) >> 16u);
var uv = tex_coords; let v = in_vert.vertex_idx % 4u;
switch v { switch v {
case 0u: {
}
case 1u: { case 1u: {
pos.x += width; pos.x += width;
uv.x += width; uv.x += width;
@ -46,12 +52,15 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32, @location(0) in_vert: vec4<f3
default: {} default: {}
} }
pos = 2.0 * pos / vec2<f32>(params.screen_resolution) - 1.0;
pos.y *= -1.0;
var vert_output: VertexOutput; var vert_output: VertexOutput;
vert_output.position = vec4<f32>(pos.xy, 0.0, 1.0); vert_output.position = vec4<f32>(
2.0 * vec2<f32>(pos) / vec2<f32>(params.screen_resolution) - 1.0,
0.0,
1.0,
);
vert_output.position.y *= -1.0;
vert_output.color = vec4<f32>( vert_output.color = vec4<f32>(
f32((color & 0xffu)), f32((color & 0xffu)),
@ -60,12 +69,12 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32, @location(0) in_vert: vec4<f3
f32((color & 0xff000000u) >> 24u), f32((color & 0xff000000u) >> 24u),
) / 255.0; ) / 255.0;
vert_output.tex_coords = uv / vec2<f32>(textureDimensions(atlas_texture).xy); vert_output.uv = vec2<f32>(uv) / vec2<f32>(textureDimensions(atlas_texture).xy);
return vert_output; return vert_output;
} }
@fragment @fragment
fn fs_main(in_frag: VertexOutput) -> @location(0) vec4<f32> { fn fs_main(in_frag: VertexOutput) -> @location(0) vec4<f32> {
return in_frag.color * textureSample(atlas_texture, atlas_sampler, in_frag.tex_coords).x; return in_frag.color * textureSample(atlas_texture, atlas_sampler, in_frag.uv).x;
} }