/// <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; }
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); }
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)); }
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); }
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; }
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); }
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) ) )); }
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(); }
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));