Separate opacity out from paint.
This allows `globalAlpha` to work on render targets.
This commit is contained in:
parent
1deb53fa9c
commit
77b3555828
|
@ -103,12 +103,9 @@ impl CanvasRenderingContext2D {
|
||||||
let paint = self.current_state.resolve_paint(&paint);
|
let paint = self.current_state.resolve_paint(&paint);
|
||||||
let paint_id = self.scene.push_paint(&paint);
|
let paint_id = self.scene.push_paint(&paint);
|
||||||
|
|
||||||
self.scene.push_path(DrawPath::new(outline,
|
let mut path = DrawPath::new(outline, paint_id);
|
||||||
paint_id,
|
path.set_blend_mode(BlendMode::Clear);
|
||||||
None,
|
self.scene.push_path(path);
|
||||||
FillRule::Winding,
|
|
||||||
BlendMode::Clear,
|
|
||||||
String::new()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line styles
|
// Line styles
|
||||||
|
@ -224,8 +221,9 @@ impl CanvasRenderingContext2D {
|
||||||
let mut outline = path.into_outline();
|
let mut outline = path.into_outline();
|
||||||
outline.transform(&self.current_state.transform);
|
outline.transform(&self.current_state.transform);
|
||||||
|
|
||||||
let clip_path_id = self.scene
|
let mut clip_path = ClipPath::new(outline);
|
||||||
.push_clip_path(ClipPath::new(outline, fill_rule, String::new()));
|
clip_path.set_fill_rule(fill_rule);
|
||||||
|
let clip_path_id = self.scene.push_clip_path(clip_path);
|
||||||
|
|
||||||
self.current_state.clip_path = Some(clip_path_id);
|
self.current_state.clip_path = Some(clip_path_id);
|
||||||
}
|
}
|
||||||
|
@ -234,6 +232,7 @@ impl CanvasRenderingContext2D {
|
||||||
let clip_path = self.current_state.clip_path;
|
let clip_path = self.current_state.clip_path;
|
||||||
let blend_mode = self.current_state.global_composite_operation.to_blend_mode();
|
let blend_mode = self.current_state.global_composite_operation.to_blend_mode();
|
||||||
let composite_op = self.current_state.global_composite_operation.to_composite_op();
|
let composite_op = self.current_state.global_composite_operation.to_composite_op();
|
||||||
|
let opacity = (self.current_state.global_alpha * 255.0) as u8;
|
||||||
|
|
||||||
if !self.current_state.shadow_paint.is_fully_transparent() {
|
if !self.current_state.shadow_paint.is_fully_transparent() {
|
||||||
let render_target_id = self.push_render_target_if_needed(composite_op);
|
let render_target_id = self.push_render_target_if_needed(composite_op);
|
||||||
|
@ -243,24 +242,24 @@ impl CanvasRenderingContext2D {
|
||||||
|
|
||||||
let mut outline = outline.clone();
|
let mut outline = outline.clone();
|
||||||
outline.transform(&Transform2F::from_translation(self.current_state.shadow_offset));
|
outline.transform(&Transform2F::from_translation(self.current_state.shadow_offset));
|
||||||
self.scene.push_path(DrawPath::new(outline,
|
let mut path = DrawPath::new(outline, paint_id);
|
||||||
paint_id,
|
path.set_clip_path(clip_path);
|
||||||
clip_path,
|
path.set_fill_rule(fill_rule);
|
||||||
fill_rule,
|
path.set_blend_mode(blend_mode);
|
||||||
blend_mode,
|
path.set_opacity(opacity);
|
||||||
String::new()));
|
self.scene.push_path(path);
|
||||||
|
|
||||||
self.composite_render_target_if_needed(composite_op, render_target_id);
|
self.composite_render_target_if_needed(composite_op, render_target_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let render_target_id = self.push_render_target_if_needed(composite_op);
|
let render_target_id = self.push_render_target_if_needed(composite_op);
|
||||||
|
|
||||||
self.scene.push_path(DrawPath::new(outline,
|
let mut path = DrawPath::new(outline, paint_id);
|
||||||
paint_id,
|
path.set_clip_path(clip_path);
|
||||||
clip_path,
|
path.set_fill_rule(fill_rule);
|
||||||
fill_rule,
|
path.set_blend_mode(blend_mode);
|
||||||
blend_mode,
|
path.set_opacity(opacity);
|
||||||
String::new()));
|
self.scene.push_path(path);
|
||||||
|
|
||||||
self.composite_render_target_if_needed(composite_op, render_target_id);
|
self.composite_render_target_if_needed(composite_op, render_target_id);
|
||||||
}
|
}
|
||||||
|
@ -387,12 +386,11 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_paint<'a>(&self, paint: &'a Paint) -> Cow<'a, Paint> {
|
fn resolve_paint<'a>(&self, paint: &'a Paint) -> Cow<'a, Paint> {
|
||||||
if self.global_alpha == 1.0 && (paint.is_color() || self.transform.is_identity()) {
|
if self.transform.is_identity() {
|
||||||
return Cow::Borrowed(paint);
|
return Cow::Borrowed(paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut paint = (*paint).clone();
|
let mut paint = (*paint).clone();
|
||||||
paint.set_opacity(self.global_alpha);
|
|
||||||
paint.apply_transform(&self.transform);
|
paint.apply_transform(&self.transform);
|
||||||
Cow::Owned(paint)
|
Cow::Owned(paint)
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,12 +148,6 @@ impl Gradient {
|
||||||
.lerp(upper_stop.color.to_f32(), (t - lower_stop.offset) / denom)
|
.lerp(upper_stop.color.to_f32(), (t - lower_stop.offset) / denom)
|
||||||
.to_u8()
|
.to_u8()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_opacity(&mut self, alpha: f32) {
|
|
||||||
for stop in &mut self.stops.array {
|
|
||||||
stop.color.a = (stop.color.a as f32 * alpha).round() as u8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorStop {
|
impl ColorStop {
|
||||||
|
|
|
@ -86,17 +86,6 @@ impl Image {
|
||||||
pub fn is_opaque(&self) -> bool {
|
pub fn is_opaque(&self) -> bool {
|
||||||
self.is_opaque
|
self.is_opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_opacity(&mut self, alpha: f32) {
|
|
||||||
debug_assert!(alpha >= 0.0 && alpha <= 1.0);
|
|
||||||
if alpha == 1.0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(pcwalton): Go four pixels at a time with SIMD.
|
|
||||||
self.pixels.iter_mut().for_each(|pixel| pixel.a = (pixel.a as f32 * alpha).round() as u8);
|
|
||||||
self.is_opaque = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PatternSource {
|
impl PatternSource {
|
||||||
|
@ -110,18 +99,6 @@ impl PatternSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_opacity(&mut self, alpha: f32) {
|
|
||||||
match *self {
|
|
||||||
PatternSource::Image(ref mut image) => image.set_opacity(alpha),
|
|
||||||
PatternSource::RenderTarget(_) => {
|
|
||||||
// TODO(pcwalton): We'll probably have to introduce and use an Opacity filter for
|
|
||||||
// this.
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Image {
|
impl Debug for Image {
|
||||||
|
|
|
@ -365,6 +365,9 @@ impl Device for MetalDevice {
|
||||||
(VertexAttrClass::Int, VertexAttrType::I8, 1) => MTLVertexFormat::Char,
|
(VertexAttrClass::Int, VertexAttrType::I8, 1) => MTLVertexFormat::Char,
|
||||||
(VertexAttrClass::Int, VertexAttrType::U8, 1) => MTLVertexFormat::UChar,
|
(VertexAttrClass::Int, VertexAttrType::U8, 1) => MTLVertexFormat::UChar,
|
||||||
(VertexAttrClass::FloatNorm, VertexAttrType::I8, 1) => MTLVertexFormat::CharNormalized,
|
(VertexAttrClass::FloatNorm, VertexAttrType::I8, 1) => MTLVertexFormat::CharNormalized,
|
||||||
|
(VertexAttrClass::FloatNorm, VertexAttrType::U8, 1) => {
|
||||||
|
MTLVertexFormat::UCharNormalized
|
||||||
|
}
|
||||||
(VertexAttrClass::Int, VertexAttrType::I16, 1) => MTLVertexFormat::Short,
|
(VertexAttrClass::Int, VertexAttrType::I16, 1) => MTLVertexFormat::Short,
|
||||||
(VertexAttrClass::Int, VertexAttrType::U16, 1) => MTLVertexFormat::UShort,
|
(VertexAttrClass::Int, VertexAttrType::U16, 1) => MTLVertexFormat::UShort,
|
||||||
(VertexAttrClass::FloatNorm, VertexAttrType::U16, 1) => {
|
(VertexAttrClass::FloatNorm, VertexAttrType::U16, 1) => {
|
||||||
|
|
|
@ -180,6 +180,7 @@ impl<'a> SceneBuilder<'a> {
|
||||||
TilingPathInfo::Draw {
|
TilingPathInfo::Draw {
|
||||||
paint_metadata,
|
paint_metadata,
|
||||||
blend_mode: path_object.blend_mode(),
|
blend_mode: path_object.blend_mode(),
|
||||||
|
opacity: path_object.opacity(),
|
||||||
built_clip_path,
|
built_clip_path,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -670,27 +671,32 @@ impl ObjectBuilder {
|
||||||
mask_tile_index: u16,
|
mask_tile_index: u16,
|
||||||
tile_coords: Vector2I,
|
tile_coords: Vector2I,
|
||||||
object_index: u16,
|
object_index: u16,
|
||||||
|
opacity: u8,
|
||||||
paint_metadata: &PaintMetadata) {
|
paint_metadata: &PaintMetadata) {
|
||||||
alpha_tiles.push(AlphaTile {
|
alpha_tiles.push(AlphaTile {
|
||||||
upper_left: AlphaTileVertex::new(tile_coords,
|
upper_left: AlphaTileVertex::new(tile_coords,
|
||||||
mask_tile_index,
|
mask_tile_index,
|
||||||
Vector2I::default(),
|
Vector2I::default(),
|
||||||
object_index,
|
object_index,
|
||||||
|
opacity,
|
||||||
paint_metadata),
|
paint_metadata),
|
||||||
upper_right: AlphaTileVertex::new(tile_coords,
|
upper_right: AlphaTileVertex::new(tile_coords,
|
||||||
mask_tile_index,
|
mask_tile_index,
|
||||||
Vector2I::new(1, 0),
|
Vector2I::new(1, 0),
|
||||||
object_index,
|
object_index,
|
||||||
|
opacity,
|
||||||
paint_metadata),
|
paint_metadata),
|
||||||
lower_left: AlphaTileVertex::new(tile_coords,
|
lower_left: AlphaTileVertex::new(tile_coords,
|
||||||
mask_tile_index,
|
mask_tile_index,
|
||||||
Vector2I::new(0, 1),
|
Vector2I::new(0, 1),
|
||||||
object_index,
|
object_index,
|
||||||
|
opacity,
|
||||||
paint_metadata),
|
paint_metadata),
|
||||||
lower_right: AlphaTileVertex::new(tile_coords,
|
lower_right: AlphaTileVertex::new(tile_coords,
|
||||||
mask_tile_index,
|
mask_tile_index,
|
||||||
Vector2I::splat(1),
|
Vector2I::splat(1),
|
||||||
object_index,
|
object_index,
|
||||||
|
opacity,
|
||||||
paint_metadata),
|
paint_metadata),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -723,6 +729,7 @@ impl AlphaTileVertex {
|
||||||
tile_index: u16,
|
tile_index: u16,
|
||||||
tile_offset: Vector2I,
|
tile_offset: Vector2I,
|
||||||
object_index: u16,
|
object_index: u16,
|
||||||
|
opacity: u8,
|
||||||
paint_metadata: &PaintMetadata)
|
paint_metadata: &PaintMetadata)
|
||||||
-> AlphaTileVertex {
|
-> AlphaTileVertex {
|
||||||
let tile_position = tile_origin + tile_offset;
|
let tile_position = tile_origin + tile_offset;
|
||||||
|
@ -737,6 +744,7 @@ impl AlphaTileVertex {
|
||||||
mask_u: mask_uv.x() as u16,
|
mask_u: mask_uv.x() as u16,
|
||||||
mask_v: mask_uv.y() as u16,
|
mask_v: mask_uv.y() as u16,
|
||||||
object_index,
|
object_index,
|
||||||
|
opacity,
|
||||||
pad: 0,
|
pad: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,7 @@ impl<D> AlphaTileVertexArray<D> where D: Device {
|
||||||
"ColorTexCoord").unwrap();
|
"ColorTexCoord").unwrap();
|
||||||
let mask_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
let mask_tex_coord_attr = device.get_vertex_attr(&alpha_tile_program.program,
|
||||||
"MaskTexCoord").unwrap();
|
"MaskTexCoord").unwrap();
|
||||||
|
let opacity_attr = device.get_vertex_attr(&alpha_tile_program.program, "Opacity").unwrap();
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, alpha_tile_vertex_buffer, BufferTarget::Vertex);
|
device.bind_buffer(&vertex_array, alpha_tile_vertex_buffer, BufferTarget::Vertex);
|
||||||
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
device.configure_vertex_attr(&vertex_array, &tile_position_attr, &VertexAttrDescriptor {
|
||||||
|
@ -222,6 +223,15 @@ impl<D> AlphaTileVertexArray<D> where D: Device {
|
||||||
divisor: 0,
|
divisor: 0,
|
||||||
buffer_index: 0,
|
buffer_index: 0,
|
||||||
});
|
});
|
||||||
|
device.configure_vertex_attr(&vertex_array, &opacity_attr, &VertexAttrDescriptor {
|
||||||
|
size: 1,
|
||||||
|
class: VertexAttrClass::FloatNorm,
|
||||||
|
attr_type: VertexAttrType::U8,
|
||||||
|
stride: ALPHA_TILE_VERTEX_SIZE,
|
||||||
|
offset: 14,
|
||||||
|
divisor: 0,
|
||||||
|
buffer_index: 0,
|
||||||
|
});
|
||||||
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
device.bind_buffer(&vertex_array, quads_vertex_indices_buffer, BufferTarget::Index);
|
||||||
|
|
||||||
AlphaTileVertexArray { vertex_array }
|
AlphaTileVertexArray { vertex_array }
|
||||||
|
|
|
@ -173,7 +173,8 @@ pub struct AlphaTileVertex {
|
||||||
pub color_u: u16,
|
pub color_u: u16,
|
||||||
pub color_v: u16,
|
pub color_v: u16,
|
||||||
pub object_index: u16,
|
pub object_index: u16,
|
||||||
pub pad: u16,
|
pub opacity: u8,
|
||||||
|
pub pad: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for RenderCommand {
|
impl Debug for RenderCommand {
|
||||||
|
|
|
@ -113,18 +113,6 @@ impl Paint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_opacity(&mut self, alpha: f32) {
|
|
||||||
if alpha == 1.0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
Paint::Color(ref mut color) => color.a = (color.a as f32 * alpha).round() as u8,
|
|
||||||
Paint::Gradient(ref mut gradient) => gradient.set_opacity(alpha),
|
|
||||||
Paint::Pattern(ref mut pattern) => pattern.source.set_opacity(alpha),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_transform(&mut self, transform: &Transform2F) {
|
pub fn apply_transform(&mut self, transform: &Transform2F) {
|
||||||
if transform.is_identity() {
|
if transform.is_identity() {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -226,6 +226,7 @@ pub struct DrawPath {
|
||||||
clip_path: Option<ClipPathId>,
|
clip_path: Option<ClipPathId>,
|
||||||
fill_rule: FillRule,
|
fill_rule: FillRule,
|
||||||
blend_mode: BlendMode,
|
blend_mode: BlendMode,
|
||||||
|
opacity: u8,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,14 +268,16 @@ pub enum DisplayItem {
|
||||||
|
|
||||||
impl DrawPath {
|
impl DrawPath {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(outline: Outline,
|
pub fn new(outline: Outline, paint: PaintId) -> DrawPath {
|
||||||
paint: PaintId,
|
DrawPath {
|
||||||
clip_path: Option<ClipPathId>,
|
outline,
|
||||||
fill_rule: FillRule,
|
paint,
|
||||||
blend_mode: BlendMode,
|
clip_path: None,
|
||||||
name: String)
|
fill_rule: FillRule::Winding,
|
||||||
-> DrawPath {
|
blend_mode: BlendMode::SrcOver,
|
||||||
DrawPath { outline, paint, clip_path, fill_rule, blend_mode, name }
|
opacity: !0,
|
||||||
|
name: String::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -287,6 +290,11 @@ impl DrawPath {
|
||||||
self.clip_path
|
self.clip_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_clip_path(&mut self, new_clip_path: Option<ClipPathId>) {
|
||||||
|
self.clip_path = new_clip_path
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn paint(&self) -> PaintId {
|
pub(crate) fn paint(&self) -> PaintId {
|
||||||
self.paint
|
self.paint
|
||||||
|
@ -297,16 +305,41 @@ impl DrawPath {
|
||||||
self.fill_rule
|
self.fill_rule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) {
|
||||||
|
self.fill_rule = new_fill_rule
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn blend_mode(&self) -> BlendMode {
|
pub(crate) fn blend_mode(&self) -> BlendMode {
|
||||||
self.blend_mode
|
self.blend_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_blend_mode(&mut self, new_blend_mode: BlendMode) {
|
||||||
|
self.blend_mode = new_blend_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn opacity(&self) -> u8 {
|
||||||
|
self.opacity
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_opacity(&mut self, new_opacity: u8) {
|
||||||
|
self.opacity = new_opacity
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_name(&mut self, new_name: String) {
|
||||||
|
self.name = new_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClipPath {
|
impl ClipPath {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(outline: Outline, fill_rule: FillRule, name: String) -> ClipPath {
|
pub fn new(outline: Outline) -> ClipPath {
|
||||||
ClipPath { outline, fill_rule, name }
|
ClipPath { outline, fill_rule: FillRule::Winding, name: String::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -318,6 +351,16 @@ impl ClipPath {
|
||||||
pub(crate) fn fill_rule(&self) -> FillRule {
|
pub(crate) fn fill_rule(&self) -> FillRule {
|
||||||
self.fill_rule
|
self.fill_rule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_fill_rule(&mut self, new_fill_rule: FillRule) {
|
||||||
|
self.fill_rule = new_fill_rule
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_name(&mut self, new_name: String) {
|
||||||
|
self.name = new_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTarget {
|
impl RenderTarget {
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub(crate) enum TilingPathInfo<'a> {
|
||||||
Draw {
|
Draw {
|
||||||
paint_metadata: &'a PaintMetadata,
|
paint_metadata: &'a PaintMetadata,
|
||||||
blend_mode: BlendMode,
|
blend_mode: BlendMode,
|
||||||
|
opacity: u8,
|
||||||
built_clip_path: Option<&'a BuiltPath>,
|
built_clip_path: Option<&'a BuiltPath>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -127,10 +128,10 @@ impl<'a> Tiler<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pack_and_cull_draw_path(&mut self) {
|
fn pack_and_cull_draw_path(&mut self) {
|
||||||
let (paint_metadata, blend_mode, built_clip_path) = match self.path_info {
|
let (paint_metadata, blend_mode, opacity, built_clip_path) = match self.path_info {
|
||||||
TilingPathInfo::Clip => unreachable!(),
|
TilingPathInfo::Clip => unreachable!(),
|
||||||
TilingPathInfo::Draw { paint_metadata, blend_mode, built_clip_path } => {
|
TilingPathInfo::Draw { paint_metadata, blend_mode, opacity, built_clip_path } => {
|
||||||
(paint_metadata, blend_mode, built_clip_path)
|
(paint_metadata, blend_mode, opacity, built_clip_path)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,7 +182,7 @@ impl<'a> Tiler<'a> {
|
||||||
|
|
||||||
// Next, if this is a solid tile that completely occludes the background, record
|
// Next, if this is a solid tile that completely occludes the background, record
|
||||||
// that fact and stop here.
|
// that fact and stop here.
|
||||||
if paint_metadata.is_opaque && blend_mode.occludes_backdrop() {
|
if paint_metadata.is_opaque && blend_mode.occludes_backdrop() && opacity == !0 {
|
||||||
self.object_builder.built_path.solid_tiles.push(SolidTile::new(tile_coords));
|
self.object_builder.built_path.solid_tiles.push(SolidTile::new(tile_coords));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +210,7 @@ impl<'a> Tiler<'a> {
|
||||||
mask_tile_index,
|
mask_tile_index,
|
||||||
tile_coords,
|
tile_coords,
|
||||||
self.object_index,
|
self.object_index,
|
||||||
|
opacity,
|
||||||
paint_metadata);
|
paint_metadata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -20,15 +20,18 @@ uniform vec2 uTileSize;
|
||||||
in ivec2 aTilePosition;
|
in ivec2 aTilePosition;
|
||||||
in vec2 aColorTexCoord;
|
in vec2 aColorTexCoord;
|
||||||
in vec2 aMaskTexCoord;
|
in vec2 aMaskTexCoord;
|
||||||
|
in float aOpacity;
|
||||||
|
|
||||||
out vec2 vColorTexCoord;
|
out vec2 vColorTexCoord;
|
||||||
out vec2 vMaskTexCoord;
|
out vec2 vMaskTexCoord;
|
||||||
|
out float vOpacity;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec2 position = aTilePosition * uTileSize;
|
vec2 position = aTilePosition * uTileSize;
|
||||||
|
|
||||||
vMaskTexCoord = aMaskTexCoord;
|
vMaskTexCoord = aMaskTexCoord;
|
||||||
vColorTexCoord = aColorTexCoord;
|
vColorTexCoord = aColorTexCoord;
|
||||||
|
vOpacity = aOpacity;
|
||||||
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -40,12 +40,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -45,12 +45,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -38,12 +38,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
|
|
||||||
vec4 sampleSrcColor(){
|
vec4 sampleSrcColor(){
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord). r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA . rgb, srcRGBA . a * coverage);
|
return vec4(srcRGBA . rgb, srcRGBA . a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor(){
|
vec4 sampleDestColor(){
|
||||||
|
|
|
@ -23,19 +23,20 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
out.oFragColor = float4(srcRGBA.xyz * srcRGBA.w, srcRGBA.w);
|
out.oFragColor = float4(srcRGBA.xyz * srcRGBA.w, srcRGBA.w);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct main0_out
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
float4 gl_Position [[position]];
|
float4 gl_Position [[position]];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ struct main0_in
|
||||||
int2 aTilePosition [[attribute(0)]];
|
int2 aTilePosition [[attribute(0)]];
|
||||||
float2 aColorTexCoord [[attribute(1)]];
|
float2 aColorTexCoord [[attribute(1)]];
|
||||||
float2 aMaskTexCoord [[attribute(2)]];
|
float2 aMaskTexCoord [[attribute(2)]];
|
||||||
|
float aOpacity [[attribute(3)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
|
@ -30,6 +32,7 @@ vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer
|
||||||
float2 position = float2(in.aTilePosition) * (*spvDescriptorSet0.uTileSize);
|
float2 position = float2(in.aTilePosition) * (*spvDescriptorSet0.uTileSize);
|
||||||
out.vMaskTexCoord = in.aMaskTexCoord;
|
out.vMaskTexCoord = in.aMaskTexCoord;
|
||||||
out.vColorTexCoord = in.aColorTexCoord;
|
out.vColorTexCoord = in.aColorTexCoord;
|
||||||
|
out.vOpacity = in.aOpacity;
|
||||||
out.gl_Position = (*spvDescriptorSet0.uTransform) * float4(position, 0.0, 1.0);
|
out.gl_Position = (*spvDescriptorSet0.uTransform) * float4(position, 0.0, 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -49,7 +50,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
float3 blended = abs(destRGBA.xyz - srcRGBA.xyz);
|
float3 blended = abs(destRGBA.xyz - srcRGBA.xyz);
|
||||||
float4 param = destRGBA;
|
float4 param = destRGBA;
|
||||||
|
|
|
@ -27,13 +27,14 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -50,57 +51,57 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
float3 _118;
|
float3 _122;
|
||||||
if ((*spvDescriptorSet0.uBurn) == 0)
|
if ((*spvDescriptorSet0.uBurn) == 0)
|
||||||
{
|
{
|
||||||
_118 = destRGBA.xyz;
|
_122 = destRGBA.xyz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_118 = float3(1.0) - destRGBA.xyz;
|
_122 = float3(1.0) - destRGBA.xyz;
|
||||||
}
|
}
|
||||||
float3 dest = _118;
|
float3 dest = _122;
|
||||||
float3 _132;
|
float3 _136;
|
||||||
if ((*spvDescriptorSet0.uBurn) == 0)
|
if ((*spvDescriptorSet0.uBurn) == 0)
|
||||||
{
|
{
|
||||||
_132 = float3(1.0) - srcRGBA.xyz;
|
_136 = float3(1.0) - srcRGBA.xyz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_132 = srcRGBA.xyz;
|
_136 = srcRGBA.xyz;
|
||||||
}
|
}
|
||||||
float3 src = _132;
|
float3 src = _136;
|
||||||
bool3 srcNonzero = src != float3(0.0);
|
bool3 srcNonzero = src != float3(0.0);
|
||||||
float _153;
|
float _157;
|
||||||
if (srcNonzero.x)
|
if (srcNonzero.x)
|
||||||
{
|
{
|
||||||
_153 = dest.x / src.x;
|
_157 = dest.x / src.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_153 = 1.0;
|
_157 = 1.0;
|
||||||
}
|
}
|
||||||
float _166;
|
float _170;
|
||||||
if (srcNonzero.y)
|
if (srcNonzero.y)
|
||||||
{
|
{
|
||||||
_166 = dest.y / src.y;
|
_170 = dest.y / src.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_166 = 1.0;
|
_170 = 1.0;
|
||||||
}
|
}
|
||||||
float _179;
|
float _183;
|
||||||
if (srcNonzero.z)
|
if (srcNonzero.z)
|
||||||
{
|
{
|
||||||
_179 = dest.z / src.z;
|
_183 = dest.z / src.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_179 = 1.0;
|
_183 = 1.0;
|
||||||
}
|
}
|
||||||
float3 blended = fast::min(float3(_153, _166, _179), float3(1.0));
|
float3 blended = fast::min(float3(_157, _170, _183), float3(1.0));
|
||||||
if ((*spvDescriptorSet0.uBurn) != 0)
|
if ((*spvDescriptorSet0.uBurn) != 0)
|
||||||
{
|
{
|
||||||
blended = float3(1.0) - blended;
|
blended = float3(1.0) - blended;
|
||||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -49,7 +50,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
float3 dest = destRGBA.xyz;
|
float3 dest = destRGBA.xyz;
|
||||||
float3 src = srcRGBA.xyz;
|
float3 src = srcRGBA.xyz;
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
|
// Implementation of the GLSL mod() function, which is slightly different than Metal fmod()
|
||||||
|
@ -36,11 +37,11 @@ Tx mod(Tx x, Ty y)
|
||||||
return x - y * floor(x / y);
|
return x - y * floor(x / y);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -85,34 +86,34 @@ float3 convertRGBToHSL(thread const float3& rgb)
|
||||||
|
|
||||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||||
{
|
{
|
||||||
float _125;
|
float _129;
|
||||||
if (cond.x)
|
if (cond.x)
|
||||||
{
|
{
|
||||||
_125 = a.x;
|
_129 = a.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_125 = b.x;
|
_129 = b.x;
|
||||||
}
|
}
|
||||||
float _137;
|
float _141;
|
||||||
if (cond.y)
|
if (cond.y)
|
||||||
{
|
{
|
||||||
_137 = a.y;
|
_141 = a.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_137 = b.y;
|
_141 = b.y;
|
||||||
}
|
}
|
||||||
float _149;
|
float _153;
|
||||||
if (cond.z)
|
if (cond.z)
|
||||||
{
|
{
|
||||||
_149 = a.z;
|
_153 = a.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_149 = b.z;
|
_153 = b.z;
|
||||||
}
|
}
|
||||||
return float3(_125, _137, _149);
|
return float3(_129, _141, _153);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 convertHSLToRGB(thread const float3& hsl)
|
float3 convertHSLToRGB(thread const float3& hsl)
|
||||||
|
@ -130,7 +131,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
float3 param = destRGBA.xyz;
|
float3 param = destRGBA.xyz;
|
||||||
float3 destHSL = convertRGBToHSL(param);
|
float3 destHSL = convertRGBToHSL(param);
|
||||||
|
|
|
@ -27,13 +27,14 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -44,34 +45,34 @@ float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSi
|
||||||
|
|
||||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||||
{
|
{
|
||||||
float _118;
|
float _122;
|
||||||
if (cond.x)
|
if (cond.x)
|
||||||
{
|
{
|
||||||
_118 = a.x;
|
_122 = a.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_118 = b.x;
|
_122 = b.x;
|
||||||
}
|
}
|
||||||
float _130;
|
float _134;
|
||||||
if (cond.y)
|
if (cond.y)
|
||||||
{
|
{
|
||||||
_130 = a.y;
|
_134 = a.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_130 = b.y;
|
_134 = b.y;
|
||||||
}
|
}
|
||||||
float _142;
|
float _146;
|
||||||
if (cond.z)
|
if (cond.z)
|
||||||
{
|
{
|
||||||
_142 = a.z;
|
_146 = a.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_142 = b.z;
|
_146 = b.z;
|
||||||
}
|
}
|
||||||
return float3(_118, _130, _142);
|
return float3(_122, _134, _146);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
||||||
|
@ -82,29 +83,29 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
bool reversed = (*spvDescriptorSet0.uBlendMode) == 3;
|
bool reversed = (*spvDescriptorSet0.uBlendMode) == 3;
|
||||||
float3 _167;
|
float3 _171;
|
||||||
if (reversed)
|
if (reversed)
|
||||||
{
|
{
|
||||||
_167 = srcRGBA.xyz;
|
_171 = srcRGBA.xyz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_167 = destRGBA.xyz;
|
_171 = destRGBA.xyz;
|
||||||
}
|
}
|
||||||
float3 src = _167;
|
float3 src = _171;
|
||||||
float3 _178;
|
float3 _182;
|
||||||
if (reversed)
|
if (reversed)
|
||||||
{
|
{
|
||||||
_178 = destRGBA.xyz;
|
_182 = destRGBA.xyz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_178 = srcRGBA.xyz;
|
_182 = srcRGBA.xyz;
|
||||||
}
|
}
|
||||||
float3 dest = _178;
|
float3 dest = _182;
|
||||||
float3 multiply = src * dest;
|
float3 multiply = src * dest;
|
||||||
float3 blended;
|
float3 blended;
|
||||||
if ((*spvDescriptorSet0.uBlendMode) == 0)
|
if ((*spvDescriptorSet0.uBlendMode) == 0)
|
||||||
|
|
|
@ -26,13 +26,14 @@ struct main0_in
|
||||||
{
|
{
|
||||||
float2 vColorTexCoord [[user(locn0)]];
|
float2 vColorTexCoord [[user(locn0)]];
|
||||||
float2 vMaskTexCoord [[user(locn1)]];
|
float2 vMaskTexCoord [[user(locn1)]];
|
||||||
|
float vOpacity [[user(locn2)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord)
|
float4 sampleSrcColor(thread texture2d<float> uStencilTexture, thread const sampler uStencilTextureSmplr, thread float2& vMaskTexCoord, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& vColorTexCoord, thread float& vOpacity)
|
||||||
{
|
{
|
||||||
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
float coverage = uStencilTexture.sample(uStencilTextureSmplr, vMaskTexCoord).x;
|
||||||
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
float4 srcRGBA = uPaintTexture.sample(uPaintTextureSmplr, vColorTexCoord);
|
||||||
return float4(srcRGBA.xyz, srcRGBA.w * coverage);
|
return float4(srcRGBA.xyz, (srcRGBA.w * coverage) * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSize, thread texture2d<float> uDest, thread const sampler uDestSmplr)
|
||||||
|
@ -43,34 +44,34 @@ float4 sampleDestColor(thread float4& gl_FragCoord, thread float2 uFramebufferSi
|
||||||
|
|
||||||
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
float3 select3(thread const bool3& cond, thread const float3& a, thread const float3& b)
|
||||||
{
|
{
|
||||||
float _118;
|
float _122;
|
||||||
if (cond.x)
|
if (cond.x)
|
||||||
{
|
{
|
||||||
_118 = a.x;
|
_122 = a.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_118 = b.x;
|
_122 = b.x;
|
||||||
}
|
}
|
||||||
float _130;
|
float _134;
|
||||||
if (cond.y)
|
if (cond.y)
|
||||||
{
|
{
|
||||||
_130 = a.y;
|
_134 = a.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_130 = b.y;
|
_134 = b.y;
|
||||||
}
|
}
|
||||||
float _142;
|
float _146;
|
||||||
if (cond.z)
|
if (cond.z)
|
||||||
{
|
{
|
||||||
_142 = a.z;
|
_146 = a.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_142 = b.z;
|
_146 = b.z;
|
||||||
}
|
}
|
||||||
return float3(_118, _130, _142);
|
return float3(_122, _134, _146);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA, thread const float3& blendedRGB)
|
||||||
|
@ -81,7 +82,7 @@ float4 blendColors(thread const float4& destRGBA, thread const float4& srcRGBA,
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], float4 gl_FragCoord [[position]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord);
|
float4 srcRGBA = sampleSrcColor(spvDescriptorSet0.uStencilTexture, spvDescriptorSet0.uStencilTextureSmplr, in.vMaskTexCoord, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.vColorTexCoord, in.vOpacity);
|
||||||
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
float4 destRGBA = sampleDestColor(gl_FragCoord, (*spvDescriptorSet0.uFramebufferSize), spvDescriptorSet0.uDest, spvDescriptorSet0.uDestSmplr);
|
||||||
float3 dest = destRGBA.xyz;
|
float3 dest = destRGBA.xyz;
|
||||||
float3 src = srcRGBA.xyz;
|
float3 src = srcRGBA.xyz;
|
||||||
|
|
|
@ -18,14 +18,17 @@ uniform vec2 uTileSize;
|
||||||
in ivec2 aTilePosition;
|
in ivec2 aTilePosition;
|
||||||
in vec2 aColorTexCoord;
|
in vec2 aColorTexCoord;
|
||||||
in vec2 aMaskTexCoord;
|
in vec2 aMaskTexCoord;
|
||||||
|
in float aOpacity;
|
||||||
|
|
||||||
out vec2 vColorTexCoord;
|
out vec2 vColorTexCoord;
|
||||||
out vec2 vMaskTexCoord;
|
out vec2 vMaskTexCoord;
|
||||||
|
out float vOpacity;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 position = aTilePosition * uTileSize;
|
vec2 position = aTilePosition * uTileSize;
|
||||||
|
|
||||||
vMaskTexCoord = aMaskTexCoord;
|
vMaskTexCoord = aMaskTexCoord;
|
||||||
vColorTexCoord = aColorTexCoord;
|
vColorTexCoord = aColorTexCoord;
|
||||||
|
vOpacity = aOpacity;
|
||||||
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
gl_Position = uTransform * vec4(position, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,13 @@ uniform vec2 uFramebufferSize;
|
||||||
|
|
||||||
in vec2 vColorTexCoord;
|
in vec2 vColorTexCoord;
|
||||||
in vec2 vMaskTexCoord;
|
in vec2 vMaskTexCoord;
|
||||||
|
in float vOpacity;
|
||||||
|
|
||||||
// NB: This does not premultiply.
|
// NB: This does not premultiply.
|
||||||
vec4 sampleSrcColor() {
|
vec4 sampleSrcColor() {
|
||||||
float coverage = texture(uStencilTexture, vMaskTexCoord).r;
|
float coverage = texture(uStencilTexture, vMaskTexCoord).r;
|
||||||
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
vec4 srcRGBA = texture(uPaintTexture, vColorTexCoord);
|
||||||
return vec4(srcRGBA.rgb, srcRGBA.a * coverage);
|
return vec4(srcRGBA.rgb, srcRGBA.a * coverage * vOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sampleDestColor() {
|
vec4 sampleDestColor() {
|
||||||
|
|
|
@ -15,7 +15,6 @@ extern crate bitflags;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_content::effects::BlendMode;
|
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::outline::Outline;
|
use pathfinder_content::outline::Outline;
|
||||||
use pathfinder_content::segment::{Segment, SegmentFlags};
|
use pathfinder_content::segment::{Segment, SegmentFlags};
|
||||||
|
@ -180,9 +179,9 @@ impl BuiltSVG {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(clip_outline) = clip_outline {
|
if let Some(clip_outline) = clip_outline {
|
||||||
let name = format!("ClipPath({})", node.id());
|
|
||||||
// FIXME(pcwalton): Is the winding fill rule correct to use?
|
// FIXME(pcwalton): Is the winding fill rule correct to use?
|
||||||
let clip_path = ClipPath::new(clip_outline, FillRule::Winding, name);
|
let mut clip_path = ClipPath::new(clip_outline);
|
||||||
|
clip_path.set_name(format!("ClipPath({})", node.id()));
|
||||||
let clip_path_id = self.scene.push_clip_path(clip_path);
|
let clip_path_id = self.scene.push_clip_path(clip_path);
|
||||||
self.clip_paths.insert(node.id().to_owned(), clip_path_id);
|
self.clip_paths.insert(node.id().to_owned(), clip_path_id);
|
||||||
}
|
}
|
||||||
|
@ -232,16 +231,14 @@ impl BuiltSVG {
|
||||||
paint: &UsvgPaint,
|
paint: &UsvgPaint,
|
||||||
opacity: Opacity,
|
opacity: Opacity,
|
||||||
fill_rule: UsvgFillRule) {
|
fill_rule: UsvgFillRule) {
|
||||||
let style = self.scene.push_paint(&Paint::from_svg_paint(paint,
|
let style = self.scene.push_paint(&Paint::from_svg_paint(paint, &mut self.result_flags));
|
||||||
opacity,
|
|
||||||
&mut self.result_flags));
|
|
||||||
let fill_rule = FillRule::from_usvg_fill_rule(fill_rule);
|
let fill_rule = FillRule::from_usvg_fill_rule(fill_rule);
|
||||||
self.scene.push_path(DrawPath::new(outline,
|
let mut path = DrawPath::new(outline, style);
|
||||||
style,
|
path.set_clip_path(state.clip_path);
|
||||||
state.clip_path,
|
path.set_fill_rule(fill_rule);
|
||||||
fill_rule,
|
path.set_name(name);
|
||||||
BlendMode::SrcOver,
|
path.set_opacity((opacity.value() * 255.0) as u8);
|
||||||
name));
|
self.scene.push_path(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,17 +285,15 @@ impl Display for BuildResultFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PaintExt {
|
trait PaintExt {
|
||||||
fn from_svg_paint(svg_paint: &UsvgPaint, opacity: Opacity, result_flags: &mut BuildResultFlags)
|
fn from_svg_paint(svg_paint: &UsvgPaint, result_flags: &mut BuildResultFlags) -> Self;
|
||||||
-> Self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintExt for Paint {
|
impl PaintExt for Paint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_svg_paint(svg_paint: &UsvgPaint, opacity: Opacity, result_flags: &mut BuildResultFlags)
|
fn from_svg_paint(svg_paint: &UsvgPaint, result_flags: &mut BuildResultFlags) -> Paint {
|
||||||
-> Paint {
|
|
||||||
// TODO(pcwalton): Support gradients.
|
// TODO(pcwalton): Support gradients.
|
||||||
Paint::Color(match *svg_paint {
|
Paint::Color(match *svg_paint {
|
||||||
UsvgPaint::Color(color) => ColorU::from_svg_color(color, opacity),
|
UsvgPaint::Color(color) => ColorU::from_svg_color(color),
|
||||||
UsvgPaint::Link(_) => {
|
UsvgPaint::Link(_) => {
|
||||||
// TODO(pcwalton)
|
// TODO(pcwalton)
|
||||||
result_flags.insert(BuildResultFlags::UNSUPPORTED_LINK_PAINT);
|
result_flags.insert(BuildResultFlags::UNSUPPORTED_LINK_PAINT);
|
||||||
|
@ -412,18 +407,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ColorUExt {
|
trait ColorUExt {
|
||||||
fn from_svg_color(svg_color: SvgColor, opacity: Opacity) -> Self;
|
fn from_svg_color(svg_color: SvgColor) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorUExt for ColorU {
|
impl ColorUExt for ColorU {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_svg_color(svg_color: SvgColor, opacity: Opacity) -> ColorU {
|
fn from_svg_color(svg_color: SvgColor) -> ColorU {
|
||||||
ColorU {
|
ColorU { r: svg_color.red, g: svg_color.green, b: svg_color.blue, a: !0 }
|
||||||
r: svg_color.red,
|
|
||||||
g: svg_color.green,
|
|
||||||
b: svg_color.blue,
|
|
||||||
a: (opacity.value() * 255.0).round() as u8,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use pathfinder_color::{ColorF, ColorU};
|
use pathfinder_color::{ColorF, ColorU};
|
||||||
use pathfinder_content::effects::BlendMode;
|
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::outline::{Outline, Contour};
|
use pathfinder_content::outline::{Outline, Contour};
|
||||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||||
|
@ -196,14 +195,9 @@ pub fn draw_paths_into_scene(library: &SymbolLibrary, scene: &mut Scene) {
|
||||||
path = stroke_to_fill.into_outline();
|
path = stroke_to_fill.into_outline();
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.push_path(DrawPath::new(
|
let mut path = DrawPath::new(path, paint_id);
|
||||||
path,
|
path.set_fill_rule(FillRule::EvenOdd);
|
||||||
paint_id,
|
scene.push_path(path);
|
||||||
None,
|
|
||||||
FillRule::EvenOdd,
|
|
||||||
BlendMode::SrcOver,
|
|
||||||
String::new()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,6 @@ use font_kit::error::GlyphLoadingError;
|
||||||
use font_kit::hinting::HintingOptions;
|
use font_kit::hinting::HintingOptions;
|
||||||
use font_kit::loader::Loader;
|
use font_kit::loader::Loader;
|
||||||
use lyon_path::builder::{FlatPathBuilder, PathBuilder, Build};
|
use lyon_path::builder::{FlatPathBuilder, PathBuilder, Build};
|
||||||
use pathfinder_content::effects::BlendMode;
|
|
||||||
use pathfinder_content::fill::FillRule;
|
|
||||||
use pathfinder_content::outline::{Contour, Outline};
|
use pathfinder_content::outline::{Contour, Outline};
|
||||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||||
use pathfinder_geometry::transform2d::Transform2F;
|
use pathfinder_geometry::transform2d::Transform2F;
|
||||||
|
@ -78,13 +76,7 @@ impl SceneExt for Scene {
|
||||||
outline = stroke_to_fill.into_outline();
|
outline = stroke_to_fill.into_outline();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push_path(DrawPath::new(outline,
|
self.push_path(DrawPath::new(outline, paint_id));
|
||||||
paint_id,
|
|
||||||
None,
|
|
||||||
FillRule::Winding,
|
|
||||||
BlendMode::SrcOver,
|
|
||||||
String::new()));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue