I am making a system for line drawing in wgpu with lyon. My problem is when I call draw_indexed()
with the VertexBuffers
from lyon nothing shows up.
Sorry about the huge amount of code, wgpu takes a lot to get running
impl LineDrawer {
fn build(self, device: &Device) -> Vec<Buffer> {
let mut buffers = Vec::new();
for i in self.lines {
let buffer = i.build();
let vertex = device.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: bytemuck::cast_slice(&buffer.vertices),
usage: wgpu::BufferUsages::VERTEX,
});
let index_len = buffer.indices.len();
let index = device.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: bytemuck::cast_slice(&buffer.indices),
usage: wgpu::BufferUsages::INDEX,
});
buffers.push(Buffer { index, vertex, index_len });
}
buffers
}
pub fn render(
self,
device: &Device,
encoder: &mut wgpu::CommandEncoder,
view: &wgpu::TextureView,
camera_bind_group: &wgpu::BindGroup,
) {
let shader = device.create_shader_module(wgpu::include_wgsl!("line_drawer.wgsl"));
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Line Drawer Pipeline Layout"),
bind_group_layouts: &[camera_bind_group_layout],
push_constant_ranges: &[],
});
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Line Drawer Pipeline"),
layout: Some(&render_pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
buffers: &[ColorVertex::desc()],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState {
format: config.format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
polygon_mode: wgpu::PolygonMode::Fill,
front_face: wgpu::FrontFace::Ccw,
strip_index_format: None,
cull_mode: Some(wgpu::Face::Back),
conservative: false,
unclipped_depth: false,
},
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
multiview: None,
});
let buffers = self.build(device);
{
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
},
})],
depth_stencil_attachment: None,
});
render_pass.set_pipeline(pipeline);
render_pass.set_bind_group(0, camera_bind_group, &[]);
for i in 0..buffers.len() {
render_pass.set_index_buffer(buffers[i].index.slice(..), wgpu::IndexFormat::Uint16);
render_pass.set_vertex_buffer(0, buffers[i].vertex.slice(..));
render_pass.draw_indexed(0..buffers[i].index_len as u32, 0, 0..1)
}
}
}
pub struct Line {
buffer: VertexBuffers<ColorVertex, u32>,
}
struct Buffer {
index: wgpu::Buffer,
vertex: wgpu::Buffer,
index_len: usize,
}
impl Line {
pub fn rectangle(mut self, bounds: Rect, color: Color) -> Self {
{
let buffers = &mut self.buffer;
let rect = lyon::math::Box2D::from_origin_and_size(
lyon::math::point(bounds.x, bounds.y),
lyon::math::size(bounds.width, bounds.height),
);
let vb = VertexBuilder {
color: LinearColor::from(color),
};
let builder = &mut lyon::tessellation::BuffersBuilder::new(buffers, vb);
let mut tessellator = lyon::tessellation::FillTessellator::new();
tessellator.tessellate_rectangle(
&rect,
&lyon::lyon_tessellation::FillOptions::default(),
builder
)
.expect("could not create rectangle");
}
self
}
pub fn build(self) -> VertexBuffers<ColorVertex, u32> {
dbg!(&self.buffer);
self.buffer
}
and here is the output
&self.buffer = VertexBuffers {
vertices: [
ColorVertex {
position: [
0.0,
0.0,
0.0,
],
color: [
1.0,
1.0,
1.0,
1.0,
],
},
ColorVertex {
position: [
0.0,
100.0,
0.0,
],
color: [
1.0,
1.0,
1.0,
1.0,
],
},
ColorVertex {
position: [
100.0,
100.0,
0.0,
],
color: [
1.0,
1.0,
1.0,
1.0,
],
},
ColorVertex {
position: [
100.0,
0.0,
0.0,
],
color: [
1.0,
1.0,
1.0,
1.0,
],
},
],
indices: [
0,
1,
2,
0,
2,
3,
],
}
The fix was that lyon uses u32s as indices so I changed the pipelines index format to wgpu::IndexFormat::Uint16 and also the cull mode to Some(wgpu::Face::Front)