public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); IShader shader = needsRoundedShader ? RoundedTextureShader : TextureShader; shader.Bind(); var avgColour = (Color4)DrawColourInfo.Colour.AverageColour; float shadowAlpha = (float)Math.Pow(Math.Max(Math.Max(avgColour.R, avgColour.G), avgColour.B), 2); //adjust shadow alpha based on highest component intensity to avoid muddy display of darker text. //squared result for quadratic fall-off seems to give the best result. var shadowColour = DrawColourInfo.Colour; shadowColour.ApplyChild(ShadowColour.MultiplyAlpha(shadowAlpha)); for (int i = 0; i < Parts.Count; i++) { if (Shadow) { var shadowQuad = Parts[i].DrawQuad; shadowQuad.TopLeft += ShadowOffset; shadowQuad.TopRight += ShadowOffset; shadowQuad.BottomLeft += ShadowOffset; shadowQuad.BottomRight += ShadowOffset; Parts[i].Texture.DrawQuad(shadowQuad, shadowColour, vertexAction: vertexAction); } Parts[i].Texture.DrawQuad(Parts[i].DrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); } shader.Unbind(); }
public void Draw(DrawState state) { state.PushWorldTranslateMultiply(ref this.position); if (geometry.CullTest(state)) { //draw the geometry shader.Bind(state); geometry.Draw(state); //now, if set, draw the wireframe too if (wireframeShader != null) { wireframeShader.Bind(state); //show the wireframe, disabling depth testing state.PushRenderState(); state.RenderState.DepthColourCull.DepthTestEnabled = false; //also set additive blending state.RenderState.AlphaBlend = AlphaBlendState.Additive; //set wireframe state.RenderState.DepthColourCull.FillMode = FillMode.WireFrame; //draw geometry.Draw(state); state.PopRenderState(); } } state.PopWorldMatrix(); }
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.WrapMode = TextureWrapMode.ClampToEdge; texture.TextureGL.Bind(); updateVertexBuffer(); pathShader.Unbind(); GLWrapper.PopDepthInfo(); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); shader.Bind(); shader.GetUniform <float>("g_FadeClock").UpdateValue(ref time); for (int i = 0; i < parts.Length; ++i) { Vector2 pos = parts[i].Position; float localTime = parts[i].Time; DrawQuad( texture, new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y), DrawColourInfo.Colour, null, v => vertexBatch.Add(new TexturedTrailVertex { Position = v.Position, TexturePosition = v.TexturePosition, Time = localTime + 1, Colour = v.Colour, })); } shader.Unbind(); }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override void BindShader(DrawState state, bool maskOnly) { if (shader == null) { throw new InvalidOperationException("Shader == null"); } shader.Bind(state); }
private static void setVignetteResolution() { var resolution = AGSGame.Game.Settings.WindowSize; _vignetteShader.Compile(); _vignetteShader.Bind(); _vignetteShader.SetVariable("resolution", resolution.Width, resolution.Height); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { shader.GetUniform <float>("g_FadeClock").UpdateValue(ref time); int updateStart = -1, updateEnd = 0; for (int i = 0; i < parts.Length; ++i) { if (parts[i].WasUpdated) { if (updateStart == -1) { updateStart = i; } updateEnd = i + 1; int start = i * 4; int end = start; Vector2 pos = parts[i].Position; float localTime = parts[i].Time; texture.DrawQuad( new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y), DrawColourInfo.Colour, null, v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex { Position = v.Position, TexturePosition = v.TexturePosition, Time = localTime + 1, Colour = v.Colour, }); parts[i].WasUpdated = false; } else if (updateStart != -1) { vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); updateStart = -1; } } // Update all remaining vertices that have been changed. if (updateStart != -1) { vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4); } base.Draw(vertexAction); shader.Bind(); texture.TextureGL.Bind(); vertexBuffer.Draw(); shader.Unbind(); }
/// <summary> /// Submit something to be drawn /// </summary> /// <param name="shader"></param> /// <param name="vertexArray"></param> /// <param name="transform"></param> public static void Submit(IShader shader, IVertexArray vertexArray, Matrix4x4 transform) { shader.Bind(); shader.SetMat4("u_ViewProjection", sceneData.ViewProjectionMatrix); shader.SetMat4("u_Transform", transform); vertexArray.Bind(); RenderingAPI.DrawIndexed(vertexArray); }
public void Submit(IShader shader, IVertexArray vertexArray) { shader.Bind(); shader.SetMat4("viewProjection", _viewProjection); vertexArray.Bind(); _renderContext.Draw(vertexArray); }
private static IShader applyObjectShader(IShader shader) { if (shader != null) { shader = shader.Compile(); } shader?.Bind(); return(shader); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); shader.Bind(); Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy; ColourInfo colourInfo = DrawColourInfo.Colour; colourInfo.ApplyChild(colour); if (audioData != null) { for (int j = 0; j < visualiser_rounds; j++) { for (int i = 0; i < bars_per_visualiser; i++) { if (audioData[i] < amplitude_dead_zone) { continue; } float rotation = MathHelper.DegreesToRadians(i / (float)bars_per_visualiser * 360 + j * 360 / visualiser_rounds); float rotationCos = (float)Math.Cos(rotation); float rotationSin = (float)Math.Sin(rotation); //taking the cos and sin to the 0..1 range var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * size; var barSize = new Vector2(size * (float)Math.Sqrt(2 * (1 - Math.Cos(MathHelper.DegreesToRadians(360f / bars_per_visualiser)))) / 2f, bar_length * audioData[i]); //The distance between the position and the sides of the bar. var bottomOffset = new Vector2(-rotationSin * barSize.X / 2, rotationCos * barSize.X / 2); //The distance between the bottom side of the bar and the top side. var amplitudeOffset = new Vector2(rotationCos * barSize.Y, rotationSin * barSize.Y); var rectangle = new Quad( Vector2Extensions.Transform(barPosition - bottomOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition - bottomOffset + amplitudeOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition + bottomOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix) ); DrawQuad( texture, rectangle, colourInfo, null, vertexBatch.AddAction, //barSize by itself will make it smooth more in the X axis than in the Y axis, this reverts that. Vector2.Divide(inflation, barSize.Yx)); } } } shader.Unbind(); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); _shader.Bind(); var inflation = DrawInfo.MatrixInverse.ExtractScale().Xy; var colourInfo = DrawColourInfo.Colour; colourInfo.ApplyChild(_colour); if (_audioData != null) { for (var j = 0; j < VisualiserRounds; j++) { for (var i = 0; i < BarsPerVisualiser; i++) { if (_audioData[i] < AmplitudeDeadZone) { continue; } var rotation = MathUtils.DegreesToRadians(i / (float)BarsPerVisualiser * 360 + j * 360 / VisualiserRounds); var rotationCos = MathF.Cos(rotation); var rotationSin = MathF.Sin(rotation); //taking the cos and sin to the 0..1 range var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * _size; var barSize = new Vector2(_size * MathF.Sqrt(2 * (1 - MathF.Cos(MathUtils.DegreesToRadians(360f / BarsPerVisualiser)))) / 2f, BarLength * _audioData[i]); //The distance between the position and the sides of the bar. var bottomOffset = new Vector2(-rotationSin * barSize.X / 2, rotationCos * barSize.X / 2); //The distance between the bottom side of the bar and the top side. var amplitudeOffset = new Vector2(rotationCos * barSize.Y, rotationSin * barSize.Y); var rectangle = new Quad( Vector2Extensions.Transform(barPosition - bottomOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition - bottomOffset + amplitudeOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition + bottomOffset, DrawInfo.Matrix), Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix) ); DrawQuad( _texture, rectangle, colourInfo, null, _vertexBatch.AddAction, //barSize by itself will make it smooth more in the X axis than in the Y axis, this reverts that. Vector2.Divide(inflation, barSize.Yx)); } } } _shader.Unbind(); }
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 = MaskingInfo.Value.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; edgeEffectMaskingInfo.HollowCornerRadius = MaskingInfo.Value.CornerRadius + EdgeEffect.Radius; 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(); }
public ExampleLayer() { //Create camera cameraController = new OrthographicCameraController(1280.0f / 720.0f); //Shader library shaderLibrary = new ShaderLibrary(); // ---------- //Square // ---------- squareVertexArray = IVertexArray.Create(); float[] squareVertices = { -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f }; IVertexBuffer squareVertexBuffer = IVertexBuffer.Create(squareVertices, squareVertices.GetBytes()); BufferLayout squareBufferLayout = new BufferLayout(new[] { new BufferElement("a_Position", ShaderDataType.Float3), new BufferElement("a_TexCoord", ShaderDataType.Float2) }); squareVertexBuffer.SetLayout(squareBufferLayout); squareVertexArray.AddVertexBuffer(squareVertexBuffer); uint[] squareIndices = { 0, 1, 2, 2, 3, 0 }; IIndexBuffer squareIndexBuffer = IIndexBuffer.Create(squareIndices, squareIndices.GetBytes() / sizeof(uint)); squareVertexArray.SetIndexBuffer(squareIndexBuffer); //Square shader shaderLibrary.LoadAndAddShader("Shaders/Square.glsl"); //Texture shader IShader textureShader = IShader.Create("Shaders/Texture.glsl"); shaderLibrary.AddShader(textureShader); birdiTexture = I2DTexture.Create("Textures/Birdi.png"); faceTexture = I2DTexture.Create("Textures/Face.png"); textureShader.Bind(); textureShader.SetInt("u_Texture", 0); }
private void removeObjectShader(IShader shader) { if (shader == null) { return; } if (_lastShaderUsed != null) { _lastShaderUsed.Bind(); } else { shader.Unbind(); } }
public void Draw(DrawState state) { //push the world matrix, multiplying by the current matrix if there is one state.PushWorldMatrixMultiply(ref worldMatrix); //cull test the custom geometry if (geometry.CullTest(state)) { //bind the shader shader.Bind(state); //draw the custom geometry geometry.Draw(state); } //always pop the matrix afterwards state.PopWorldMatrix(); }
private void Flush(int submissionCount = MaxSubmissions) { _vertexArray.VertexBuffer.AddData(_submissions.ToArray()); _submissions.Clear(); _objectShader.Bind(); _objectShader.SetMat4("viewProjection", _viewProjection); foreach (var(texture, slot) in _textures) { texture.Bind(slot); } _textures.Clear(); _vertexArray.Bind(true); _renderContext.Draw(_vertexArray, submissionCount * IndicesInSubmission); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); if (Texture?.Available != true) { return; } IShader shader = needsRoundedShader ? RoundedTextureShader : TextureShader; shader.Bind(); Texture.TextureGL.WrapMode = WrapTexture ? TextureWrapMode.Repeat : TextureWrapMode.ClampToEdge; Blit(vertexAction); shader.Unbind(); }
//draw the sphere (This is the method declared in the IDraw interface) public void Draw(DrawState state) { //the DrawState object controls current drawing state for the application. //The DrawState uses a number of stacks, it is important to understand how pushing/popping a stack works. //First, push the world matrix, multiplying by the current matrix (if there is one). //This is very similar to using openGL glPushMatrix() and then glMultMatrix(). //The DrawState object maintains the world matrix stack, pushing and popping this stack is very fast. state.PushWorldMatrixMultiply(ref this.worldMatrix); //The next line frustum cull tests the sphere //Culltest will return false if the test fails (in this case false would mean the sphere is off screen) //The CullTest method requirs an ICuller to be passed in. Here the state object is used because the //DrawState object implements the ICuller interface (DrawState's culler performs screen culling) //The cull test uses the current world matrix, so make sure you perform the CullTest after applying any //transformations. //The CullTest method is defined by the ICullable interface. Any IDraw object also implements ICullable. if (sphereGeometry.CullTest(state)) { //the sphere is on screen... //bind the shader. //Note that if the sphere was off screen, the shader would never be bound, //which would save valuable CPU time. (The sphere geometry class assumes a shader is bound) //This is why the CullTest() method is separate from the Draw() method. shader.Bind(state); //Once the call to Bind() has been made, the shaders will be active ('bound') //on the graphics card. There is no way to 'unbind' or 'end' the shader. //Once bound, that shader is in use - until the point a different shader is bound. //draw the sphere geometry sphereGeometry.Draw(state); } //always pop the world matrix afterwards state.PopWorldMatrix(); }
public override void Draw(Action <TexturedVertex2D> vertexAction) { base.Draw(vertexAction); if (Texture?.Available != true || Segments.Count == 0) { return; } GLWrapper.PushDepthInfo(DepthInfo.Default); IShader shader = needsRoundedShader ? RoundedTextureShader : TextureShader; shader.Bind(); Texture.TextureGL.WrapMode = TextureWrapMode.ClampToEdge; Texture.TextureGL.Bind(); updateVertexBuffer(); shader.Unbind(); GLWrapper.PopDepthInfo(); }
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(); } }
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) { base.Draw(vertexAction); if (texture?.Available != true || points == null || points.Count == 0) { return; } shader.Bind(); texture.TextureGL.Bind(); Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; // We're dealing with a _large_ number of points, so we need to optimise the quadToDraw * drawInfo.Matrix multiplications below // for points that are going to be masked out anyway. This allows for higher resolution graphs at larger scales with virtually no performance loss. // Since the points are generated in the local coordinate space, we need to convert the screen space masking quad coordinates into the local coordinate space RectangleF localMaskingRectangle = (Quad.FromRectangle(GLWrapper.CurrentMaskingInfo.ScreenSpaceAABB) * DrawInfo.MatrixInverse).AABBFloat; float separation = drawSize.X / (points.Count - 1); for (int i = 0; i < points.Count - 1; i++) { float leftX = i * separation; float rightX = (i + 1) * separation; if (rightX < localMaskingRectangle.Left) { continue; } if (leftX > localMaskingRectangle.Right) { break; // X is always increasing } Color4 frequencyColour = baseColour; // colouring is applied in the order of interest to a viewer. frequencyColour = Interpolation.ValueAt(points[i].MidIntensity / midMax, frequencyColour, midColour, 0, 1); // high end (cymbal) can help find beat, so give it priority over mids. frequencyColour = Interpolation.ValueAt(points[i].HighIntensity / highMax, frequencyColour, highColour, 0, 1); // low end (bass drum) is generally the best visual aid for beat matching, so give it priority over high/mid. frequencyColour = Interpolation.ValueAt(points[i].LowIntensity / lowMax, frequencyColour, lowColour, 0, 1); ColourInfo finalColour = DrawColourInfo.Colour; finalColour.ApplyChild(frequencyColour); Quad quadToDraw; switch (channels) { default: case 2: { float height = drawSize.Y / 2; quadToDraw = new Quad( new Vector2(leftX, height - points[i].Amplitude[0] * height), new Vector2(rightX, height - points[i + 1].Amplitude[0] * height), new Vector2(leftX, height + points[i].Amplitude[1] * height), new Vector2(rightX, height + points[i + 1].Amplitude[1] * height) ); break; } case 1: { quadToDraw = new Quad( new Vector2(leftX, drawSize.Y - points[i].Amplitude[0] * drawSize.Y), new Vector2(rightX, drawSize.Y - points[i + 1].Amplitude[0] * drawSize.Y), new Vector2(leftX, drawSize.Y), new Vector2(rightX, drawSize.Y) ); break; } } quadToDraw *= DrawInfo.Matrix; DrawQuad(texture, quadToDraw, finalColour, null, vertexBatch.AddAction, Vector2.Divide(localInflationAmount, quadToDraw.Size)); } shader.Unbind(); }