Example #1
0
        private void DrawGrid(CartesianGraphState <T> state)
        {
            GL.UseProgram(_gridShader.Handle);
            GL.Uniform4(_gridShader.Uniforms["Color"].Location, Color4.Gray);
            GL.Uniform1(_gridShader.Uniforms["majorXGridSpacing"].Location, state.XGridSpacing.Major);
            GL.Uniform1(_gridShader.Uniforms["minorXGridSpacing"].Location, state.XGridSpacing.Minor);

            GL.Uniform1(_gridShader.Uniforms["majorYGridSpacing"].Location, state.YGridSpacing.Major);
            GL.Uniform1(_gridShader.Uniforms["minorYGridSpacing"].Location, state.YGridSpacing.Minor);

            GL.Uniform1(_gridShader.Uniforms["majorXAlpha"].Location, _cfg.XAxis.MajorVisibile ? 1.0f : 0.0f);
            GL.Uniform1(_gridShader.Uniforms["minorXAlpha"].Location, _cfg.XAxis.MinorVisible ? 1.0f : 0.0f);
            GL.Uniform1(_gridShader.Uniforms["majorYAlpha"].Location, _cfg.YAxis.MajorVisibile ? 1.0f : 0.0f);
            GL.Uniform1(_gridShader.Uniforms["minorYAlpha"].Location, _cfg.YAxis.MinorVisible ? 1.0f : 0.0f);

            GL.Uniform1(_gridShader.Uniforms["originXAlpha"].Location, _cfg.XAxis.OriginVisible ? 1.0f : 0.0f);
            GL.Uniform1(_gridShader.Uniforms["originYAlpha"].Location, _cfg.XAxis.OriginVisible ? 1.0f : 0.0f);

            var vpMat = state.Camera.Current.ViewProjection;

            vpMat = Matrix4.CreateScale(1.0f, state.YScale, 1.0f) * vpMat;
            vpMat.Invert();
            GL.UniformMatrix4(_gridShader.Uniforms["InvViewProjectionMatrix"].Location, false, ref vpMat);
            // GL.Uniform2(_solidShader.Uniforms["Scale"].Location, Vector2.One);
            GL.BindVertexArray(Primitives.Quad.Handle);
            GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            GL.BindVertexArray(0);
            GL.UseProgram(0);
        }
Example #2
0
        private void DrawLineSeries(CartesianGraphState <T> state)
        {
            GL.UseProgram(_solidShader.Handle);
            var vpMat = state.Camera.Current.ViewProjection;

            vpMat = Matrix4.CreateScale(1.0f, state.YScale, 1.0f) * vpMat;
            GL.UniformMatrix4(_solidShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);
            GL.Uniform2(_solidShader.Uniforms["Scale"].Location, Vector2.One);
            GL.Uniform2(_solidShader.Uniforms["Position"].Location, Vector2.Zero);

            for (var i = 0; i < state.Series.Count; i++)
            {
                var series = state.Series[i];
                if (series.SeriesType != SeriesType.Line || !series.IsVisible)
                {
                    continue;
                }

                var vao = _seriesVaos[i];

                GL.Uniform4(_solidShader.Uniforms["Color"].Location, series.Color);

                GL.BindVertexArray(vao.Handle);
                var primitiveType = series.SeriesType == SeriesType.Point ? PrimitiveType.Points : PrimitiveType.LineStrip;

                GL.DrawArrays(primitiveType, 0, series.Points.Count);
                GL.BindVertexArray(0);
            }
            GL.UseProgram(0);
        }
Example #3
0
        private void OnReady()
        {
            var graphSettings = CartesianGraphSettings.Default;

            Graph            = new CartesianGraph <T>(graphSettings);
            _state           = Graph.State;
            _control.Render += OnRender;
        }
Example #4
0
        internal void Render(CartesianGraphState <T> state)
        {
            if (!_hasSetupGraphics)
            {
                _hasSetupGraphics = true;
                SetupGraphics();
            }

            UpdateVaos(state);
            DrawRegions(state);
            DrawGrid(state);
            DrawLineSeries(state);
            DrawPointSeries(state);
            DrawDragBox(state);
            DrawAxisLabels(state);
            DrawTooltip(state);
        }
Example #5
0
        private void DrawRegions(CartesianGraphState <T> state)
        {
            GL.BindVertexArray(Primitives.Quad.Handle);
            GL.UseProgram(_solidShader.Handle);
            var vpMat = state.Camera.Current.ViewProjection;

            GL.UniformMatrix4(_solidShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);
            foreach (var sec in state.Regions)
            {
                var box = sec.Bounds;
                var col = sec.Color;

                GL.Uniform2(_solidShader.Uniforms["Position"].Location, box.Center);
                GL.Uniform2(_solidShader.Uniforms["Scale"].Location, box.HalfSize);
                GL.Uniform4(_solidShader.Uniforms["Color"].Location, col);

                GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            }
            GL.BindVertexArray(0);
            GL.UseProgram(0);
        }
Example #6
0
        private void DrawDragBox(CartesianGraphState <T> state)
        {
            var box = state.DragRectangle;

            if (box == default)
            {
                return;
            }
            var col = new Color4(1, 1, 1, 0.15f);
            // rescale into view co-ordinates
            var pt1 = box.Min * 2.0f - Vector2.One;
            var pt2 = box.Max * 2.0f - Vector2.One;
            // project mouse into world
            var inverseVp = state.Camera.Current.ViewProjection.Inverted();

            var minpt = (new Vector4(pt1.X, -pt2.Y, 0, 1) * inverseVp).Xy;
            var maxPt = (new Vector4(pt2.X, -pt1.Y, 0, 1) * inverseVp).Xy;


            var center = Vector2.Lerp(minpt, maxPt, 0.5f);
            var scale  = maxPt - minpt;

            // render the background box
            GL.BindVertexArray(Primitives.Quad.Handle);
            GL.UseProgram(_solidShader.Handle);

            var vpMat = state.Camera.Current.ViewProjection;

            GL.UniformMatrix4(_solidShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);

            GL.Uniform2(_solidShader.Uniforms["Position"].Location, center);
            GL.Uniform2(_solidShader.Uniforms["Scale"].Location, scale * 0.5f);

            GL.Uniform4(_solidShader.Uniforms["Color"].Location, col);

            GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);

            GL.BindVertexArray(0);
            GL.UseProgram(0);
        }
Example #7
0
        private void DrawPointSeries(CartesianGraphState <T> state)
        {
            GL.UseProgram(_pointShader.Handle);
            var vpMat = state.Camera.Current.ViewProjection;

            vpMat = Matrix4.CreateScale(1.0f, state.YScale, 1.0f) * vpMat;
            GL.UniformMatrix4(_pointShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);
            GL.Uniform2(_pointShader.Uniforms["Scale"].Location, Vector2.One);
            GL.Uniform2(_pointShader.Uniforms["Position"].Location, Vector2.Zero);
            GL.Uniform1(_pointShader.Uniforms["Aspect"].Location, state.Camera.Current.AspectRatio);

            for (var i = 0; i < state.Series.Count; i++)
            {
                var series = state.Series[i];
                if (series.SeriesType != SeriesType.Point || !series.IsVisible)
                {
                    continue;
                }

                var vao = _seriesVaos[i];

                if (series.SeriesType == SeriesType.Point)
                {
                    var tex = ShapeHelper.TextureFor(series.PointShape);
                    GL.ActiveTexture(TextureUnit.Texture0);
                    GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
                    GL.Uniform1(_pointShader.Uniforms["tex"].Location, 0);
                }

                GL.Uniform1(_pointShader.Uniforms["PointSize"].Location, 2 * _cfg.PointSize / state.ViewportHeight);
                GL.Uniform4(_pointShader.Uniforms["Color"].Location, series.Color);

                GL.BindVertexArray(vao.Handle);
                var primitiveType = series.SeriesType == SeriesType.Point ? PrimitiveType.Triangles : PrimitiveType.LineStrip;

                GL.DrawArrays(primitiveType, 0, series.Points.Count * _stride);
                GL.BindVertexArray(0);
            }
            GL.UseProgram(0);
        }
Example #8
0
        private void UpdateVaos(CartesianGraphState <T> state)
        {
            for (var i = 0; i < state.Series.Count; i++)
            {
                var series = state.Series[i];
                if (series.SeriesType == SeriesType.Point)
                {
                    if (i >= _seriesVaos.Count)
                    {
                        var newVao = CreatePointSeriesVao(series);
                        _seriesVaos.Add(newVao);
                    }

                    var vao = _seriesVaos[i];
                    if (series.InvalidateRenderCache || series.Points.Count * _stride > vao.ElementCount)
                    {
                        // append the latest data:
                        UpdatePointSeriesVao(vao, series);
                    }
                }
                else
                {
                    if (i >= _seriesVaos.Count)
                    {
                        var newVao = CreateLineSeriesVao(series);
                        _seriesVaos.Add(newVao);
                    }

                    var vao = _seriesVaos[i];
                    if (series.InvalidateRenderCache || series.Points.Count > vao.ElementCount)
                    {
                        // append the latest data:
                        UpdateLineSeriesVao(vao, series);
                    }
                }
            }
        }
Example #9
0
        private void DrawTooltip(CartesianGraphState <T> state)
        {
            if (!state.MouseoverTarget.HasValue)
            {
                return;
            }
            var targetPt = state.MouseoverTarget.Value;

            // rescale into view co-ordinates
            var(x, y) = state.MousePosition * 2.0f - Vector2.One;
            // project mouse into world
            var inverseVp = state.Camera.Current.ViewProjection.Inverted();

            var worldPos = (new Vector4(x, -y, 0, 1) * inverseVp).Xy;

            // screenPos.X *= Camera.Current.AspectRatio;

            GL.BindVertexArray(Primitives.Quad.Handle);
            var tooltip  = $"{targetPt.X:0.000}, {targetPt.Y:0.000}";
            var tex      = TextRendering.GetTextTexture(tooltip);
            var tooltip2 = $"{targetPt.Series.Name}";// - {targetPt.Value}";
            var tex2     = TextRendering.GetTextTexture(tooltip2);

            var scale = 0.1f * new Vector2(tex.AspectRatio, 1.0f) * state.Camera.Current.VerticalSize * 0.15f;
            var pos   = worldPos + new Vector2(scale.X + scale.Y, -scale.Y * 2);

            GL.UseProgram(_solidShader.Handle);

            var vpMat = state.Camera.Current.ViewProjection;

            GL.UniformMatrix4(_solidShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);

            // render the background box
            var bgCol = new Color4(0.25f, 0.25f, 0.25f, 0.5f);

            GL.Uniform4(_solidShader.Uniforms["Color"].Location, bgCol);

            var scaleBg = 0.1f * new Vector2(MathF.Max(tex.AspectRatio, tex2.AspectRatio), 1.0f) * state.Camera.Current.VerticalSize * 0.15f;
            var bgPos   = new Vector2(pos.X, pos.Y - scaleBg.Y);

            GL.Uniform2(_solidShader.Uniforms["Position"].Location, bgPos);
            scaleBg.Y *= 2;
            GL.Uniform2(_solidShader.Uniforms["Scale"].Location, scaleBg);
            GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);

            GL.UseProgram(0);

            GL.UseProgram(_textShader.Handle);

            var col = Color4.White;

            GL.Uniform4(_textShader.Uniforms["Color"].Location, col);

            GL.UniformMatrix4(_textShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);


            GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
            GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);
            GL.Uniform2(_solidShader.Uniforms["Scale"].Location, scale);
            GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);

            GL.BindTexture(TextureTarget.Texture2D, tex2.Handle);
            GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);

            var scale2 = 0.1f * new Vector2(tex2.AspectRatio, 1.0f) * state.Camera.Current.VerticalSize * 0.15f;

            GL.Uniform2(_solidShader.Uniforms["Scale"].Location, scale2);

            var pos2 = pos + new Vector2(0, -scale.Y * 2f);

            GL.Uniform2(_textShader.Uniforms["Position"].Location, pos2);


            var series = targetPt.Series;
            var index  = state.Series.IndexOf(series);

            GL.Uniform4(_textShader.Uniforms["Color"].Location, series.Color);

            GL.DrawElements(PrimitiveType.TriangleStrip, Primitives.Quad.ElementCount, DrawElementsType.UnsignedInt, 0);

            GL.BindVertexArray(0);
            GL.UseProgram(0);
        }
Example #10
0
        private void DrawAxisLabels(CartesianGraphState <T> state)
        {
            GL.UseProgram(_textShader.Handle);

            // vp matrix
            var yScale = state.YScale;
            var vpMat  = state.Camera.Current.ViewProjection;

            // vpMat = Matrix4.CreateScale(1.0f, yScale, 1.0f) * vpMat;
            GL.UniformMatrix4(_textShader.Uniforms["ViewProjectionMatrix"].Location, false, ref vpMat);
            // Color
            var col = Color4.White;

            GL.Uniform4(_textShader.Uniforms["Color"].Location, col);
            // bind
            var quad = Primitives.Quad;

            GL.BindVertexArray(quad.Handle);

            var size  = _cfg.TextScale * 0.025f * state.Camera.Current.VerticalSize;
            var scale = Vector2.One * size;

            var leftPos   = -(state.Camera.Current.HorizontalSize * 0.5f - size) - state.Camera.Current.Position.X;
            var bottomPos = -(state.Camera.Current.VerticalSize * 0.5f - size) - state.Camera.Current.Position.Y;

            var minorSpacingY = state.YGridSpacing.Minor;

            for (int i = 0; i < 100; i++)
            {
                var yPos  = i * minorSpacingY;
                var pos   = new Vector2(leftPos, yPos * yScale);
                var label = yPos.ToString("0.###");

                var tex = TextRendering.GetTextTexture(label, StringAlignment.Near);
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
                GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);

                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);


                var finalScale = new Vector2(scale.X * tex.AspectRatio, scale.Y);
                GL.Uniform2(_textShader.Uniforms["Scale"].Location, finalScale);

                GL.DrawElements(PrimitiveType.TriangleStrip, quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            }


            for (int i = 1; i < 100; i++)
            {
                var yPos  = -i * minorSpacingY;
                var pos   = new Vector2(leftPos, yPos * yScale);
                var label = yPos.ToString("0.###");
                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);
                var tex = TextRendering.GetTextTexture(label, StringAlignment.Near);
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
                GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);

                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);

                var finalScale = new Vector2(scale.X * tex.AspectRatio, scale.Y);
                GL.Uniform2(_textShader.Uniforms["Scale"].Location, finalScale);

                GL.DrawElements(PrimitiveType.TriangleStrip, quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            }


            var minorSpacingX = state.XGridSpacing.Minor;

            for (int i = 0; i < 100; i++)
            {
                var xPos  = i * minorSpacingX;
                var pos   = new Vector2(xPos, bottomPos);
                var label = xPos.ToString("0.###");
                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);
                var tex = TextRendering.GetTextTexture(label, StringAlignment.Near);
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
                GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);

                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);


                var finalScale = new Vector2(scale.X * tex.AspectRatio, scale.Y);
                GL.Uniform2(_textShader.Uniforms["Scale"].Location, finalScale);

                GL.DrawElements(PrimitiveType.TriangleStrip, quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            }

            for (int i = 1; i < 100; i++)
            {
                var xPos  = -i * minorSpacingX;
                var pos   = new Vector2(xPos, bottomPos);
                var label = xPos.ToString("0.###");
                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);
                var tex = TextRendering.GetTextTexture(label, StringAlignment.Near);
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, tex.Handle);
                GL.Uniform1(_textShader.Uniforms["tex"].Location, 0);

                GL.Uniform2(_textShader.Uniforms["Position"].Location, pos);

                var finalScale = new Vector2(scale.X * tex.AspectRatio, scale.Y);
                GL.Uniform2(_textShader.Uniforms["Scale"].Location, finalScale);

                GL.DrawElements(PrimitiveType.TriangleStrip, quad.ElementCount, DrawElementsType.UnsignedInt, 0);
            }

            GL.BindVertexArray(0);
            GL.UseProgram(0);
        }