예제 #1
0
        private void drawEdgeEffect()
        {
            if (MaskingInfo == null || EdgeEffect.Type == EdgeEffectType.None || EdgeEffect.Radius <= 0.0f || EdgeEffect.Colour.Linear.A <= 0.0f)
            {
                return;
            }

            RectangleF effectRect = MaskingInfo.Value.MaskingRect.Inflate(EdgeEffect.Radius).Offset(EdgeEffect.Offset);

            if (!ScreenSpaceMaskingQuad.HasValue)
            {
                ScreenSpaceMaskingQuad = Quad.FromRectangle(effectRect) * DrawInfo.Matrix;
            }

            MaskingInfo edgeEffectMaskingInfo = MaskingInfo.Value;

            edgeEffectMaskingInfo.MaskingRect     = effectRect;
            edgeEffectMaskingInfo.ScreenSpaceAABB = ScreenSpaceMaskingQuad.Value.AABB;
            edgeEffectMaskingInfo.CornerRadius   += EdgeEffect.Radius + EdgeEffect.Roundness;
            edgeEffectMaskingInfo.BorderThickness = 0;
            // HACK HACK HACK. We abuse blend range to give us the linear alpha gradient of
            // the edge effect along its radius using the same rounded-corners shader.
            edgeEffectMaskingInfo.BlendRange    = EdgeEffect.Radius;
            edgeEffectMaskingInfo.AlphaExponent = 2;
            edgeEffectMaskingInfo.EdgeOffset    = EdgeEffect.Offset;
            edgeEffectMaskingInfo.Hollow        = EdgeEffect.Hollow;

            GLWrapper.PushMaskingInfo(edgeEffectMaskingInfo);

            GLWrapper.SetBlend(new BlendingInfo(EdgeEffect.Type == EdgeEffectType.Glow ? BlendingMode.Additive : BlendingMode.Mixture));

            Shader.Bind();

            ColourInfo colour = ColourInfo.SingleColour(EdgeEffect.Colour);

            colour.TopLeft.MultiplyAlpha(DrawColourInfo.Colour.TopLeft.Linear.A);
            colour.BottomLeft.MultiplyAlpha(DrawColourInfo.Colour.BottomLeft.Linear.A);
            colour.TopRight.MultiplyAlpha(DrawColourInfo.Colour.TopRight.Linear.A);
            colour.BottomRight.MultiplyAlpha(DrawColourInfo.Colour.BottomRight.Linear.A);

            Texture.WhitePixel.DrawQuad(
                ScreenSpaceMaskingQuad.Value,
                colour, null, null, null,
                // HACK HACK HACK. We re-use the unused vertex blend range to store the original
                // masking blend range when rendering edge effects. This is needed for smooth inner edges
                // with a hollow edge effect.
                new Vector2(MaskingInfo.Value.BlendRange));

            Shader.Unbind();

            GLWrapper.PopMaskingInfo();
        }
 protected override void PreDrawMask(FrameBuffer clippingMask)
 {
     clippingMask.Bind();
     GLWrapper.PushViewport(new RectangleI(0, 0, clippingMask.Texture.Width, clippingMask.Texture.Height));
     GLWrapper.Clear(new ClearInfo(Colour4.White));
     GLWrapper.SetBlend(new BlendingParameters
     {
         Source           = BlendingType.Zero,
         Destination      = BlendingType.OneMinusSrcColor,
         SourceAlpha      = BlendingType.Zero,
         DestinationAlpha = BlendingType.OneMinusSrcAlpha,
     });
 }
예제 #3
0
        public void DrawSubTree()
        {
            PreDraw();

            GLWrapper.SetBlend(DrawInfo.Blending.Source, DrawInfo.Blending.Destination);

            Draw();

            foreach (DrawNode child in Children)
            {
                child.DrawSubTree();
            }

            PostDraw();
        }
        public override void Draw(Action <TexturedVertex2D> vertexAction)
        {
            Vector2 frameBufferSize = new Vector2((float)Math.Ceiling(ScreenSpaceDrawRectangle.Width), (float)Math.Ceiling(ScreenSpaceDrawRectangle.Height));

            if (UpdateVersion > DrawVersion.Value || frameBufferSize != FrameBuffers[0].Size)
            {
                DrawVersion.Value = UpdateVersion;

                using (establishFrameBufferViewport(frameBufferSize))
                {
                    drawChildren(vertexAction, frameBufferSize);

                    // Blur post-processing in case a blur radius is defined.
                    int radiusX = BlurSigma.X > 0 ? findBlurRadius(BlurSigma.X) : 0;
                    int radiusY = BlurSigma.Y > 0 ? findBlurRadius(BlurSigma.Y) : 0;

                    if (radiusX > 0 || radiusY > 0)
                    {
                        GL.Disable(EnableCap.ScissorTest);

                        if (radiusX > 0)
                        {
                            drawBlurredFrameBuffer(radiusX, BlurSigma.X, BlurRotation);
                        }
                        if (radiusY > 0)
                        {
                            drawBlurredFrameBuffer(radiusY, BlurSigma.Y, BlurRotation + 90);
                        }

                        GL.Enable(EnableCap.ScissorTest);
                    }
                }

                finalizeFrameBuffer();
            }

            RectangleF drawRectangle = FilteringMode == All.Nearest
                ? new RectangleF(ScreenSpaceDrawRectangle.X, ScreenSpaceDrawRectangle.Y, frameBufferSize.X, frameBufferSize.Y)
                : ScreenSpaceDrawRectangle;

            // Blit the final framebuffer to screen.
            GLWrapper.SetBlend(DrawInfo.Blending);

            Shader.Bind();
            drawFrameBufferToBackBuffer(FrameBuffers[0], drawRectangle, DrawInfo.Colour);
            Shader.Unbind();
        }
        protected override void PostDraw()
        {
            frameBuffer.Unbind();

            GLWrapper.PopOrtho();
            GLWrapper.PopViewport();

            GLWrapper.SetBlend(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);

            Rectangle textureRect = new Rectangle(0, frameBuffer.Texture.Height, frameBuffer.Texture.Width, -frameBuffer.Texture.Height);

            frameBuffer.Texture.Draw(ScreenSpaceDrawQuad, textureRect, DrawInfo.Colour, quadBatch);

            // In the case of nested framebuffer containerse we need to draw to
            // the last framebuffer container immediately, so let's force it
            ActiveBatch.Draw();
        }
예제 #6
0
        private void drawEdgeEffect()
        {
            if (MaskingInfo == null || EdgeEffect.Type == EdgeEffectType.None || EdgeEffect.Radius <= 0.0f || EdgeEffect.Colour.Linear.A <= 0.0f)
            {
                return;
            }

            RectangleF effectRect = MaskingInfo.Value.MaskingRect.Inflate(EdgeEffect.Radius).Offset(EdgeEffect.Offset);

            if (!ScreenSpaceMaskingQuad.HasValue)
            {
                ScreenSpaceMaskingQuad = Quad.FromRectangle(effectRect) * DrawInfo.Matrix;
            }

            MaskingInfo edgeEffectMaskingInfo = MaskingInfo.Value;

            edgeEffectMaskingInfo.MaskingRect     = effectRect;
            edgeEffectMaskingInfo.ScreenSpaceAABB = ScreenSpaceMaskingQuad.Value.AABB;
            edgeEffectMaskingInfo.CornerRadius   += EdgeEffect.Radius + EdgeEffect.Roundness;
            edgeEffectMaskingInfo.BorderThickness = 0;
            edgeEffectMaskingInfo.BlendRange      = EdgeEffect.Radius;
            edgeEffectMaskingInfo.AlphaExponent   = 2;
            edgeEffectMaskingInfo.Hollow          = EdgeEffect.Hollow;

            GLWrapper.PushMaskingInfo(edgeEffectMaskingInfo);

            GLWrapper.SetBlend(new BlendingInfo(EdgeEffect.Type == EdgeEffectType.Glow ? BlendingMode.Additive : BlendingMode.Mixture));

            Shader.Bind();

            ColourInfo colour = ColourInfo.SingleColour(EdgeEffect.Colour);

            colour.TopLeft.MultiplyAlpha(DrawInfo.Colour.TopLeft.Linear.A);
            colour.BottomLeft.MultiplyAlpha(DrawInfo.Colour.BottomLeft.Linear.A);
            colour.TopRight.MultiplyAlpha(DrawInfo.Colour.TopRight.Linear.A);
            colour.BottomRight.MultiplyAlpha(DrawInfo.Colour.BottomRight.Linear.A);

            Texture.WhitePixel.DrawQuad(ScreenSpaceMaskingQuad.Value, colour);

            Shader.Unbind();

            GLWrapper.PopMaskingInfo();
        }
예제 #7
0
            protected override void DrawContents()
            {
                if (drawOriginal && effectPlacement == EffectPlacement.InFront)
                {
                    base.DrawContents();
                }

                GLWrapper.SetBlend(effectBlending);

                ColourInfo finalEffectColour = DrawColourInfo.Colour;

                finalEffectColour.ApplyChild(effectColour);

                DrawFrameBuffer(SharedData.CurrentEffectBuffer, DrawRectangle, finalEffectColour);

                if (drawOriginal && effectPlacement == EffectPlacement.Behind)
                {
                    base.DrawContents();
                }
            }
        public override void Draw(IVertexBatch vertexBatch)
        {
            if (ForceRedraw.Reset() > 0)
            {
                Vector2 frameBufferSize = new Vector2((float)Math.Ceiling(ScreenSpaceDrawRectangle.Width), (float)Math.Ceiling(ScreenSpaceDrawRectangle.Height));

                using (establishFrameBufferViewport(frameBufferSize))
                {
                    drawChildren(vertexBatch, frameBufferSize);

                    // Blur post-processing in case a blur radius is defined.
                    int radiusX = BlurSigma.X > 0 ? findBlurRadius(BlurSigma.X) : 0;
                    int radiusY = BlurSigma.Y > 0 ? findBlurRadius(BlurSigma.Y) : 0;

                    if (radiusX > 0 || radiusY > 0)
                    {
                        GL.Disable(EnableCap.ScissorTest);

                        if (radiusX > 0)
                        {
                            drawBlurredFrameBuffer(radiusX, BlurSigma.X, BlurRotation);
                        }
                        if (radiusY > 0)
                        {
                            drawBlurredFrameBuffer(radiusY, BlurSigma.Y, BlurRotation + 90);
                        }

                        GL.Enable(EnableCap.ScissorTest);
                    }
                }

                finalizeFrameBuffer();
            }

            // Blit the final framebuffer to screen.
            GLWrapper.SetBlend(DrawInfo.Blending);

            Shader.Bind();
            drawFrameBufferToBackBuffer(FrameBuffers[0], ScreenSpaceDrawRectangle);
            Shader.Unbind();
        }
예제 #9
0
        private void drawEdgeEffect()
        {
            if (MaskingInfo == null || EdgeEffect.Type == EdgeEffectType.None || EdgeEffect.Radius <= 0.0f || EdgeEffect.Colour.A <= 0.0f)
            {
                return;
            }

            RectangleF effectRect = MaskingInfo.Value.MaskingRect.Inflate(EdgeEffect.Radius).Offset(EdgeEffect.Offset);

            if (!ScreenSpaceMaskingQuad.HasValue)
            {
                ScreenSpaceMaskingQuad = Quad.FromRectangle(effectRect) * DrawInfo.Matrix;
            }

            MaskingInfo edgeEffectMaskingInfo = MaskingInfo.Value;

            edgeEffectMaskingInfo.MaskingRect     = effectRect;
            edgeEffectMaskingInfo.ScreenSpaceAABB = ScreenSpaceMaskingQuad.Value.AABB;
            edgeEffectMaskingInfo.CornerRadius   += EdgeEffect.Radius + EdgeEffect.Roundness;
            edgeEffectMaskingInfo.BorderThickness = 0;
            edgeEffectMaskingInfo.BlendRange      = EdgeEffect.Radius;

            GLWrapper.PushMaskingInfo(edgeEffectMaskingInfo);

            GLWrapper.SetBlend(new BlendingInfo(EdgeEffect.Type == EdgeEffectType.Glow ? BlendingMode.Additive : BlendingMode.Mixture));

            Shader.Bind();

            Color4 colour = EdgeEffect.Colour;

            colour.A *= DrawInfo.Colour.A;

            Texture.WhitePixel.Draw(ScreenSpaceMaskingQuad.Value, colour);

            Shader.Unbind();

            GLWrapper.PopMaskingInfo();
        }
예제 #10
0
        public override void Draw()
        {
            if (Texture == null)
            {
                return;
            }

            // For billboarding
            Shader.SetGlobalProperty("g_InverseViewMatrix", InverseViewMatrix);

            // Taken from DrawNode3D, since we don't need the world transform for particle systems
            GLWrapper.SetBlend(Blending);

            Shader.Bind();

            // Force create a separate batch so we can use instanced rendering
            if (particleInstancedBatch == null)
            {
                particleInstancedBatch = new QuadBatch <TexturedVertex2D>(TexturedVertex2D.Stride * 4, 1);
            }

            var colourInfo = new ColourInfo {
                Colour = Color4.White
            };

            Texture.DrawQuad(new Quad(-0.5f, -0.5f, 1.0f, 1.0f), colourInfo, vertexAction: v => particleInstancedBatch.Add(v));

            // Set GPU buffer data
            Buffer.SetData(BufferData);

            Buffer.Bind();

            // Render instanced
            particleInstancedBatch.DrawInstanced(InstanceCount);

            Shader.Unbind();
        }
예제 #11
0
            private void drawBlurredFrameBuffer(int kernelRadius, float sigma, float blurRotation)
            {
                FrameBuffer current = SharedData.CurrentEffectBuffer;
                FrameBuffer target  = SharedData.GetNextEffectBuffer();

                GLWrapper.SetBlend(BlendingParameters.None);

                using (BindFrameBuffer(target))
                {
                    blurShader.GetUniform <int>(@"g_Radius").UpdateValue(ref kernelRadius);
                    blurShader.GetUniform <float>(@"g_Sigma").UpdateValue(ref sigma);

                    Vector2 size = current.Size;
                    blurShader.GetUniform <Vector2>(@"g_TexSize").UpdateValue(ref size);

                    float   radians = -MathUtils.DegreesToRadians(blurRotation);
                    Vector2 blur    = new Vector2(MathF.Cos(radians), MathF.Sin(radians));
                    blurShader.GetUniform <Vector2>(@"g_BlurDirection").UpdateValue(ref blur);

                    blurShader.Bind();
                    DrawFrameBuffer(current, new RectangleF(0, 0, current.Texture.Width, current.Texture.Height), ColourInfo.SingleColour(Color4.White));
                    blurShader.Unbind();
                }
            }
            public override void Draw(Action <TexturedVertex2D> vertexAction)
            {
                base.Draw(vertexAction);

                if (texture?.Available != true || segments.Count == 0)
                {
                    return;
                }

                GLWrapper.PushDepthInfo(DepthInfo.Default);

                // Blending is removed to allow for correct blending between the wedges of the path.
                GLWrapper.SetBlend(BlendingParameters.None);

                pathShader.Bind();

                texture.TextureGL.Bind();

                updateVertexBuffer();

                pathShader.Unbind();

                GLWrapper.PopDepthInfo();
            }
            private void drawBlurredFrameBuffer(int kernelRadius, float sigma, float blurRotation)
            {
                FrameBuffer source = currentFrameBuffer;
                FrameBuffer target = advanceFrameBuffer();

                GLWrapper.SetBlend(new BlendingInfo(BlendingMode.None));

                using (bindFrameBuffer(target, source.Size))
                {
                    blurShader.GetUniform <int>(@"g_Radius").UpdateValue(ref kernelRadius);
                    blurShader.GetUniform <float>(@"g_Sigma").UpdateValue(ref sigma);

                    Vector2 size = source.Size;
                    blurShader.GetUniform <Vector2>(@"g_TexSize").UpdateValue(ref size);

                    float   radians = -MathHelper.DegreesToRadians(blurRotation);
                    Vector2 blur    = new Vector2((float)Math.Cos(radians), (float)Math.Sin(radians));
                    blurShader.GetUniform <Vector2>(@"g_BlurDirection").UpdateValue(ref blur);

                    blurShader.Bind();
                    drawFrameBufferToBackBuffer(source, new RectangleF(0, 0, source.Texture.Width, source.Texture.Height), ColourInfo.SingleColour(Color4.White));
                    blurShader.Unbind();
                }
            }
        public override void Draw(Action <TexturedVertex2D> vertexAction)
        {
            currentFrameBufferIndex = originalIndex;

            Vector2 frameBufferSize = new Vector2((float)Math.Ceiling(ScreenSpaceDrawRectangle.Width), (float)Math.Ceiling(ScreenSpaceDrawRectangle.Height));

            if (RequiresRedraw)
            {
                Shared.DrawVersion = UpdateVersion;

                using (establishFrameBufferViewport(frameBufferSize))
                {
                    drawChildren(vertexAction, frameBufferSize);

                    // Blur post-processing in case a blur radius is defined.
                    if (BlurRadius.X > 0 || BlurRadius.Y > 0)
                    {
                        GL.Disable(EnableCap.ScissorTest);

                        if (BlurRadius.X > 0)
                        {
                            drawBlurredFrameBuffer(BlurRadius.X, BlurSigma.X, BlurRotation);
                        }
                        if (BlurRadius.Y > 0)
                        {
                            drawBlurredFrameBuffer(BlurRadius.Y, BlurSigma.Y, BlurRotation + 90);
                        }

                        GL.Enable(EnableCap.ScissorTest);
                    }
                }

                finalizeFrameBuffer();
            }

            RectangleF drawRectangle = FilteringMode == All.Nearest
                ? new RectangleF(ScreenSpaceDrawRectangle.X, ScreenSpaceDrawRectangle.Y, frameBufferSize.X, frameBufferSize.Y)
                : ScreenSpaceDrawRectangle;

            Shader.Bind();

            if (DrawOriginal && EffectPlacement == EffectPlacement.InFront)
            {
                GLWrapper.SetBlend(DrawColourInfo.Blending);
                drawFrameBufferToBackBuffer(Shared.FrameBuffers[originalIndex], drawRectangle, DrawColourInfo.Colour);
            }

            // Blit the final framebuffer to screen.
            GLWrapper.SetBlend(new BlendingInfo(EffectBlending));

            ColourInfo effectColour = DrawColourInfo.Colour;

            effectColour.ApplyChild(EffectColour);
            drawFrameBufferToBackBuffer(Shared.FrameBuffers[0], drawRectangle, effectColour);

            if (DrawOriginal && EffectPlacement == EffectPlacement.Behind)
            {
                GLWrapper.SetBlend(DrawColourInfo.Blending);
                drawFrameBufferToBackBuffer(Shared.FrameBuffers[originalIndex], drawRectangle, DrawColourInfo.Colour);
            }

            Shader.Unbind();
        }
예제 #15
0
 /// <summary>
 /// Draws this draw node to the screen.
 /// </summary>
 /// <param name="vertexAction">The action to be performed on each vertex of
 /// the draw node in order to draw it if required. This is primarily used by
 /// textured sprites.</param>
 public virtual void Draw(Action <TexturedVertex2D> vertexAction)
 {
     GLWrapper.SetBlend(DrawColourInfo.Blending);
 }
예제 #16
0
 public virtual void Draw(IVertexBatch vertexBatch)
 {
     GLWrapper.SetBlend(DrawInfo.Blending);
 }
예제 #17
0
 public virtual void Draw()
 {
     Shader.SetGlobalProperty("g_WorldMatrix", WorldMatrix);
     GLWrapper.SetBlend(Blending);
 }
예제 #18
0
 /// <summary>
 /// Draws the opaque interior of this <see cref="DrawNode"/> to the screen.
 /// The opaque interior must be a fully-opaque, non-blended area of this <see cref="DrawNode"/>, clipped to the current masking area via <code>DrawClipped()</code>.
 /// See <see cref="Shapes.Box.BoxDrawNode"/> for an example implementation.
 /// </summary>
 /// <remarks>
 /// Subclasses must invoke <code>base.DrawOpaqueInterior()</code> prior to drawing vertices.
 /// </remarks>
 /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
 protected virtual void DrawOpaqueInterior(Action <TexturedVertex2D> vertexAction)
 {
     GLWrapper.SetBlend(DrawColourInfo.Blending);
     GLWrapper.SetDrawDepth(drawDepth);
 }
예제 #19
0
 public virtual void Draw(Action <TexturedVertex2D> vertexAction)
 {
     GLWrapper.SetDepthTest(NeedsDepthTest);
     GLWrapper.SetBlend(DrawInfo.Blending);
 }
        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();
        }