render: Add Filter::DisplacementMapFilter
This commit is contained in:
parent
f9c7303f01
commit
dbe2efff00
|
@ -1,10 +1,12 @@
|
|||
use crate::avm2::error::type_error;
|
||||
use crate::avm2::{Activation, ArrayObject, Error, Object, TObject, Value};
|
||||
use ruffle_render::filters::{
|
||||
BevelFilter, BevelFilterType, BlurFilter, ColorMatrixFilter, ConvolutionFilter, Filter,
|
||||
BevelFilter, BevelFilterType, BlurFilter, ColorMatrixFilter, ConvolutionFilter,
|
||||
DisplacementMapFilter, DisplacementMapFilterMode, Filter,
|
||||
};
|
||||
use swf::Color;
|
||||
|
||||
use crate::avm2::error::{argument_error, type_error};
|
||||
use crate::avm2::{Activation, ArrayObject, Error, Object, TObject, Value};
|
||||
|
||||
pub trait FilterAvm2Ext {
|
||||
fn from_avm2_object<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
|
@ -42,6 +44,11 @@ impl FilterAvm2Ext for Filter {
|
|||
return ConvolutionFilter::from_avm2_object(activation, object);
|
||||
}
|
||||
|
||||
let displacement_map_filter = activation.avm2().classes().displacementmapfilter;
|
||||
if object.is_of_type(displacement_map_filter, activation) {
|
||||
return DisplacementMapFilter::from_avm2_object(activation, object);
|
||||
}
|
||||
|
||||
Err(Error::AvmError(type_error(
|
||||
activation,
|
||||
&format!(
|
||||
|
@ -60,6 +67,7 @@ impl FilterAvm2Ext for Filter {
|
|||
Filter::BlurFilter(filter) => filter.as_avm2_object(activation),
|
||||
Filter::ColorMatrixFilter(filter) => filter.as_avm2_object(activation),
|
||||
Filter::ConvolutionFilter(filter) => filter.as_avm2_object(activation),
|
||||
Filter::DisplacementMapFilter(filter) => filter.as_avm2_object(activation),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,3 +312,119 @@ impl FilterAvm2Ext for ConvolutionFilter {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterAvm2Ext for DisplacementMapFilter {
|
||||
fn from_avm2_object<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
object: Object<'gc>,
|
||||
) -> Result<Filter, Error<'gc>> {
|
||||
let alpha = object
|
||||
.get_public_property("alpha", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let color = object
|
||||
.get_public_property("color", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let component_x = object
|
||||
.get_public_property("componentX", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let component_y = object
|
||||
.get_public_property("componentY", activation)?
|
||||
.coerce_to_u32(activation)?;
|
||||
let map_point =
|
||||
if let Value::Object(point) = object.get_public_property("mapPoint", activation)? {
|
||||
(
|
||||
point
|
||||
.get_public_property("x", activation)?
|
||||
.coerce_to_u32(activation)?,
|
||||
point
|
||||
.get_public_property("y", activation)?
|
||||
.coerce_to_u32(activation)?,
|
||||
)
|
||||
} else {
|
||||
(0, 0)
|
||||
};
|
||||
let mode = if let Value::String(mode) = object.get_public_property("mode", activation)? {
|
||||
if &mode == b"clamp" {
|
||||
DisplacementMapFilterMode::Clamp
|
||||
} else if &mode == b"ignore" {
|
||||
DisplacementMapFilterMode::Ignore
|
||||
} else if &mode == b"color" {
|
||||
DisplacementMapFilterMode::Color
|
||||
} else if &mode == b"wrap" {
|
||||
DisplacementMapFilterMode::Wrap
|
||||
} else {
|
||||
return Err(Error::AvmError(argument_error(
|
||||
activation,
|
||||
"Parameter mode must be one of the accepted values.",
|
||||
2008,
|
||||
)?));
|
||||
}
|
||||
} else {
|
||||
DisplacementMapFilterMode::Wrap
|
||||
};
|
||||
let scale_x = object
|
||||
.get_public_property("scaleX", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let scale_y = object
|
||||
.get_public_property("scaleY", activation)?
|
||||
.coerce_to_number(activation)?;
|
||||
let map_bitmap = if let Value::Object(bitmap) =
|
||||
object.get_public_property("mapBitmap", activation)?
|
||||
{
|
||||
if let Some(bitmap) = bitmap.as_bitmap_data() {
|
||||
bitmap
|
||||
.write(activation.context.gc_context)
|
||||
.bitmap_handle(activation.context.renderer)
|
||||
} else {
|
||||
return Err(Error::AvmError(type_error(
|
||||
activation,
|
||||
&format!("Type Coercion failed: cannot convert {bitmap:?} to flash.display.BitmapData."),
|
||||
1034,
|
||||
)?));
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(Filter::DisplacementMapFilter(DisplacementMapFilter {
|
||||
color: Color::from_rgb(color, (alpha * 255.0) as u8),
|
||||
component_x: component_x as u8,
|
||||
component_y: component_y as u8,
|
||||
map_bitmap,
|
||||
map_point,
|
||||
mode,
|
||||
scale_x: scale_x as f32,
|
||||
scale_y: scale_y as f32,
|
||||
}))
|
||||
}
|
||||
|
||||
fn as_avm2_object<'gc>(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
let point = activation.avm2().classes().point;
|
||||
let map_point = point.construct(
|
||||
activation,
|
||||
&[self.map_point.0.into(), self.map_point.1.into()],
|
||||
)?;
|
||||
let mode = match self.mode {
|
||||
DisplacementMapFilterMode::Clamp => "clamp",
|
||||
DisplacementMapFilterMode::Color => "color",
|
||||
DisplacementMapFilterMode::Ignore => "ignore",
|
||||
DisplacementMapFilterMode::Wrap => "wrap",
|
||||
};
|
||||
activation.avm2().classes().displacementmapfilter.construct(
|
||||
activation,
|
||||
&[
|
||||
Value::Null, // TODO: This should be a BitmapData...
|
||||
map_point.into(),
|
||||
self.component_x.into(),
|
||||
self.component_y.into(),
|
||||
self.scale_x.into(),
|
||||
self.scale_y.into(),
|
||||
mode.into(),
|
||||
self.color.to_rgb().into(),
|
||||
(f64::from(self.color.a) / 255.0).into(),
|
||||
],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::bitmap::BitmapHandle;
|
||||
use swf::{BevelFilterFlags, Color, Fixed16};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -6,6 +7,7 @@ pub enum Filter {
|
|||
BlurFilter(BlurFilter),
|
||||
ColorMatrixFilter(ColorMatrixFilter),
|
||||
ConvolutionFilter(ConvolutionFilter),
|
||||
DisplacementMapFilter(DisplacementMapFilter),
|
||||
}
|
||||
|
||||
impl Default for Filter {
|
||||
|
@ -174,3 +176,46 @@ impl Default for ConvolutionFilter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DisplacementMapFilterComponent {
|
||||
Alpha,
|
||||
Blue,
|
||||
Green,
|
||||
Red,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DisplacementMapFilterMode {
|
||||
Clamp,
|
||||
Color,
|
||||
Ignore,
|
||||
Wrap,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DisplacementMapFilter {
|
||||
pub color: Color,
|
||||
pub component_x: u8,
|
||||
pub component_y: u8,
|
||||
pub map_bitmap: Option<BitmapHandle>,
|
||||
pub map_point: (u32, u32),
|
||||
pub mode: DisplacementMapFilterMode,
|
||||
pub scale_x: f32,
|
||||
pub scale_y: f32,
|
||||
}
|
||||
|
||||
impl Default for DisplacementMapFilter {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
color: Color::from_rgba(0),
|
||||
component_x: 0,
|
||||
component_y: 0,
|
||||
map_bitmap: None,
|
||||
map_point: (0, 0),
|
||||
mode: DisplacementMapFilterMode::Wrap,
|
||||
scale_x: 0.0,
|
||||
scale_y: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue