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, }); }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
/// <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); }
public virtual void Draw(IVertexBatch vertexBatch) { GLWrapper.SetBlend(DrawInfo.Blending); }
public virtual void Draw() { Shader.SetGlobalProperty("g_WorldMatrix", WorldMatrix); GLWrapper.SetBlend(Blending); }
/// <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); }
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(); }