Compare commits

...

2 commits

Author SHA1 Message Date
796c6cc2a4 [game] Debug lines and whatnot for actor collision
I'm just leaving it on for now, I need to get text rendering working
for reals.
2023-08-27 09:29:30 -07:00
df49143885 [oden] Some perhaps unadvised factoring
Traits for fun and profit. I was nervous about the amount of magic
"you have to get this right" coupling between runtime structures (the
draw mode) and types (the various instance types) and I didn't want to
get them wrong. So now some things are more generic than they were
before, and maybe that's good? Who can say in the end.
2023-08-27 09:28:14 -07:00
2 changed files with 52 additions and 37 deletions

View file

@ -1,7 +1,7 @@
import { load_texture } from "./assets";
import { btn, Button } from "./input";
import { Vec2, new_v2, vadd, vsub, vnorm, vmul } from "./vector";
import { spr, use_texture, Texture } from "./graphics";
import { color, stroke, circle, spr, use_texture, Texture } from "./graphics";
import { has_collision, Level } from "./level";
export interface ActorProps {
@ -192,9 +192,12 @@ export class Robo extends Actor {
const frame = (anim.start + ((clock / anim.speed) % anim.length)) >> 0;
spr(x, y, w, h, frame * w, 0, 32, 32);
// color(0, 0, 0, 0);
// stroke(0, 0, 0, 1);
// circle(this.props.position.x, this.props.position.y, 8, 1);
color(0, 0, 0, 0);
stroke(1, 0, 0, 1);
circle(this.props.position.x, this.props.position.y, 8, 1);
stroke(0, 1, 0, 1);
circle(this.props.position.x, this.props.position.y, 16, 1);
}
}
}

View file

@ -692,6 +692,34 @@ enum DrawMode {
Circles,
}
trait DrawModeInstance: Sized {
const MODE: DrawMode;
fn get_vertex_buffer<'a>(
state: &'a mut State,
vb: &VertexBufferHandle,
) -> &'a mut VertexBuffer<Self>;
}
impl DrawModeInstance for SpriteInstance {
const MODE: DrawMode = DrawMode::Sprites;
fn get_vertex_buffer<'a>(
state: &'a mut State,
vb: &VertexBufferHandle,
) -> &'a mut VertexBuffer<Self> {
state.sprite_instance_buffers.get_mut(&vb)
}
}
impl DrawModeInstance for CircleInstance {
const MODE: DrawMode = DrawMode::Circles;
fn get_vertex_buffer<'a>(
state: &'a mut State,
vb: &VertexBufferHandle,
) -> &'a mut VertexBuffer<Self> {
state.circle_instance_buffers.get_mut(&vb)
}
}
#[derive(Debug)]
struct DrawCall {
mode: DrawMode,
@ -891,7 +919,16 @@ impl<'a> FrameBuilder<'a> {
}
fn start_pass(&mut self, color: Option<[f64; 4]>, target: Rc<wgpu::TextureView>) {
// NOTE: We're not changing drawing modes here which means we can preserve the
// buffer tail if we want to.
let first_call = match self.draw_calls.last() {
Some(call) => call.new_at_buffer_tail(),
None => DrawCall::new(self.mode, self.new_instance_buffer(), 0),
};
self.flush();
self.draw_calls.push(first_call);
self.color = color;
self.target = target;
}
@ -935,19 +972,15 @@ impl<'a> FrameBuilder<'a> {
}
}
fn switch_mode(&mut self, mode: DrawMode) {
if self.mode != mode {
fn get_instance_buffer<T: DrawModeInstance>(&mut self) -> &mut VertexBuffer<T> {
if self.mode != T::MODE {
self.flush();
self.draw_calls.clear();
self.mode = mode;
self.mode = T::MODE;
}
}
fn get_sprite_instance_buffer(&mut self) -> &mut VertexBuffer<SpriteInstance> {
self.switch_mode(DrawMode::Sprites);
match self.draw_calls.last_mut() {
Some(call) => match call.allocate_capacity(1) {
Some(vb) => return self.state.sprite_instance_buffers.get_mut(&vb),
Some(vb) => return T::get_vertex_buffer(self.state, &vb),
None => {}
},
None => {}
@ -956,34 +989,19 @@ impl<'a> FrameBuilder<'a> {
let mut call = DrawCall::new(self.mode, self.new_instance_buffer(), 0);
let vb = call.allocate_capacity(1).unwrap();
self.draw_calls.push(call);
self.state.sprite_instance_buffers.get_mut(&vb)
T::get_vertex_buffer(self.state, &vb)
}
fn push_sprite(&mut self, si: SpriteInstance) {
let vertex_buffer = self.get_sprite_instance_buffer();
let vertex_buffer = self.get_instance_buffer();
vertex_buffer.vec.push(si);
}
fn get_circle_instance_buffer(&mut self) -> &mut VertexBuffer<CircleInstance> {
self.switch_mode(DrawMode::Circles);
match self.draw_calls.last_mut() {
Some(call) => match call.allocate_capacity(1) {
Some(vb) => return self.state.circle_instance_buffers.get_mut(&vb),
None => {}
},
None => {}
};
let mut call = DrawCall::new(self.mode, self.new_instance_buffer(), 0);
let vb = call.allocate_capacity(1).unwrap();
self.draw_calls.push(call);
self.state.circle_instance_buffers.get_mut(&vb)
}
fn push_circle(&mut self, cc: script::graphics::CircleCommand) {
let stroke_color = self.stroke_color.clone();
let fill_color = self.fill_color.clone();
let vertex_buffer = self.get_circle_instance_buffer();
let vertex_buffer = self.get_instance_buffer();
vertex_buffer.vec.push(CircleInstance {
center: cc.center,
radius: cc.radius,
@ -994,11 +1012,6 @@ impl<'a> FrameBuilder<'a> {
}
fn flush(&mut self) {
let first_call = match self.draw_calls.last() {
Some(call) => call.new_at_buffer_tail(),
None => DrawCall::new(self.mode, self.new_instance_buffer(), 0),
};
if self.draw_calls.len() > 0 {
let mut pass = self.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
@ -1034,7 +1047,6 @@ impl<'a> FrameBuilder<'a> {
self.color = None;
self.draw_calls.clear();
self.draw_calls.push(first_call);
}
}