Skip to content

Commit

Permalink
Add basic support for transform matrices
Browse files Browse the repository at this point in the history
This is implemented in a way that's probably a little inefficient, but it's good enough for now.
  • Loading branch information
17cupsofcoffee committed Jan 8, 2024
1 parent db126f1 commit 0ab3f22
Showing 1 changed file with 28 additions and 8 deletions.
36 changes: 28 additions & 8 deletions src/graphics/batch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bytemuck::{Pod, Zeroable};
use glam::{BVec2, Vec2};
use glam::{BVec2, Mat3, Vec2};

use crate::graphics::{
Color, Graphics, Mesh, Rectangle, RenderPass, Shader, SpriteFont, Target, TextSegment, Texture,
Expand Down Expand Up @@ -120,6 +120,7 @@ pub struct Batcher {

sprites: Vec<Sprite>,
batches: Vec<Batch>,
matrices: Vec<Mat3>,
}

impl Batcher {
Expand All @@ -141,12 +142,12 @@ impl Batcher {

Batcher {
mesh,
default_texture,
default_shader,

sprites: Vec::new(),
batches: vec![Batch::default()],

default_texture,
default_shader,
matrices: Vec::new(),
}
}

Expand Down Expand Up @@ -184,6 +185,7 @@ impl Batcher {

self.sprites.clear();
self.batches.push(Batch::default());
self.matrices.clear();
}

pub fn clear_and_draw(&mut self, clear_color: Color, target: &impl Target) {
Expand All @@ -194,6 +196,15 @@ impl Batcher {
self.draw_internal(None, target)
}

pub fn push_matrix(&mut self, matrix: Mat3) {
// TODO: Support relative transforms
self.matrices.push(matrix);
}

pub fn pop_matrix(&mut self) {
self.matrices.pop();
}

pub fn rect(&mut self, rect: Rectangle, params: DrawParams) {
self.push_sprite(None, Rectangle::ZERO, rect, params);
}
Expand Down Expand Up @@ -327,26 +338,35 @@ impl Batcher {
let sin = params.rotation.sin();
let cos = params.rotation.cos();

let tl = Vec2::new(
let mut tl = Vec2::new(
dest.x + (cos * fx) - (sin * fy),
dest.y + (sin * fx) + (cos * fy),
);

let bl = Vec2::new(
let mut bl = Vec2::new(
dest.x + (cos * fx) - (sin * fy2),
dest.y + (sin * fx) + (cos * fy2),
);

let br = Vec2::new(
let mut br = Vec2::new(
dest.x + (cos * fx2) - (sin * fy2),
dest.y + (sin * fx2) + (cos * fy2),
);

let tr = Vec2::new(
let mut tr = Vec2::new(
dest.x + (cos * fx2) - (sin * fy),
dest.y + (sin * fx2) + (cos * fy),
);

// TODO: It may be faster to do this on the GPU, but that would cause a new batch every
// time that a new matrix is pushed. Would need to benchmark.
if let Some(m) = self.matrices.last() {
tl = m.transform_point2(tl);
bl = m.transform_point2(bl);
br = m.transform_point2(br);
tr = m.transform_point2(tr);
}

let (l_offset, r_offset) = if params.flip.x {
(source.width, 0.0)
} else {
Expand Down

0 comments on commit 0ab3f22

Please sign in to comment.