Esempio n. 1
0
        /// <summary>
        /// Sets the blending function to draw with.
        /// </summary>
        /// <param name="blendingParameters">The info we should use to update the active state.</param>
        public static void SetBlend(BlendingParameters blendingParameters)
        {
            if (lastBlendingParameters == blendingParameters)
            {
                return;
            }

            FlushCurrentBatch();

            if (blendingParameters.IsDisabled)
            {
                if (!lastBlendingEnabledState.HasValue || lastBlendingEnabledState.Value)
                {
                    GL.Disable(EnableCap.Blend);
                }

                lastBlendingEnabledState = false;
            }
            else
            {
                if (!lastBlendingEnabledState.HasValue || !lastBlendingEnabledState.Value)
                {
                    GL.Enable(EnableCap.Blend);
                }

                lastBlendingEnabledState = true;

                GL.BlendEquationSeparate(blendingParameters.RGBEquationMode, blendingParameters.AlphaEquationMode);
                GL.BlendFuncSeparate(blendingParameters.SourceBlendingFactor, blendingParameters.DestinationBlendingFactor,
                                     blendingParameters.SourceAlphaBlendingFactor, blendingParameters.DestinationAlphaBlendingFactor);
            }

            lastBlendingParameters = blendingParameters;
        }
Esempio n. 2
0
        public BlendingParameters Deserialize(string data)
        {
            var parts = data.SplitByComma();

            if (parts.Length == 0)
            {
                throw new MarkupException($"Unrecognized {nameof(BlendingParameters)}.");
            }

            var blending = new BlendingParameters
            {
                Mode = Enum.Parse <BlendingMode>(parts[0], ignoreCase: true)
            };

            BlendingEquation?alpha = null;
            BlendingEquation?rgb   = null;

            void parseEquation(string part)
            {
                if (part.StartsWith("alpha(", StringComparison.OrdinalIgnoreCase) && part.EndsWith(')'))
                {
                    if (alpha.HasValue)
                    {
                        throw new MarkupException($"Cannot specify multiple alpha equations.");
                    }

                    alpha = Enum.Parse <BlendingEquation>(part.Substring(6, part.Length - 7), ignoreCase: true);
                }
                else if (part.StartsWith("rgb(", StringComparison.OrdinalIgnoreCase) && part.EndsWith(')'))
                {
                    if (rgb.HasValue)
                    {
                        throw new MarkupException($"Cannot specify multiple RGB equations.");
                    }

                    rgb = Enum.Parse <BlendingEquation>(part.Substring(4, part.Length - 5), ignoreCase: true);
                }
            }

            if (parts.Length > 1)
            {
                parseEquation(parts[1]);
            }
            if (parts.Length > 2)
            {
                parseEquation(parts[2]);
            }
            if (parts.Length > 3)
            {
                throw new MarkupException($"Unknown {nameof(BlendingParameters)} component '{parts[3]}'.");
            }

            blending.AlphaEquation = alpha ?? BlendingEquation.Inherit;
            blending.RGBEquation   = rgb ?? BlendingEquation.Inherit;

            return(blending);
        }
Esempio n. 3
0
        internal static void Reset(Vector2 size)
        {
            Trace.Assert(shader_stack.Count == 0);

            reset_scheduler.Update();

            if (expensive_operations_queue.TryDequeue(out Action action))
            {
                action.Invoke();
            }

            Array.Clear(last_bound_texture, 0, last_bound_texture.Length);
            lastActiveBatch          = null;
            lastBlendingParameters   = new BlendingParameters();
            lastBlendingEnabledState = null;

            foreach (var b in batch_reset_list)
            {
                b.ResetCounters();
            }
            batch_reset_list.Clear();

            viewport_stack.Clear();
            ortho_stack.Clear();
            masking_stack.Clear();
            scissor_rect_stack.Clear();
            frame_buffer_stack.Clear();
            depth_stack.Clear();
            scissor_state_stack.Clear();
            scissor_offset_stack.Clear();

            BindFrameBuffer(DefaultFrameBuffer);

            Scissor       = RectangleI.Empty;
            ScissorOffset = Vector2I.Zero;
            Viewport      = RectangleI.Empty;
            Ortho         = RectangleF.Empty;

            PushScissorState(true);
            PushViewport(new RectangleI(0, 0, (int)size.X, (int)size.Y));
            PushScissor(new RectangleI(0, 0, (int)size.X, (int)size.Y));
            PushScissorOffset(Vector2I.Zero);
            PushMaskingInfo(new MaskingInfo
            {
                ScreenSpaceAABB = new RectangleI(0, 0, (int)size.X, (int)size.Y),
                MaskingRect     = new RectangleF(0, 0, size.X, size.Y),
                ToMaskingSpace  = Matrix3.Identity,
                BlendRange      = 1,
                AlphaExponent   = 1,
                CornerExponent  = 2.5f,
            }, true);

            PushDepthInfo(DepthInfo.Default);
            Clear(new ClearInfo(Color4.Black));
        }
Esempio n. 4
0
        public void TestBlendingFull()
        {
            //Given
            var data  = "Additive, alpha(Min), rgb(Add)";
            var value = new BlendingParameters
            {
                Mode          = BlendingMode.Additive,
                AlphaEquation = BlendingEquation.Min,
                RGBEquation   = BlendingEquation.Add
            };

            //Then
            testAssert(data, value);
        }
Esempio n. 5
0
            public override void ApplyState()
            {
                base.ApplyState();

                updateVersion = Source.updateVersion;

                effectColour    = Source.EffectColour;
                effectBlending  = Source.DrawEffectBlending;
                effectPlacement = Source.EffectPlacement;

                drawOriginal = Source.DrawOriginal;
                blurSigma    = Source.BlurSigma;
                blurRadius   = new Vector2I(Blur.KernelSize(blurSigma.X), Blur.KernelSize(blurSigma.Y));
                blurRotation = Source.BlurRotation;

                blurShader = Source.blurShader;
            }
Esempio n. 6
0
        public static string Serialize(BlendingParameters b)
        {
            var list = new List <string>();

            list.Add(b.Mode.ToString());

            if (b.AlphaEquation != default)
            {
                list.Add($"alpha({b.AlphaEquation})");
            }
            if (b.RGBEquation != default)
            {
                list.Add($"rgb({b.RGBEquation})");
            }

            return(string.Join(", ", list));
        }
        private void updateBlending()
        {
            if (colourModeDropdown.Current.Value == "Custom")
            {
                if (!inCustomMode)
                {
                    switchToCustomBlending();
                }

                var blending = new BlendingParameters
                {
                    Source           = blendingSrcDropdown.Current.Value,
                    Destination      = blendingDestDropdown.Current.Value,
                    SourceAlpha      = blendingAlphaSrcDropdown.Current.Value,
                    DestinationAlpha = blendingAlphaDestDropdown.Current.Value,
                    RGBEquation      = colourEquation.Current.Value,
                    AlphaEquation    = alphaEquation.Current.Value
                };

                Logger.Log("Changed blending mode to: " + blending, LoggingTarget.Runtime, LogLevel.Debug);

                foregroundContainer.Blending = blending;

                inCustomMode = true;
            }
            else
            {
                if (inCustomMode)
                {
                    switchOffCustomBlending();
                }

                var blending = blendingModes[colourModeDropdown.Current.Value];

                blending.RGBEquation   = colourEquation.Current.Value;
                blending.AlphaEquation = alphaEquation.Current.Value;

                Logger.Log("Changed blending mode to: " + blending, LoggingTarget.Runtime, LogLevel.Debug);

                foregroundContainer.Blending = blending;

                inCustomMode = false;
            }
        }
            public override void ApplyState()
            {
                base.ApplyState();

                screenSpaceDrawRectangle = Source.ScreenSpaceDrawQuad.AABBFloat;
                filteringMode            = Source.PixelSnapping ? All.Nearest : All.Linear;

                updateVersion    = Source.updateVersion;
                backgroundColour = Source.BackgroundColour;

                BlendingParameters localEffectBlending = Source.EffectBlending;

                if (localEffectBlending.Mode == BlendingMode.Inherit)
                {
                    localEffectBlending.Mode = Source.Blending.Mode;
                }

                if (localEffectBlending.RGBEquation == BlendingEquation.Inherit)
                {
                    localEffectBlending.RGBEquation = Source.Blending.RGBEquation;
                }

                if (localEffectBlending.AlphaEquation == BlendingEquation.Inherit)
                {
                    localEffectBlending.AlphaEquation = Source.Blending.AlphaEquation;
                }

                effectColour    = Source.EffectColour;
                effectBlending  = localEffectBlending;
                effectPlacement = Source.EffectPlacement;

                drawOriginal = Source.DrawOriginal;
                blurSigma    = Source.BlurSigma;
                blurRadius   = new Vector2I(Blur.KernelSize(blurSigma.X), Blur.KernelSize(blurSigma.Y));
                blurRotation = Source.BlurRotation;

                formats.Clear();
                formats.AddRange(Source.attachedFormats);

                blurShader = Source.blurShader;

                // BufferedContainer overrides DrawColourInfo for children, but needs to be reset to draw ourselves
                DrawColourInfo = Source.baseDrawColourInfo;
            }
        public void TestBlendingFull()
        {
            //Given
            var data =
                @"new osu.Framework.Graphics.BlendingParameters
{
    Mode = osu.Framework.Graphics.BlendingMode.Additive,
    AlphaEquation = osu.Framework.Graphics.BlendingMode.Min,
    RGBEquation = osu.Framework.Graphics.BlendingMode.Add
}";
            var value = new BlendingParameters
            {
                Mode          = BlendingMode.Additive,
                AlphaEquation = BlendingEquation.Min,
                RGBEquation   = BlendingEquation.Add
            };

            //Then
            testAssert(data, value);
        }
Esempio n. 10
0
        public static ExpressionSyntax GenerateSyntax(BlendingParameters b)
        {
            var list = new List <ExpressionSyntax>();

            if (b.Mode != default)
            {
                list.Add(AssignmentExpression(
                             kind: SyntaxKind.SimpleAssignmentExpression,
                             left: IdentifierName(nameof(BlendingParameters.Mode)),
                             right: ParseTypeName($"{typeof(BlendingMode).FullName}.{b.Mode}")
                             ));
            }
            if (b.AlphaEquation != default)
            {
                list.Add(AssignmentExpression(
                             kind: SyntaxKind.SimpleAssignmentExpression,
                             left: IdentifierName(nameof(BlendingParameters.AlphaEquation)),
                             right: ParseTypeName($"{typeof(BlendingMode).FullName}.{b.AlphaEquation}")
                             ));
            }
            if (b.RGBEquation != default)
            {
                list.Add(AssignmentExpression(
                             kind: SyntaxKind.SimpleAssignmentExpression,
                             left: IdentifierName(nameof(BlendingParameters.RGBEquation)),
                             right: ParseTypeName($"{typeof(BlendingMode).FullName}.{b.RGBEquation}")
                             ));
            }

            return(ObjectCreationExpression(
                       type: ParseTypeName(typeof(BlendingParameters).FullName),
                       argumentList: null,
                       initializer: InitializerExpression(
                           kind: SyntaxKind.ObjectInitializerExpression,
                           expressions: SeparatedList(list)
                           )
                       ));
        }
Esempio n. 11
0
        internal static void Reset(Vector2 size)
        {
            Trace.Assert(shader_stack.Count == 0);

            reset_scheduler.Update();

            stat_expensive_operations_queued.Value = expensive_operation_queue.Count;
            if (expensive_operation_queue.TryDequeue(out Action action))
            {
                action.Invoke();
            }

            stat_texture_uploads_queued.Value    = texture_upload_queue.Count;
            stat_texture_uploads_dequeued.Value  = 0;
            stat_texture_uploads_performed.Value = 0;

            // increase the number of items processed with the queue length to ensure it doesn't get out of hand.
            int targetUploads  = Math.Clamp(texture_upload_queue.Count / 2, 1, MaxTexturesUploadedPerFrame);
            int uploads        = 0;
            int uploadedPixels = 0;

            // continue attempting to upload textures until enough uploads have been performed.
            while (texture_upload_queue.TryDequeue(out TextureGL texture))
            {
                stat_texture_uploads_dequeued.Value++;

                texture.IsQueuedForUpload = false;

                if (!texture.Upload())
                {
                    continue;
                }

                stat_texture_uploads_performed.Value++;

                if (++uploads >= targetUploads)
                {
                    break;
                }

                if ((uploadedPixels += texture.Width * texture.Height) > MaxPixelsUploadedPerFrame)
                {
                    break;
                }
            }

            Array.Clear(last_bound_texture, 0, last_bound_texture.Length);
            Array.Clear(last_bound_texture_is_atlas, 0, last_bound_texture_is_atlas.Length);

            lastActiveBatch          = null;
            lastBlendingParameters   = new BlendingParameters();
            lastBlendingEnabledState = null;

            foreach (var b in batch_reset_list)
            {
                b.ResetCounters();
            }
            batch_reset_list.Clear();

            viewport_stack.Clear();
            ortho_stack.Clear();
            masking_stack.Clear();
            scissor_rect_stack.Clear();
            frame_buffer_stack.Clear();
            depth_stack.Clear();
            scissor_state_stack.Clear();
            scissor_offset_stack.Clear();

            BindFrameBuffer(DefaultFrameBuffer);

            Scissor       = RectangleI.Empty;
            ScissorOffset = Vector2I.Zero;
            Viewport      = RectangleI.Empty;
            Ortho         = RectangleF.Empty;

            PushScissorState(true);
            PushViewport(new RectangleI(0, 0, (int)size.X, (int)size.Y));
            PushScissor(new RectangleI(0, 0, (int)size.X, (int)size.Y));
            PushScissorOffset(Vector2I.Zero);
            PushMaskingInfo(new MaskingInfo
            {
                ScreenSpaceAABB = new RectangleI(0, 0, (int)size.X, (int)size.Y),
                MaskingRect     = new RectangleF(0, 0, size.X, size.Y),
                ToMaskingSpace  = Matrix3.Identity,
                BlendRange      = 1,
                AlphaExponent   = 1,
                CornerExponent  = 2.5f,
            }, true);

            PushDepthInfo(DepthInfo.Default);
            Clear(new ClearInfo(Color4.Black));
        }
        protected override void DrawMesh(CubismDrawable drawable, Texture texture, FrameBuffer clippingMask, Matrix4 drawMatrix)
        {
            int offset = 1 + (clippingMask != null ? (drawable.ConstantFlags.HasFlag(ConstantDrawableFlags.IsInvertedMask) ? 2 : 1) : 0) + (UsePremultipliedAlpha ? 3 : 0);

            IShader            shader;
            BlendingParameters blendingParameters;

            if (drawable.ConstantFlags.HasFlag(ConstantDrawableFlags.BlendMultiplicative))
            {
                shader             = shaders[offset];
                blendingParameters = new BlendingParameters
                {
                    Source           = BlendingType.DstColor,
                    Destination      = BlendingType.OneMinusSrcAlpha,
                    SourceAlpha      = BlendingType.Zero,
                    DestinationAlpha = BlendingType.One,
                };
            }
            else if (drawable.ConstantFlags.HasFlag(ConstantDrawableFlags.BlendAdditive))
            {
                shader             = shaders[offset];
                blendingParameters = new BlendingParameters
                {
                    Source           = BlendingType.One,
                    Destination      = BlendingType.One,
                    SourceAlpha      = BlendingType.Zero,
                    DestinationAlpha = BlendingType.One,
                };
            }
            else
            {
                shader             = shaders[offset];
                blendingParameters = new BlendingParameters
                {
                    Source           = BlendingType.One,
                    Destination      = BlendingType.OneMinusSrcAlpha,
                    SourceAlpha      = BlendingType.One,
                    DestinationAlpha = BlendingType.OneMinusSrcAlpha,
                };
            }

            GLWrapper.SetBlend(blendingParameters);
            shader.Bind();

            if (clippingMask != null)
            {
                clippingMask.Texture.Bind(TextureUnit.Texture1);

                shader.GetUniform <int>("s_texture1").Value        = 1;
                shader.GetUniform <Matrix4>("u_clipMatrix").Value  = drawMatrix;
                shader.GetUniform <Vector4>("u_channelFlag").Value = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
            }
            else
            {
                GLWrapper.BindTexture(null, TextureUnit.Texture1);
            }

            texture.TextureGL.Bind();

            shader.GetUniform <int>("s_texture0").Value   = 0;
            shader.GetUniform <Matrix4>("u_matrix").Value = MvpMatrix;

            var color = new Vector4(Color.R, Color.G, Color.B, Color.A);

            color.W *= drawable.Opacity;

            if (UsePremultipliedAlpha)
            {
                color.X *= drawable.Opacity;
                color.Y *= drawable.Opacity;
                color.Z *= drawable.Opacity;
            }

            shader.GetUniform <Vector4>("u_baseColor").Value = color;

            GL.EnableVertexAttribArray(0);

            fixed(float *pinnedVertexBuffer = drawable.Vertices)
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, sizeof(float) * 2, (IntPtr)pinnedVertexBuffer);

            GL.EnableVertexAttribArray(1);

            fixed(float *pinnedUVBuffer = drawable.TextureCoordinates)
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 2, (IntPtr)pinnedUVBuffer);

            fixed(short *pinnedIndexBuffer = drawable.Indices)
            GL.DrawElements(PrimitiveType.Triangles, drawable.Indices.Length, DrawElementsType.UnsignedShort, (IntPtr)pinnedIndexBuffer);

            shader.Unbind();
        }
Esempio n. 13
0
 public bool Equals(BlendingParameters other) => other.Mode == Mode && other.RGBEquation == RGBEquation && other.AlphaEquation == AlphaEquation;
 /// <summary>
 /// Adjusts <see cref="Drawable.Blending"/> after a delay.
 /// </summary>
 /// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
 public static TransformSequence <T> TransformBlendingMode <T>(this T drawable, BlendingParameters newValue, double delay = 0)
     where T : Drawable
 => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingParameters(), newValue, delay));