Pack attributes slightly
This commit is contained in:
parent
f5648e0f94
commit
195374c716
3 changed files with 62 additions and 50 deletions
|
@ -1,12 +1,14 @@
|
||||||
use fontdue::{
|
use glyphon::{
|
||||||
layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle},
|
fontdue::{
|
||||||
Font, FontSettings,
|
layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle},
|
||||||
|
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},
|
||||||
|
|
61
src/lib.rs
61
src/lib.rs
|
@ -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(¶ms as *const Params as *const u8, size_of::<Params>())
|
||||||
¶ms 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(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue