Refactor and cleanup

This commit is contained in:
Maximilian Ammann 2021-12-05 12:43:16 +01:00
parent 995246bfe3
commit 5efe51ad5b
8 changed files with 211 additions and 177 deletions

View File

@ -1,7 +1,7 @@
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::{BufReader, Read}; use std::io::{BufReader, Read};
use std::path::{Path, PathBuf}; use std::path::{Path};
use protobuf::Message; use protobuf::Message;

View File

@ -1,4 +1,3 @@
mod multisampling;
mod piplines; mod piplines;
mod shader; mod shader;
mod shader_ffi; mod shader_ffi;

View File

@ -1,25 +0,0 @@
/// Creates a texture that uses MSAA and fits a given swap chain
pub fn create_multisampled_framebuffer(
device: &wgpu::Device,
desc: &wgpu::SurfaceConfiguration,
sample_count: u32,
) -> wgpu::TextureView {
let multisampled_frame_descriptor = &wgpu::TextureDescriptor {
label: Some("Multisampled frame descriptor"),
size: wgpu::Extent3d {
width: desc.width,
height: desc.height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count,
dimension: wgpu::TextureDimension::D2,
format: desc.format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
};
device
.create_texture(multisampled_frame_descriptor)
.create_view(&wgpu::TextureViewDescriptor::default())
}

View File

@ -2,18 +2,37 @@ use wgpu::{FragmentState, PipelineLayout, RenderPipelineDescriptor, VertexState}
use super::texture::DEPTH_TEXTURE_FORMAT; use super::texture::DEPTH_TEXTURE_FORMAT;
///
/// Creates a render pipeline description
///
/// # Arguments
///
/// * `pipeline_layout`:
/// * `vertex_state`:
/// * `fragment_state`:
/// * `sample_count`:
/// * `update_stencil`: Fragments passing through the pipeline will be able to update the stencil
/// buffer. This is used for masking
///
/// returns: RenderPipelineDescriptor
///
/// # Examples
///
/// ```
///
/// ```
pub fn create_map_render_pipeline_description<'a>( pub fn create_map_render_pipeline_description<'a>(
pipeline_layout: &'a PipelineLayout, pipeline_layout: &'a PipelineLayout,
vertex_state: VertexState<'a>, vertex_state: VertexState<'a>,
fragment_state: FragmentState<'a>, fragment_state: FragmentState<'a>,
sample_count: u32, sample_count: u32,
draw_mask: bool, update_stencil: bool,
) -> RenderPipelineDescriptor<'a> { ) -> RenderPipelineDescriptor<'a> {
let stencil_state = if draw_mask { let stencil_state = if update_stencil {
wgpu::StencilFaceState { wgpu::StencilFaceState {
compare: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always, // Allow ALL values to update the stencil
fail_op: wgpu::StencilOperation::Keep, fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep, depth_fail_op: wgpu::StencilOperation::Keep, // This is used when the depth test already failed
pass_op: wgpu::StencilOperation::IncrementClamp, pass_op: wgpu::StencilOperation::IncrementClamp,
} }
} else { } else {
@ -21,7 +40,7 @@ pub fn create_map_render_pipeline_description<'a>(
compare: wgpu::CompareFunction::Equal, compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep, fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep, depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep pass_op: wgpu::StencilOperation::Keep,
} }
}; };
let descriptor = wgpu::RenderPipelineDescriptor { let descriptor = wgpu::RenderPipelineDescriptor {
@ -41,12 +60,12 @@ pub fn create_map_render_pipeline_description<'a>(
depth_stencil: Some(wgpu::DepthStencilState { depth_stencil: Some(wgpu::DepthStencilState {
format: DEPTH_TEXTURE_FORMAT, format: DEPTH_TEXTURE_FORMAT,
depth_write_enabled: true, depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always, // FIXME: Effectively disable depth test depth_compare: wgpu::CompareFunction::Less,
stencil: wgpu::StencilState { stencil: wgpu::StencilState {
front: stencil_state, front: stencil_state,
back: stencil_state, back: stencil_state,
read_mask: 0xff, read_mask: 0xff, // Applied to stencil values being read from the stencil buffer
write_mask: 0xff, write_mask: 0xff, // Applied to fragment stencil values before being written to the stencil buffer
}, },
bias: wgpu::DepthBiasState::default(), bias: wgpu::DepthBiasState::default(),
}), }),

View File

@ -6,7 +6,7 @@ use wgpu::{
use super::platform_constants::COLOR_TEXTURE_FORMAT; use super::platform_constants::COLOR_TEXTURE_FORMAT;
use super::shader_ffi::GpuVertex; use super::shader_ffi::GpuVertex;
const MAP_VERTEX_SHADER_ARGUMENTS: [VertexAttribute; 3] = [ const VERTEX_SHADER_ARGUMENTS: [VertexAttribute; 3] = [
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: 0, offset: 0,
format: wgpu::VertexFormat::Float32x2, format: wgpu::VertexFormat::Float32x2,
@ -24,19 +24,19 @@ const MAP_VERTEX_SHADER_ARGUMENTS: [VertexAttribute; 3] = [
}, },
]; ];
const MAP_VERTEX_SHADER_BUFFERS: [VertexBufferLayout; 1] = [wgpu::VertexBufferLayout { const VERTEX_SHADER_BUFFERS: [VertexBufferLayout; 1] = [wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<GpuVertex>() as u64, array_stride: std::mem::size_of::<GpuVertex>() as u64,
step_mode: wgpu::VertexStepMode::Vertex, step_mode: wgpu::VertexStepMode::Vertex,
attributes: &MAP_VERTEX_SHADER_ARGUMENTS, attributes: &VERTEX_SHADER_ARGUMENTS,
}]; }];
const MAP_VERTEX_COLOR_TARGETS: [ColorTargetState; 1] = [wgpu::ColorTargetState { const DEFAULT_FRAGMENT_COLOR_TARGETS: [ColorTargetState; 1] = [wgpu::ColorTargetState {
format: COLOR_TEXTURE_FORMAT, format: COLOR_TEXTURE_FORMAT,
blend: None, blend: None,
write_mask: wgpu::ColorWrites::ALL, write_mask: wgpu::ColorWrites::ALL,
}]; }];
const MASK_MAP_VERTEX_COLOR_TARGETS: [ColorTargetState; 1] = [wgpu::ColorTargetState { const NO_COLOR_FRAGMENT_COLOR_TARGETS: [ColorTargetState; 1] = [wgpu::ColorTargetState {
format: COLOR_TEXTURE_FORMAT, format: COLOR_TEXTURE_FORMAT,
blend: None, blend: None,
write_mask: wgpu::ColorWrites::empty(), write_mask: wgpu::ColorWrites::empty(),
@ -56,25 +56,25 @@ pub fn create_fragment_module_descriptor<'a>() -> ShaderModuleDescriptor<'a> {
} }
} }
pub fn create_map_vertex_state(vertex_shader_module: &ShaderModule) -> VertexState { pub fn create_vertex_state(vertex_shader_module: &ShaderModule) -> VertexState {
wgpu::VertexState { wgpu::VertexState {
module: vertex_shader_module, module: vertex_shader_module,
entry_point: "main", entry_point: "main",
buffers: &MAP_VERTEX_SHADER_BUFFERS, buffers: &VERTEX_SHADER_BUFFERS,
} }
} }
pub fn create_map_fragment_state( pub fn create_fragment_state(
fragment_shader_module: &ShaderModule, fragment_shader_module: &ShaderModule,
mask: bool, disable_color: bool,
) -> FragmentState { ) -> FragmentState {
wgpu::FragmentState { wgpu::FragmentState {
module: fragment_shader_module, module: fragment_shader_module,
entry_point: "main", entry_point: "main",
targets: if mask { targets: if disable_color {
&MASK_MAP_VERTEX_COLOR_TARGETS &NO_COLOR_FRAGMENT_COLOR_TARGETS
} else { } else {
&MAP_VERTEX_COLOR_TARGETS &DEFAULT_FRAGMENT_COLOR_TARGETS
}, },
} }
} }

View File

@ -1,24 +1,22 @@
use std::cmp; use std::cmp;
use std::io::Cursor; use std::io::Cursor;
use std::num::NonZeroU32;
use std::ops::Range; use std::ops::Range;
use lyon::math::Vector; use lyon::math::Vector;
use lyon::tessellation::VertexBuffers; use lyon::tessellation::VertexBuffers;
use vector_tile::parse_tile_reader; use vector_tile::parse_tile_reader;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use wgpu::Extent3d;
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
use winit::window::Window; use winit::window::Window;
use crate::fps_meter::FPSMeter; use crate::fps_meter::FPSMeter;
use crate::render::tesselation::TileMask;
use super::multisampling::create_multisampled_framebuffer;
use super::piplines::*; use super::piplines::*;
use super::platform_constants::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE}; use super::platform_constants::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
use super::shader::*; use super::shader::*;
use super::shader_ffi::*; use super::shader_ffi::*;
use super::tesselation::{RustLogo, Tesselated}; use super::tesselation::Tesselated;
use super::texture::Texture; use super::texture::Texture;
pub struct SceneParams { pub struct SceneParams {
@ -26,22 +24,28 @@ pub struct SceneParams {
pub zoom: f32, pub zoom: f32,
pub target_scroll: Vector, pub target_scroll: Vector,
pub scroll: Vector, pub scroll: Vector,
pub show_points: bool,
pub stroke_width: f32, pub stroke_width: f32,
pub target_stroke_width: f32, pub target_stroke_width: f32,
cpu_primitives: Vec<Primitive>,
} }
const PRIM_BUFFER_LEN: usize = 256; impl Default for SceneParams {
fn default() -> Self {
pub const DEFAULT_SCENE: SceneParams = SceneParams { SceneParams {
target_zoom: 5.0, target_zoom: 5.0,
zoom: 5.0, zoom: 5.0,
target_scroll: Vector::new(70.0, 70.0), target_scroll: Vector::new(70.0, 70.0),
scroll: Vector::new(70.0, 70.0), scroll: Vector::new(70.0, 70.0),
show_points: false,
stroke_width: 1.0, stroke_width: 1.0,
target_stroke_width: 1.0, target_stroke_width: 1.0,
}; cpu_primitives: vec![],
}
}
}
const PRIM_BUFFER_LEN: usize = 256;
const STROKE_PRIM_ID: u32 = 0;
const FILL_PRIM_ID: u32 = 1;
pub struct State { pub struct State {
device: wgpu::Device, device: wgpu::Device,
@ -59,53 +63,28 @@ pub struct State {
bind_group: wgpu::BindGroup, bind_group: wgpu::BindGroup,
sample_count: u32, sample_count: u32,
multisampled_render_target: Option<wgpu::TextureView>, multisampling_texture: Option<Texture>,
depth_texture: Texture, depth_texture: Texture,
prims_uniform_buffer: wgpu::Buffer, prims_uniform_buffer: wgpu::Buffer,
globals_uniform_buffer: wgpu::Buffer, globals_uniform_buffer: wgpu::Buffer,
vertex_uniform_buffer: wgpu::Buffer, vertex_uniform_buffer: wgpu::Buffer,
indices_uniform_buffer: wgpu::Buffer, indices_uniform_buffer: wgpu::Buffer,
tile_fill_range: Range<u32>,
tile_stroke_range: Range<u32>,
mask_vertex_uniform_buffer: wgpu::Buffer, tile_mask_vertex_uniform_buffer: wgpu::Buffer,
mask_indices_uniform_buffer: wgpu::Buffer, tile_mask_indices_uniform_buffer: wgpu::Buffer,
tile_mask_range: Range<u32>,
num_instances: u32,
stroke_prim_id: u32,
fill_prim_id: u32,
cpu_primitives: Vec<Primitive>,
fill_range: Range<u32>,
stroke_range: Range<u32>,
scene: SceneParams, scene: SceneParams,
} }
const TEST_TILES: &[u8] = include_bytes!("../../test-data/12-2176-1425.pbf"); const TEST_TILES: &[u8] = include_bytes!("../../test-data/12-2176-1425.pbf");
impl SceneParams {
impl State { pub fn new() -> Self {
pub async fn new(window: &Window) -> Self {
let sample_count = 4;
let stroke_prim_id = 0;
let fill_prim_id = 1;
let size = window.inner_size();
let mut geometry: VertexBuffers<GpuVertex, u16> = VertexBuffers::new();
let (stroke_range, fill_range) = {
//let tile = parse_tile("test-data/12-2176-1425.pbf").expect("failed loading tile");
let tile = parse_tile_reader(&mut Cursor::new(TEST_TILES));
let count_stroke = tile.tesselate_stroke(&mut geometry, stroke_prim_id);
let count_fill = 0;
let start_stroke = tile.tesselate_fill(&mut geometry, fill_prim_id);
let start_fill = start_stroke + count_stroke;
(
start_stroke..start_fill,
start_fill..start_fill + count_fill,
)
};
let mut cpu_primitives = Vec::with_capacity(PRIM_BUFFER_LEN); let mut cpu_primitives = Vec::with_capacity(PRIM_BUFFER_LEN);
for _ in 0..PRIM_BUFFER_LEN { for _ in 0..PRIM_BUFFER_LEN {
cpu_primitives.push(Primitive::new( cpu_primitives.push(Primitive::new(
@ -119,12 +98,34 @@ impl State {
} }
// Stroke primitive // Stroke primitive
cpu_primitives[stroke_prim_id as usize] = cpu_primitives[STROKE_PRIM_ID as usize] =
Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 3, 1.0, 0.0, 1.0); Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 3, 1.0, 0.0, 1.0);
// Main fill primitive // Main fill primitive
cpu_primitives[fill_prim_id as usize] = cpu_primitives[FILL_PRIM_ID as usize] =
Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 1, 0.0, 0.0, 1.0); Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 1, 0.0, 0.0, 1.0);
Self {
cpu_primitives,
..SceneParams::default()
}
}
}
impl State {
pub async fn new(window: &Window) -> Self {
let sample_count = 4;
let size = window.inner_size();
let mut geometry: VertexBuffers<GpuVertex, u16> = VertexBuffers::new();
//let tile = parse_tile("test-data/12-2176-1425.pbf").expect("failed loading tile");
let tile = parse_tile_reader(&mut Cursor::new(TEST_TILES));
let (tile_stroke_range, tile_fill_range) = (
tile.tesselate_stroke(&mut geometry, STROKE_PRIM_ID),
tile.tesselate_fill(&mut geometry, FILL_PRIM_ID),
);
// create an instance // create an instance
let instance = wgpu::Instance::new(wgpu::Backends::all()); let instance = wgpu::Instance::new(wgpu::Backends::all());
@ -172,26 +173,20 @@ impl State {
usage: wgpu::BufferUsages::INDEX, usage: wgpu::BufferUsages::INDEX,
}); });
const EXTENT: f32 = 4096.0; let mut tile_mask_geometry: VertexBuffers<GpuVertex, u16> = VertexBuffers::new();
let mask_vertex_data = [ let tile_mask = TileMask();
GpuVertex::new([0.0, 0.0], [0.0, 0.0], stroke_prim_id), let tile_mask_range = tile_mask.tesselate_fill(&mut tile_mask_geometry, FILL_PRIM_ID);
GpuVertex::new([EXTENT, 0.0], [0.0, 0.0], stroke_prim_id), let tile_mask_vertex_uniform_buffer =
GpuVertex::new([0.0, EXTENT], [0.0, 0.0], stroke_prim_id),
GpuVertex::new([EXTENT, EXTENT], [0.0, 0.0], stroke_prim_id),
];
let mask_index_data: &[u16] = &[0, 2, 1, 1, 2, 3];
let mask_vertex_uniform_buffer =
device.create_buffer_init(&wgpu::util::BufferInitDescriptor { device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: None, label: None,
contents: bytemuck::cast_slice(&mask_vertex_data), contents: bytemuck::cast_slice(&tile_mask_geometry.vertices),
usage: wgpu::BufferUsages::VERTEX, usage: wgpu::BufferUsages::VERTEX,
}); });
let mask_indices_uniform_buffer = let tile_mask_indices_uniform_buffer =
device.create_buffer_init(&wgpu::util::BufferInitDescriptor { device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: None, label: None,
contents: bytemuck::cast_slice(&mask_index_data), contents: bytemuck::cast_slice(&tile_mask_geometry.indices),
usage: wgpu::BufferUsages::INDEX, usage: wgpu::BufferUsages::INDEX,
}); });
@ -241,6 +236,7 @@ impl State {
}, },
], ],
}); });
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Bind group"), label: Some("Bind group"),
layout: &bind_group_layout, layout: &bind_group_layout,
@ -270,21 +266,20 @@ impl State {
let fragment_module = device.create_shader_module(&create_fragment_module_descriptor()); let fragment_module = device.create_shader_module(&create_fragment_module_descriptor());
let render_pipeline_descriptor = create_map_render_pipeline_description( let render_pipeline_descriptor = create_map_render_pipeline_description(
&pipeline_layout, &pipeline_layout,
create_map_vertex_state(&vertex_module), create_vertex_state(&vertex_module),
create_map_fragment_state(&fragment_module, false), create_fragment_state(&fragment_module, false),
sample_count, sample_count,
false, false,
); );
let mask_pipeline_descriptor = create_map_render_pipeline_description( let mask_pipeline_descriptor = create_map_render_pipeline_description(
&pipeline_layout, &pipeline_layout,
create_map_vertex_state(&vertex_module), create_vertex_state(&vertex_module),
create_map_fragment_state(&fragment_module, true), create_fragment_state(&fragment_module, true),
sample_count, sample_count,
true, true,
); );
let render_pipeline = device.create_render_pipeline(&render_pipeline_descriptor); let render_pipeline = device.create_render_pipeline(&render_pipeline_descriptor);
let mask_pipeline = device.create_render_pipeline(&mask_pipeline_descriptor); let mask_pipeline = device.create_render_pipeline(&mask_pipeline_descriptor);
@ -328,8 +323,8 @@ impl State {
} }
);*/ );*/
let multisampled_render_target = if sample_count > 1 { let multisampling_texture = if sample_count > 1 {
Some(create_multisampled_framebuffer( Some(Texture::create_multisampling_texture(
&device, &device,
&surface_config, &surface_config,
sample_count, sample_count,
@ -347,23 +342,20 @@ impl State {
render_pipeline, render_pipeline,
mask_pipeline, mask_pipeline,
bind_group, bind_group,
multisampled_render_target, multisampling_texture,
depth_texture, depth_texture,
sample_count, sample_count,
fill_range, tile_fill_range,
num_instances: 1, scene: SceneParams::new(),
stroke_prim_id: 0,
fill_prim_id: 1,
scene: DEFAULT_SCENE,
vertex_uniform_buffer, vertex_uniform_buffer,
globals_uniform_buffer, globals_uniform_buffer,
prims_uniform_buffer, prims_uniform_buffer,
indices_uniform_buffer, indices_uniform_buffer,
mask_vertex_uniform_buffer, tile_mask_vertex_uniform_buffer,
fps_meter: FPSMeter::new(), fps_meter: FPSMeter::new(),
stroke_range, tile_stroke_range,
cpu_primitives, tile_mask_indices_uniform_buffer,
mask_indices_uniform_buffer, tile_mask_range,
} }
} }
@ -383,8 +375,8 @@ impl State {
); );
// Re-configure multi-sampling buffer // Re-configure multi-sampling buffer
self.multisampled_render_target = if self.sample_count > 1 { self.multisampling_texture = if self.sample_count > 1 {
Some(create_multisampled_framebuffer( Some(Texture::create_multisampling_texture(
&self.device, &self.device,
&self.surface_config, &self.surface_config,
self.sample_count, self.sample_count,
@ -431,10 +423,6 @@ impl State {
scene.target_scroll.y += 50.0 / scene.target_zoom; scene.target_scroll.y += 50.0 / scene.target_zoom;
true true
} }
VirtualKeyCode::P => {
scene.show_points = !scene.show_points;
true
}
VirtualKeyCode::A => { VirtualKeyCode::A => {
scene.target_stroke_width /= 0.8; scene.target_stroke_width /= 0.8;
true true
@ -454,17 +442,11 @@ impl State {
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> { pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
let frame = self.surface.get_current_texture()?; let frame = self.surface.get_current_texture()?;
let scene = &mut self.scene; let scene = &mut self.scene;
let frame_view = frame let frame_view = frame
.texture .texture
.create_view(&wgpu::TextureViewDescriptor::default()); .create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder = self {
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Encoder"),
});
self.queue.write_buffer( self.queue.write_buffer(
&self.globals_uniform_buffer, &self.globals_uniform_buffer,
0, 0,
@ -478,15 +460,20 @@ impl State {
self.queue.write_buffer( self.queue.write_buffer(
&self.prims_uniform_buffer, &self.prims_uniform_buffer,
0, 0,
bytemuck::cast_slice(&self.cpu_primitives), bytemuck::cast_slice(&scene.cpu_primitives),
); );
}
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Encoder"),
});
{ {
// A resolve target is only supported if the attachment actually uses anti-aliasing let color_attachment = if let Some(multisampling_target) = &self.multisampling_texture {
// So if sample_count == 1 then we must render directly to the surface's buffer
let color_attachment = if let Some(msaa_target) = &self.multisampled_render_target {
wgpu::RenderPassColorAttachment { wgpu::RenderPassColorAttachment {
view: msaa_target, view: &multisampling_target.view,
ops: wgpu::Operations { ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::WHITE), load: wgpu::LoadOp::Clear(wgpu::Color::WHITE),
store: true, store: true,
@ -527,11 +514,11 @@ impl State {
pass.set_pipeline(&self.mask_pipeline); pass.set_pipeline(&self.mask_pipeline);
//pass.set_stencil_reference(0); //pass.set_stencil_reference(0);
pass.set_index_buffer( pass.set_index_buffer(
self.mask_indices_uniform_buffer.slice(..), self.tile_mask_indices_uniform_buffer.slice(..),
wgpu::IndexFormat::Uint16, wgpu::IndexFormat::Uint16,
); );
pass.set_vertex_buffer(0, self.mask_vertex_uniform_buffer.slice(..)); pass.set_vertex_buffer(0, self.tile_mask_vertex_uniform_buffer.slice(..));
pass.draw_indexed(0..6, 0, 0..1); pass.draw_indexed(self.tile_mask_range.clone(), 0, 0..1);
} }
{ {
pass.set_pipeline(&self.render_pipeline); pass.set_pipeline(&self.render_pipeline);
@ -542,7 +529,7 @@ impl State {
); );
pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..)); pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..));
//pass.draw_indexed(self.fill_range.clone(), 0, 0..(self.num_instances as u32)); //pass.draw_indexed(self.fill_range.clone(), 0, 0..(self.num_instances as u32));
pass.draw_indexed(self.stroke_range.clone(), 0, 0..1); pass.draw_indexed(self.tile_stroke_range.clone(), 0, 0..1);
} }
} }
@ -563,8 +550,8 @@ impl State {
scene.stroke_width + (scene.target_stroke_width - scene.stroke_width) / 5.0; scene.stroke_width + (scene.target_stroke_width - scene.stroke_width) / 5.0;
// Animate the strokes of primitive // Animate the strokes of primitive
self.cpu_primitives[self.stroke_prim_id as usize].width = scene.stroke_width; scene.cpu_primitives[STROKE_PRIM_ID as usize].width = scene.stroke_width;
self.cpu_primitives[self.stroke_prim_id as usize].color = [ scene.cpu_primitives[STROKE_PRIM_ID as usize].color = [
(time_secs * 0.8 - 1.6).sin() * 0.1 + 0.1, (time_secs * 0.8 - 1.6).sin() * 0.1 + 0.1,
(time_secs * 0.5 - 1.6).sin() * 0.1 + 0.1, (time_secs * 0.5 - 1.6).sin() * 0.1 + 0.1,
(time_secs - 1.6).sin() * 0.1 + 0.1, (time_secs - 1.6).sin() * 0.1 + 0.1,

View File

@ -1,3 +1,5 @@
use std::ops::Range;
use lyon::extra::rust_logo::build_logo_path; use lyon::extra::rust_logo::build_logo_path;
use lyon::lyon_tessellation::{FillTessellator, StrokeTessellator}; use lyon::lyon_tessellation::{FillTessellator, StrokeTessellator};
use lyon::tessellation; use lyon::tessellation;
@ -15,8 +17,8 @@ use super::shader_ffi::GpuVertex;
const DEFAULT_TOLERANCE: f32 = 0.02; const DEFAULT_TOLERANCE: f32 = 0.02;
pub trait Tesselated { pub trait Tesselated {
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32; fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> Range<u32>;
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32; fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> Range<u32>;
} }
/// This vertex constructor forwards the positions and normals provided by the /// This vertex constructor forwards the positions and normals provided by the
@ -40,7 +42,11 @@ impl StrokeVertexConstructor<GpuVertex> for WithId {
} }
impl Tesselated for Tile { impl Tesselated for Tile {
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 { fn tesselate_stroke(
&self,
buffer: &mut VertexBuffers<GpuVertex, u16>,
prim_id: u32,
) -> Range<u32> {
let mut stroke_tess = StrokeTessellator::new(); let mut stroke_tess = StrokeTessellator::new();
let mut tile_builder = Path::builder().with_svg(); let mut tile_builder = Path::builder().with_svg();
@ -92,14 +98,13 @@ impl Tesselated for Tile {
)); ));
} }
Command::Close => { Command::Close => {
tile_builder.close(); panic!("error")
} }
}; };
} }
} }
_ => {} _ => {}
}; };
//tile_builder.close();
tile_builder.move_to(lyon_path::math::point(0.0, 0.0)); tile_builder.move_to(lyon_path::math::point(0.0, 0.0));
} }
} }
@ -114,18 +119,18 @@ impl Tesselated for Tile {
) )
.unwrap(); .unwrap();
(buffer.indices.len() - initial_indices_count) as u32 initial_indices_count as u32..buffer.indices.len() as u32
} }
fn tesselate_fill(&self, _buffer: &mut VertexBuffers<GpuVertex, u16>, _prim_id: u32) -> u32 { fn tesselate_fill(&self, _buffer: &mut VertexBuffers<GpuVertex, u16>, _prim_id: u32) -> Range<u32> {
return 0; return 0..0;
} }
} }
pub struct RustLogo(); pub struct RustLogo();
impl Tesselated for RustLogo { impl Tesselated for RustLogo {
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 { fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> Range<u32> {
let mut stroke_tess = StrokeTessellator::new(); let mut stroke_tess = StrokeTessellator::new();
let initial_indices_count = buffer.indices.len(); let initial_indices_count = buffer.indices.len();
@ -143,10 +148,10 @@ impl Tesselated for RustLogo {
) )
.unwrap(); .unwrap();
(buffer.indices.len() - initial_indices_count) as u32 initial_indices_count as u32..buffer.indices.len() as u32
} }
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 { fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> Range<u32> {
let mut fill_tess = FillTessellator::new(); let mut fill_tess = FillTessellator::new();
let initial_indices_count = buffer.indices.len(); let initial_indices_count = buffer.indices.len();
@ -165,6 +170,32 @@ impl Tesselated for RustLogo {
) )
.unwrap(); .unwrap();
(buffer.indices.len() - initial_indices_count) as u32 initial_indices_count as u32..buffer.indices.len() as u32
}
}
const EXTENT: f32 = 4096.0;
pub struct TileMask();
impl Tesselated for TileMask {
fn tesselate_stroke(&self, _buffer: &mut VertexBuffers<GpuVertex, u16>, _prim_id: u32) -> Range<u32> {
0..0
}
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> Range<u32> {
let initial_indices_count = buffer.indices.len();
buffer.vertices = vec![
GpuVertex::new([0.0, 0.0], [0.0, 0.0], prim_id),
GpuVertex::new([EXTENT, 0.0], [0.0, 0.0], prim_id),
GpuVertex::new([0.0, EXTENT], [0.0, 0.0], prim_id),
GpuVertex::new([EXTENT, EXTENT], [0.0, 0.0], prim_id),
];
buffer.indices = vec![0, 2, 1, 1, 2, 3];
initial_indices_count as u32.. buffer.indices.len() as u32
} }
} }

View File

@ -6,14 +6,12 @@ pub struct Texture {
pub const DEPTH_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24PlusStencil8; pub const DEPTH_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24PlusStencil8;
impl Texture { impl Texture {
pub fn create_depth_texture( pub fn create_depth_texture(
device: &wgpu::Device, device: &wgpu::Device,
config: &wgpu::SurfaceConfiguration, config: &wgpu::SurfaceConfiguration,
_label: &str, _label: &str,
sample_count: u32, sample_count: u32,
) -> Self { ) -> Self {
let depth_texture = device.create_texture(&wgpu::TextureDescriptor { let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Depth texture"), label: Some("Depth texture"),
size: wgpu::Extent3d { size: wgpu::Extent3d {
@ -34,4 +32,29 @@ impl Texture {
view, view,
} }
} }
/// Creates a texture that uses MSAA and fits a given swap chain
pub fn create_multisampling_texture(
device: &wgpu::Device,
desc: &wgpu::SurfaceConfiguration,
sample_count: u32,
) -> Texture {
let multisampling_texture = &wgpu::TextureDescriptor {
label: Some("Multisampled frame descriptor"),
size: wgpu::Extent3d {
width: desc.width,
height: desc.height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count,
dimension: wgpu::TextureDimension::D2,
format: desc.format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
};
let texture = device.create_texture(multisampling_texture);
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
Self { texture, view }
}
} }