Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions renderer/src/pods.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(unused)]
use std::{
fmt,
mem::{self, size_of},
Expand Down Expand Up @@ -91,7 +92,6 @@ pub struct TextureVertex {
}

impl TextureVertex {
#[allow(unused)]
pub fn new(position: impl Into<Vertex>, uv: (f32, f32)) -> Self {
Self {
position: position.into(),
Expand All @@ -113,15 +113,13 @@ impl VertexLayout for TextureVertex {
}
}

#[allow(unused)]
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct ColorVertex {
pub position: Vertex,
pub color: Color,
}

#[allow(unused)]
impl ColorVertex {
pub fn new(position: impl Into<Vertex>, color: impl Into<Color>) -> Self {
Self {
Expand Down
141 changes: 71 additions & 70 deletions renderer/src/text_layer/atlas_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct AtlasRenderer {
}

impl AtlasRenderer {
pub fn new<VertexT: VertexLayout>(
pub fn new<InstanceVertexT: VertexLayout>(
device: &wgpu::Device,
atlas_format: wgpu::TextureFormat,
shader: wgpu::ShaderModuleDescriptor<'_>,
Expand All @@ -46,7 +46,8 @@ impl AtlasRenderer {
write_mask: wgpu::ColorWrites::ALL,
})];

let vertex_layout = [VertexT::layout()];
// One vertex buffer layout describing instance attributes.
let vertex_layout = [InstanceVertexT::layout()];

let pipeline = create_pipeline(
"Atlas Pipeline",
Expand All @@ -66,20 +67,15 @@ impl AtlasRenderer {
}
}

// Convert a number of instances to a batch.
pub fn batch<InstanceT: AtlasInstance>(
// Build a batch from instance data, uploading one instance per glyph.
pub fn batch_instances<InstanceVertexT: Pod>(
&self,
context: &PreparationContext,
instances: &[InstanceT],
instances: &[InstanceVertexT],
) -> Option<QuadBatch> {
if instances.is_empty() {
return None;
}
let mut vertices = Vec::with_capacity(instances.len() * 4);

for instance in instances {
vertices.extend(instance.to_vertices());
}

let device = context.device;

Expand All @@ -90,8 +86,8 @@ impl AtlasRenderer {
);

let vertex_buffer = device.create_buffer_init(&BufferInitDescriptor {
label: Some("Atlas Vertex Buffer"),
contents: bytemuck::cast_slice(&vertices),
label: Some("Atlas Instance Buffer"),
contents: bytemuck::cast_slice(instances),
usage: wgpu::BufferUsages::VERTEX,
});

Expand All @@ -107,75 +103,80 @@ impl AtlasRenderer {
}
}

pub trait AtlasInstance {
type Vertex: Pod;

fn to_vertices(&self) -> [Self::Vertex; 4];
}

// Instance vertex types used by the shaders
pub mod sdf_atlas {
use massive_geometry::{Color, Point3};

use super::AtlasInstance;
use crate::{glyph::glyph_atlas, pods::TextureColorVertex};

#[derive(Debug)]
pub struct QuadInstance {
pub atlas_rect: glyph_atlas::Rectangle,
pub vertices: [Point3; 4],
use bytemuck::{Pod, Zeroable};

use crate::pods::Color;

#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct Instance {
// pos_lt.xy, pos_rb.xy
pub pos_lt: [f32; 2],
pub pos_rb: [f32; 2],
// uv_lt.xy, uv_rb.xy
pub uv_lt: [f32; 2],
pub uv_rb: [f32; 2],
// color rgba
pub color: Color,
// depth (z in pixel space)
pub depth: f32,
}

impl AtlasInstance for QuadInstance {
type Vertex = TextureColorVertex;

fn to_vertices(&self) -> [Self::Vertex; 4] {
let r = self.atlas_rect;
// ADR: u/v normalization is done in the shader, because its probably free and we don't
// have to care about the atlas texture growing as long the rects stay the same.
let (ltx, lty) = (r.min.x as f32, r.min.y as f32);
let (rbx, rby) = (r.max.x as f32, r.max.y as f32);

let v = &self.vertices;
let color = self.color;
[
TextureColorVertex::new(v[0], (ltx, lty), color),
TextureColorVertex::new(v[1], (ltx, rby), color),
TextureColorVertex::new(v[2], (rbx, rby), color),
TextureColorVertex::new(v[3], (rbx, lty), color),
]
impl super::VertexLayout for Instance {
fn layout() -> wgpu::VertexBufferLayout<'static> {
use std::mem::size_of;
use wgpu::{BufferAddress, VertexAttribute, VertexBufferLayout, VertexStepMode};
const ATTRS: [VertexAttribute; 6] = wgpu::vertex_attr_array![
0 => Float32x2, // pos_lt
1 => Float32x2, // pos_rb
2 => Float32x2, // uv_lt
3 => Float32x2, // uv_rb
4 => Float32x4, // color
5 => Float32, // depth
];
VertexBufferLayout {
array_stride: size_of::<Instance>() as BufferAddress,
step_mode: VertexStepMode::Instance,
attributes: &ATTRS,
}
}
}
}

pub mod color_atlas {
use massive_geometry::Point3;

use super::AtlasInstance;
use crate::{glyph::glyph_atlas, pods::TextureVertex};

#[derive(Debug)]
pub struct QuadInstance {
pub atlas_rect: glyph_atlas::Rectangle,
pub vertices: [Point3; 4],
use bytemuck::{Pod, Zeroable};

use crate::pods::VertexLayout;

#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct Instance {
pub pos_lt: [f32; 2],
pub pos_rb: [f32; 2],
pub uv_lt: [f32; 2],
pub uv_rb: [f32; 2],
// depth (z in pixel space)
pub depth: f32,
}

impl AtlasInstance for QuadInstance {
type Vertex = TextureVertex;

fn to_vertices(&self) -> [Self::Vertex; 4] {
let r = self.atlas_rect;
// ADR: u/v normalization is done in the shader. Its probably free, and we don't have to
// care about the atlas texture growing as long the rects stay the same.
let (ltx, lty) = (r.min.x as f32, r.min.y as f32);
let (rbx, rby) = (r.max.x as f32, r.max.y as f32);
let v = &self.vertices;
[
TextureVertex::new(v[0], (ltx, lty)),
TextureVertex::new(v[1], (ltx, rby)),
TextureVertex::new(v[2], (rbx, rby)),
TextureVertex::new(v[3], (rbx, lty)),
]
impl VertexLayout for Instance {
fn layout() -> wgpu::VertexBufferLayout<'static> {
use std::mem::size_of;
use wgpu::{BufferAddress, VertexAttribute, VertexBufferLayout, VertexStepMode};
const ATTRS: [VertexAttribute; 5] = wgpu::vertex_attr_array![
0 => Float32x2, // pos_lt
1 => Float32x2, // pos_rb
2 => Float32x2, // uv_lt
3 => Float32x2, // uv_rb
4 => Float32, // depth
];
VertexBufferLayout {
array_stride: size_of::<Instance>() as BufferAddress,
step_mode: VertexStepMode::Instance,
attributes: &ATTRS,
}
}
}
}
Expand Down
Loading