private static void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwritePreviousScissor) { FlushCurrentBatch(); GlobalPropertyManager.Set(GlobalProperty.MaskingRect, new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); GlobalPropertyManager.Set(GlobalProperty.ToMaskingSpace, maskingInfo.ToMaskingSpace); GlobalPropertyManager.Set(GlobalProperty.CornerRadius, maskingInfo.CornerRadius); GlobalPropertyManager.Set(GlobalProperty.BorderThickness, maskingInfo.BorderThickness / maskingInfo.BlendRange); if (maskingInfo.BorderThickness > 0) { GlobalPropertyManager.Set(GlobalProperty.BorderColour, new Vector4( maskingInfo.BorderColour.Linear.R, maskingInfo.BorderColour.Linear.G, maskingInfo.BorderColour.Linear.B, maskingInfo.BorderColour.Linear.A)); } GlobalPropertyManager.Set(GlobalProperty.MaskingBlendRange, maskingInfo.BlendRange); GlobalPropertyManager.Set(GlobalProperty.AlphaExponent, maskingInfo.AlphaExponent); GlobalPropertyManager.Set(GlobalProperty.EdgeOffset, maskingInfo.EdgeOffset); GlobalPropertyManager.Set(GlobalProperty.DiscardInner, maskingInfo.Hollow); RectangleI actualRect = maskingInfo.ScreenSpaceAABB; actualRect.X += Viewport.X; actualRect.Y += Viewport.Y; // Ensure the rectangle only has positive width and height. (Required by OGL) if (actualRect.Width < 0) { actualRect.X += actualRect.Width; actualRect.Width = -actualRect.Width; } if (actualRect.Height < 0) { actualRect.Y += actualRect.Height; actualRect.Height = -actualRect.Height; } if (isPushing) { scissor_rect_stack.Push(overwritePreviousScissor ? actualRect : RectangleI.Intersect(scissor_rect_stack.Peek(), actualRect)); } else { Trace.Assert(scissor_rect_stack.Count > 1); scissor_rect_stack.Pop(); } UpdateScissorToCurrentViewportAndOrtho(); }
private static void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwritePreviousScissor) { FlushCurrentBatch(); GlobalPropertyManager.Set(GlobalProperty.MaskingRect, new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); GlobalPropertyManager.Set(GlobalProperty.ToMaskingSpace, maskingInfo.ToMaskingSpace); GlobalPropertyManager.Set(GlobalProperty.CornerRadius, maskingInfo.CornerRadius); GlobalPropertyManager.Set(GlobalProperty.CornerExponent, maskingInfo.CornerExponent); GlobalPropertyManager.Set(GlobalProperty.BorderThickness, maskingInfo.BorderThickness / maskingInfo.BlendRange); if (maskingInfo.BorderThickness > 0) { GlobalPropertyManager.Set(GlobalProperty.BorderColour, new Vector4( maskingInfo.BorderColour.Linear.R, maskingInfo.BorderColour.Linear.G, maskingInfo.BorderColour.Linear.B, maskingInfo.BorderColour.Linear.A)); } GlobalPropertyManager.Set(GlobalProperty.MaskingBlendRange, maskingInfo.BlendRange); GlobalPropertyManager.Set(GlobalProperty.AlphaExponent, maskingInfo.AlphaExponent); GlobalPropertyManager.Set(GlobalProperty.EdgeOffset, maskingInfo.EdgeOffset); GlobalPropertyManager.Set(GlobalProperty.DiscardInner, maskingInfo.Hollow); if (maskingInfo.Hollow) { GlobalPropertyManager.Set(GlobalProperty.InnerCornerRadius, maskingInfo.HollowCornerRadius); } if (isPushing) { // When drawing to a viewport that doesn't match the projection size (e.g. via framebuffers), the resultant image will be scaled Vector2 viewportScale = Vector2.Divide(Viewport.Size, Ortho.Size); Vector2 location = (maskingInfo.ScreenSpaceAABB.Location - ScissorOffset) * viewportScale; Vector2 size = maskingInfo.ScreenSpaceAABB.Size * viewportScale; RectangleI actualRect = new RectangleI( (int)Math.Floor(location.X), (int)Math.Floor(location.Y), (int)Math.Ceiling(size.X), (int)Math.Ceiling(size.Y)); PushScissor(overwritePreviousScissor ? actualRect : RectangleI.Intersect(scissor_rect_stack.Peek(), actualRect)); } else { PopScissor(); } }
/// <summary> /// Applies a new scissor rectangle. /// </summary> /// <param name="maskingInfo">The masking info.</param> /// <param name="overwritePreviousScissor">Whether or not to shrink an existing scissor rectangle.</param> public static void PushMaskingInfo(MaskingInfo maskingInfo, bool overwritePreviousScissor = false) { masking_stack.Push(maskingInfo); if (CurrentMaskingInfo.Equals(maskingInfo)) { return; } CurrentMaskingInfo = maskingInfo; setMaskingInfo(CurrentMaskingInfo, true, overwritePreviousScissor); }
private static void setMaskingInfo(MaskingInfo maskingInfo, bool overwritePreviousScissor) { FlushCurrentBatch(); Shader.SetGlobalProperty(@"g_MaskingRect", new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); Shader.SetGlobalProperty(@"g_ToMaskingSpace", maskingInfo.ToMaskingSpace); Shader.SetGlobalProperty(@"g_CornerRadius", maskingInfo.CornerRadius); Shader.SetGlobalProperty(@"g_BorderThickness", maskingInfo.BorderThickness / maskingInfo.BlendRange); Color4 linearBorderColour = maskingInfo.BorderColour.toLinear(); Shader.SetGlobalProperty(@"g_BorderColour", new Vector4( linearBorderColour.R, linearBorderColour.G, linearBorderColour.B, linearBorderColour.A)); Shader.SetGlobalProperty(@"g_MaskingBlendRange", maskingInfo.BlendRange); Rectangle actualRect = maskingInfo.ScreenSpaceAABB; actualRect.X += Viewport.X; actualRect.Y += Viewport.Y; // Ensure the rectangle only has positive width and height. (Required by OGL) if (actualRect.Width < 0) { actualRect.X += actualRect.Width; actualRect.Width = -actualRect.Width; } if (actualRect.Height < 0) { actualRect.Y += actualRect.Height; actualRect.Height = -actualRect.Height; } if (overwritePreviousScissor) { currentScissorRect = actualRect; } else { currentScissorRect.Intersect(actualRect); } UpdateScissorToCurrentViewportAndOrtho(); }
/// <summary> /// Applies the last scissor rectangle. /// </summary> public static void PopMaskingInfo() { Trace.Assert(masking_stack.Count > 1); masking_stack.Pop(); MaskingInfo maskingInfo = masking_stack.Peek(); if (CurrentMaskingInfo.Equals(maskingInfo)) { return; } CurrentMaskingInfo = maskingInfo; setMaskingInfo(CurrentMaskingInfo, false, true); }
private static void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwritePreviousScissor) { FlushCurrentBatch(); Shader.SetGlobalProperty(@"g_MaskingRect", new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); Shader.SetGlobalProperty(@"g_ToMaskingSpace", maskingInfo.ToMaskingSpace); Shader.SetGlobalProperty(@"g_CornerRadius", maskingInfo.CornerRadius); Shader.SetGlobalProperty(@"g_BorderThickness", maskingInfo.BorderThickness / maskingInfo.BlendRange); Shader.SetGlobalProperty(@"g_BorderColour", new Vector4( maskingInfo.BorderColour.Linear.R, maskingInfo.BorderColour.Linear.G, maskingInfo.BorderColour.Linear.B, maskingInfo.BorderColour.Linear.A)); Shader.SetGlobalProperty(@"g_MaskingBlendRange", maskingInfo.BlendRange); Shader.SetGlobalProperty(@"g_AlphaExponent", maskingInfo.AlphaExponent); Rectangle actualRect = maskingInfo.ScreenSpaceAABB; actualRect.X += Viewport.X; actualRect.Y += Viewport.Y; // Ensure the rectangle only has positive width and height. (Required by OGL) if (actualRect.Width < 0) { actualRect.X += actualRect.Width; actualRect.Width = -actualRect.Width; } if (actualRect.Height < 0) { actualRect.Y += actualRect.Height; actualRect.Height = -actualRect.Height; } if (isPushing) { Rectangle currentScissorRect; if (overwritePreviousScissor) { currentScissorRect = actualRect; } else { currentScissorRect = scissorRectStack.Peek(); currentScissorRect.Intersect(actualRect); } scissorRectStack.Push(currentScissorRect); } else { Debug.Assert(scissorRectStack.Count > 1); scissorRectStack.Pop(); } UpdateScissorToCurrentViewportAndOrtho(); }