Skip to content

Commit ae3d5f4

Browse files
committed
render: Render Matrix3D tz element
In Transform.Matrix3D setter, the transformation matrix was crushed to 2D, ignoring 3D parameters. This commit picks up tz element (i.e. raw_data[14] element) into render.Transform and take it into account in wgpu rendering. The projection matrix for the default perspective projection (FOV: 55.0 deg, center: stage center) is introduced to rendering.
1 parent a4eecae commit ae3d5f4

File tree

9 files changed

+144
-15
lines changed

9 files changed

+144
-15
lines changed

core/src/avm1/globals/bitmap_data.rs

+1
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ fn draw<'gc>(
577577
Transform {
578578
matrix,
579579
color_transform,
580+
tz: 0.0,
580581
},
581582
smoothing,
582583
blend_mode,

core/src/avm2/globals/flash/geom/transform.rs

+2
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ pub fn set_matrix_3d<'gc>(
364364
Some(obj) => {
365365
let matrix3d = object_to_matrix3d(obj, activation)?;
366366
let matrix = Matrix::from(matrix3d);
367+
let tz = matrix3d.tz();
368+
display_object.base_mut(activation.gc()).set_tz(tz);
367369
(matrix, true)
368370
}
369371
None => (Matrix::IDENTITY, false),

core/src/display_object.rs

+7
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ impl<'gc> DisplayObjectBase<'gc> {
336336
&mut self.transform.matrix
337337
}
338338

339+
pub fn set_tz(&mut self, tz: f64) {
340+
self.transform.tz = tz;
341+
}
342+
339343
pub fn set_matrix(&mut self, matrix: Matrix) {
340344
self.transform.matrix = matrix;
341345
self.set_scale_rotation_cached(false);
@@ -941,6 +945,7 @@ pub fn render_base<'gc>(this: DisplayObject<'gc>, context: &mut RenderContext<'_
941945
ty: -offset_y,
942946
..cache_info.base_transform.matrix
943947
},
948+
tz: 0.0,
944949
});
945950
let mut offscreen_context = RenderContext {
946951
renderer: context.renderer,
@@ -973,6 +978,7 @@ pub fn render_base<'gc>(this: DisplayObject<'gc>, context: &mut RenderContext<'_
973978
..Default::default()
974979
},
975980
color_transform: cache_info.base_transform.color_transform,
981+
tz: context.transform_stack.transform().tz,
976982
},
977983
true,
978984
PixelSnapping::Always, // cacheAsBitmap forces pixel snapping
@@ -1045,6 +1051,7 @@ pub fn apply_standard_mask_and_scroll<'gc, F>(
10451051
context.transform_stack.push(&Transform {
10461052
matrix: Matrix::translate(-rect.x_min, -rect.y_min),
10471053
color_transform: Default::default(),
1054+
tz: 0.0,
10481055
});
10491056
}
10501057

core/src/display_object/edit_text.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,7 @@ impl<'gc> EditText<'gc> {
13031303
context.transform_stack.push(&Transform {
13041304
matrix: transform.matrix,
13051305
color_transform: ColorTransform::IDENTITY,
1306+
tz: 0.0,
13061307
});
13071308
} else {
13081309
context.transform_stack.push(transform);

core/src/display_object/stage.rs

+1
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,7 @@ impl<'gc> TDisplayObject<'gc> for Stage<'gc> {
834834
context.transform_stack.push(&Transform {
835835
matrix: self.0.read().viewport_matrix,
836836
color_transform: Default::default(),
837+
tz: 0.0,
837838
});
838839

839840
// All of our Stage3D instances get rendered *underneath* the main stage.

render/src/matrix3d.rs

+34
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,37 @@ impl From<Matrix3D> for Matrix {
4848
}
4949
}
5050
}
51+
52+
impl Matrix3D {
53+
pub const ZERO: Self = Self {
54+
raw_data: [0.0; 16],
55+
};
56+
pub const IDENTITY: Self = Self {
57+
raw_data: [
58+
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
59+
],
60+
};
61+
62+
pub fn tz(&self) -> f64 {
63+
self.raw_data[14]
64+
}
65+
pub fn set_tz(&mut self, tz: f64) {
66+
self.raw_data[14] = tz;
67+
}
68+
}
69+
70+
impl std::ops::Mul for Matrix3D {
71+
type Output = Self;
72+
73+
fn mul(self, rhs: Self) -> Self::Output {
74+
let mut res = Matrix3D::ZERO;
75+
for i in 0..4 {
76+
for j in 0..4 {
77+
for k in 0..4 {
78+
res.raw_data[i + 4 * j] += self.raw_data[i + 4 * k] * rhs.raw_data[k + 4 * j];
79+
}
80+
}
81+
}
82+
res
83+
}
84+
}

render/src/transform.rs

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use swf::ColorTransform;
66
#[derive(Clone, Debug, Default)]
77
pub struct Transform {
88
pub matrix: Matrix,
9+
pub tz: f64,
910
pub color_transform: ColorTransform,
1011
}
1112

@@ -20,9 +21,11 @@ impl TransformStack {
2021
let cur_transform = self.transform();
2122
let matrix = cur_transform.matrix * transform.matrix;
2223
let color_transform = cur_transform.color_transform * transform.color_transform;
24+
let tz = cur_transform.tz + transform.tz;
2325
self.0.push(Transform {
2426
matrix,
2527
color_transform,
28+
tz,
2629
});
2730
}
2831

render/wgpu/src/globals.rs

+73-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//use super::utils::create_debug_label;
22
use bytemuck::{Pod, Zeroable};
3+
use ruffle_render::matrix3d::Matrix3D;
34
use wgpu::util::DeviceExt;
45

56
#[derive(Debug)]
@@ -21,16 +22,82 @@ impl Globals {
2122
viewport_width: u32,
2223
viewport_height: u32,
2324
) -> Self {
25+
let view_matrix = Matrix3D {
26+
raw_data: [
27+
1.0 / (viewport_width as f64 / 2.0),
28+
0.0,
29+
0.0,
30+
0.0,
31+
0.0,
32+
-1.0 / (viewport_height as f64 / 2.0),
33+
0.0,
34+
0.0,
35+
0.0,
36+
0.0,
37+
1.0 / (viewport_width as f64 / 2.0),
38+
0.0,
39+
-1.0,
40+
1.0,
41+
0.0,
42+
1.0,
43+
],
44+
};
45+
46+
let projection_matrix = {
47+
// TODO: Here, just the fixed default value is used.
48+
// This should support variable values derived for each display object.
49+
let field_of_view = 55.0;
50+
51+
let focal_length = {
52+
let deg2rad = f64::acos(-1.0) / 180.0;
53+
let rad = field_of_view / 2.0 * deg2rad;
54+
f64::cos(rad) / f64::sin(rad)
55+
};
56+
57+
let perspective_projection = {
58+
let mut m = Matrix3D::IDENTITY;
59+
m.raw_data[0] = focal_length;
60+
m.raw_data[5] = focal_length;
61+
m.raw_data[10] = focal_length;
62+
m.raw_data[11] = 1.0;
63+
m.raw_data[14] = 0.0;
64+
m.raw_data[15] = 0.0;
65+
m
66+
};
67+
let move_coord = {
68+
// AS3 places Viewpoint at (0, 0, -focalLength).
69+
70+
let mut m = Matrix3D::IDENTITY;
71+
m.raw_data[14] = focal_length;
72+
// TODO: Consider PerspectiveProjection.projectionCenter.
73+
m
74+
};
75+
let move_coord_back = {
76+
let mut m = Matrix3D::IDENTITY;
77+
m.raw_data[10] = 0.0;
78+
// TODO: Consider PerspectiveProjection.projectionCenter.
79+
m
80+
};
81+
move_coord_back * perspective_projection * move_coord
82+
};
83+
84+
let matrix = projection_matrix * view_matrix;
85+
let matrix = {
86+
let mut m = [[0.0; 4]; 4];
87+
#[allow(clippy::needless_range_loop)]
88+
for i in 0..4 {
89+
for j in 0..4 {
90+
m[j][i] = matrix.raw_data[i + 4 * j] as f32;
91+
}
92+
}
93+
m
94+
};
95+
2496
let temp_label = create_debug_label!("Globals buffer");
2597
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
2698
label: temp_label.as_deref(),
2799
contents: bytemuck::cast_slice(&[GlobalsUniform {
28-
view_matrix: [
29-
[1.0 / (viewport_width as f32 / 2.0), 0.0, 0.0, 0.0],
30-
[0.0, -1.0 / (viewport_height as f32 / 2.0), 0.0, 0.0],
31-
[0.0, 0.0, 1.0, 0.0],
32-
[-1.0, 1.0, 0.0, 1.0],
33-
],
100+
view_matrix: matrix,
34101
}]),
35102
usage: wgpu::BufferUsages::UNIFORM,
36103
});

render/wgpu/src/surface/commands.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ impl<'a> WgpuCommandHandler<'a> {
564564
fn add_to_current(
565565
&mut self,
566566
matrix: Matrix,
567+
tz: f64,
567568
color_transform: ColorTransform,
568569
command_builder: impl FnOnce(wgpu::DynamicOffset) -> DrawCommand,
569570
) {
@@ -575,7 +576,7 @@ impl<'a> WgpuCommandHandler<'a> {
575576
[
576577
matrix.tx.to_pixels() as f32,
577578
matrix.ty.to_pixels() as f32,
578-
0.0,
579+
tz as f32,
579580
1.0,
580581
],
581582
],
@@ -642,6 +643,7 @@ impl CommandHandler for WgpuCommandHandler<'_> {
642643
let transform = Transform {
643644
matrix: Matrix::scale(target.width() as f32, target.height() as f32),
644645
color_transform: Default::default(),
646+
tz: 0.0,
645647
};
646648
let texture = target.take_color_texture();
647649
let bind_group =
@@ -673,6 +675,7 @@ impl CommandHandler for WgpuCommandHandler<'_> {
673675
});
674676
self.add_to_current(
675677
transform.matrix,
678+
transform.tz,
676679
transform.color_transform,
677680
|transform_buffer| DrawCommand::RenderTexture {
678681
_texture: texture,
@@ -726,15 +729,18 @@ impl CommandHandler for WgpuCommandHandler<'_> {
726729
texture.texture.height() as f32,
727730
);
728731
}
729-
self.add_to_current(matrix, transform.color_transform, |transform_buffer| {
730-
DrawCommand::RenderBitmap {
732+
self.add_to_current(
733+
matrix,
734+
transform.tz,
735+
transform.color_transform,
736+
|transform_buffer| DrawCommand::RenderBitmap {
731737
bitmap,
732738
transform_buffer,
733739
smoothing,
734740
blend_mode: TrivialBlend::Normal,
735741
render_stage3d: false,
736-
}
737-
});
742+
},
743+
);
738744
}
739745
fn render_stage3d(&mut self, bitmap: BitmapHandle, transform: Transform) {
740746
let mut matrix = transform.matrix;
@@ -745,20 +751,24 @@ impl CommandHandler for WgpuCommandHandler<'_> {
745751
texture.texture.height() as f32,
746752
);
747753
}
748-
self.add_to_current(matrix, transform.color_transform, |transform_buffer| {
749-
DrawCommand::RenderBitmap {
754+
self.add_to_current(
755+
matrix,
756+
transform.tz,
757+
transform.color_transform,
758+
|transform_buffer| DrawCommand::RenderBitmap {
750759
bitmap,
751760
transform_buffer,
752761
smoothing: false,
753762
blend_mode: TrivialBlend::Normal,
754763
render_stage3d: true,
755-
}
756-
});
764+
},
765+
);
757766
}
758767

759768
fn render_shape(&mut self, shape: ShapeHandle, transform: Transform) {
760769
self.add_to_current(
761770
transform.matrix,
771+
transform.tz,
762772
transform.color_transform,
763773
|transform_buffer| DrawCommand::RenderShape {
764774
shape,
@@ -770,6 +780,7 @@ impl CommandHandler for WgpuCommandHandler<'_> {
770780
fn draw_rect(&mut self, color: Color, matrix: Matrix) {
771781
self.add_to_current(
772782
matrix,
783+
0.0,
773784
ColorTransform::multiply_from(color),
774785
|transform_buffer| DrawCommand::DrawRect { transform_buffer },
775786
);
@@ -785,6 +796,7 @@ impl CommandHandler for WgpuCommandHandler<'_> {
785796
matrix.ty += Twips::HALF_PX;
786797
self.add_to_current(
787798
matrix,
799+
0.0,
788800
ColorTransform::multiply_from(color),
789801
|transform_buffer| DrawCommand::DrawLine { transform_buffer },
790802
);
@@ -801,6 +813,7 @@ impl CommandHandler for WgpuCommandHandler<'_> {
801813
matrix.ty += Twips::HALF_PX;
802814
self.add_to_current(
803815
matrix,
816+
0.0,
804817
ColorTransform::multiply_from(color),
805818
|transform_buffer| DrawCommand::DrawLineRect { transform_buffer },
806819
);

0 commit comments

Comments
 (0)