[oden] lol sprite API
This commit is contained in:
parent
c7903382a0
commit
aa90cea4a3
3 changed files with 168 additions and 75 deletions
144
src/lib.rs
144
src/lib.rs
|
|
@ -1,5 +1,4 @@
|
|||
use bytemuck;
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::{
|
||||
event::*,
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
|
|
@ -8,13 +7,13 @@ use winit::{
|
|||
};
|
||||
|
||||
mod script;
|
||||
use script::graphics::{ClearCommand, GraphicsCommand, PrintCommand};
|
||||
use script::graphics::GraphicsCommand;
|
||||
mod texture;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct Vertex {
|
||||
position: [f32; 3],
|
||||
position: [f32; 3], // TODO: Why do I pass in a Z here?
|
||||
tex_coords: [f32; 2],
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +73,7 @@ struct State {
|
|||
render_pipeline: wgpu::RenderPipeline,
|
||||
|
||||
vertex_buffer: wgpu::Buffer,
|
||||
index_buffer: wgpu::Buffer,
|
||||
num_indices: u32, // Indices in index_buffer
|
||||
max_vertices: usize,
|
||||
|
||||
diffuse_bind_group: wgpu::BindGroup,
|
||||
|
||||
|
|
@ -248,17 +246,15 @@ impl State {
|
|||
multiview: None,
|
||||
});
|
||||
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
let max_vertices: usize = 4096;
|
||||
let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("Vertex Buffer"),
|
||||
contents: bytemuck::cast_slice(VERTICES),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
size: (max_vertices * std::mem::size_of::<Vertex>())
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
mapped_at_creation: false,
|
||||
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Index Buffer"),
|
||||
contents: bytemuck::cast_slice(INDICES),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
let num_indices = INDICES.len() as u32;
|
||||
|
||||
Self {
|
||||
window,
|
||||
|
|
@ -269,8 +265,7 @@ impl State {
|
|||
size,
|
||||
render_pipeline,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
num_indices,
|
||||
max_vertices,
|
||||
diffuse_bind_group,
|
||||
|
||||
mouse_x: 0.0,
|
||||
|
|
@ -302,11 +297,6 @@ impl State {
|
|||
let view = output
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder = self
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("Render Encoder"),
|
||||
});
|
||||
|
||||
// Group the commands into passes.
|
||||
struct Pass {
|
||||
|
|
@ -316,8 +306,8 @@ impl State {
|
|||
let mut passes = Vec::new();
|
||||
for command in commands {
|
||||
match command {
|
||||
GraphicsCommand::Clear(ClearCommand { color }) => passes.push(Pass {
|
||||
color: Some(color),
|
||||
GraphicsCommand::Clear(cc) => passes.push(Pass {
|
||||
color: Some(cc.color),
|
||||
commands: Vec::new(),
|
||||
}),
|
||||
GraphicsCommand::EndFrame => (),
|
||||
|
|
@ -331,39 +321,91 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
let mut vertices = Vec::new();
|
||||
for pass in passes {
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Render Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: if let Some([r, g, b, a]) = pass.color {
|
||||
wgpu::LoadOp::Clear(wgpu::Color {
|
||||
r, //0.1,
|
||||
g, //0.2,
|
||||
b,
|
||||
a,
|
||||
})
|
||||
} else {
|
||||
wgpu::LoadOp::Load
|
||||
// TODO: It would be great if we could use multiple passes in a
|
||||
// single encoder but right now because of the dyanmic
|
||||
// nature of vertices we can't, I think? Because
|
||||
// queue.write_buffer doesn't actually happen until we call
|
||||
// submit...
|
||||
let mut encoder = self
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("Render Encoder"),
|
||||
});
|
||||
|
||||
{
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Render Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: if let Some([r, g, b, a]) = pass.color {
|
||||
wgpu::LoadOp::Clear(wgpu::Color {
|
||||
r, //0.1,
|
||||
g, //0.2,
|
||||
b,
|
||||
a,
|
||||
})
|
||||
} else {
|
||||
wgpu::LoadOp::Load
|
||||
},
|
||||
store: true,
|
||||
},
|
||||
store: true,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
|
||||
for command in pass.commands {
|
||||
match command {
|
||||
GraphicsCommand::Print(PrintCommand { text }) => {
|
||||
println!("{}", text);
|
||||
vertices.clear();
|
||||
for command in pass.commands {
|
||||
match command {
|
||||
GraphicsCommand::Print(pc) => {
|
||||
println!("{}", pc.text);
|
||||
}
|
||||
GraphicsCommand::Sprite(sc) => {
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x, sc.y, 0.0],
|
||||
tex_coords: [sc.u, sc.v],
|
||||
});
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x + sc.w, sc.y, 0.0],
|
||||
tex_coords: [sc.u + sc.sw, sc.v],
|
||||
});
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x, sc.y + sc.h, 0.0],
|
||||
tex_coords: [sc.u, sc.v],
|
||||
});
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x, sc.y + sc.h, 0.0],
|
||||
tex_coords: [sc.u, sc.v],
|
||||
});
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x + sc.w, sc.y, 0.0],
|
||||
tex_coords: [sc.u, sc.v],
|
||||
});
|
||||
vertices.push(Vertex {
|
||||
position: [sc.x + sc.w, sc.y + sc.h, 0.0],
|
||||
tex_coords: [sc.u, sc.v],
|
||||
});
|
||||
}
|
||||
|
||||
GraphicsCommand::Clear(_) => (), // Already handled
|
||||
GraphicsCommand::EndFrame => (), // Should never appear
|
||||
}
|
||||
|
||||
GraphicsCommand::Clear(_) => (), // Already handled
|
||||
GraphicsCommand::EndFrame => (), // Should never appear
|
||||
}
|
||||
|
||||
assert!(vertices.len() < self.max_vertices); // !
|
||||
self.queue
|
||||
.write_buffer(&self.vertex_buffer, 0, bytemuck::cast_slice(&vertices));
|
||||
render_pass.set_pipeline(&self.render_pipeline);
|
||||
render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||
render_pass.draw(0..(vertices.len() as u32), 0..1);
|
||||
}
|
||||
|
||||
// Submit will accept anything that implements IntoIter
|
||||
self.queue.submit(std::iter::once(encoder.finish()));
|
||||
}
|
||||
|
||||
// {
|
||||
|
|
@ -397,8 +439,6 @@ impl State {
|
|||
// render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
||||
// }
|
||||
|
||||
// Submit will accept anything that implements IntoIter
|
||||
self.queue.submit(std::iter::once(encoder.finish()));
|
||||
output.present();
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue