Example #1
0
        public Renderer(RenderSurface surface)
        {
            Surface = surface;
            ContentArchive content;

            using (var stream = GetType().Assembly.GetManifestResourceStream("DemoRenderer.DemoRenderer.contentarchive"))
            {
                content = ContentArchive.Load(stream);
            }
            Shapes           = new ShapesExtractor(looper, pool);
            SphereRenderer   = new RayTracedRenderer <SphereInstance>(content, @"ShapeDrawing\RenderSpheres");
            CapsuleRenderer  = new RayTracedRenderer <CapsuleInstance>(content, @"ShapeDrawing\RenderCapsules");
            CylinderRenderer = new RayTracedRenderer <CylinderInstance>(content, @"ShapeDrawing\RenderCylinders");
            BoxRenderer      = new BoxRenderer(content);
            TriangleRenderer = new TriangleRenderer(content);
            MeshRenderer     = new MeshRenderer(Shapes.MeshCache, content);
            Lines            = new LineExtractor(pool, looper);
            LineRenderer     = new LineRenderer(content);
            Background       = new BackgroundRenderer(content);
            CompressToSwap   = new CompressToSwap(content);

            ImageRenderer  = new ImageRenderer(content);
            ImageBatcher   = new ImageBatcher(pool);
            GlyphRenderer  = new GlyphRenderer(content);
            TextBatcher    = new TextBatcher();
            UILineRenderer = new UILineRenderer(content);
            UILineBatcher  = new UILineBatcher();

            OnResize();
        }
Example #2
0
        public void Draw(TextBuilder text, TextBatcher textBatcher, DemoSet demoSet, Vector2 position, float textHeight, Vector3 textColor, Font font)
        {
            if (TrackingInput)
            {
                text.Clear().Append("Swap demo to: ");
                if (TargetDemoIndex >= 0)
                {
                    text.Append(TargetDemoIndex);
                }
                else
                {
                    text.Append("_");
                }
                textBatcher.Write(text, position, textHeight, textColor, font);

                var lineSpacing = textHeight * 1.1f;
                position.Y += textHeight * 0.5f;
                textHeight *= 0.8f;
                for (int i = 0; i < demoSet.Count; ++i)
                {
                    position.Y += lineSpacing;
                    text.Clear().Append(demoSet.GetName(i));
                    textBatcher.Write(text.Clear().Append(i).Append(": ").Append(demoSet.GetName(i)), position, textHeight, textColor, font);
                }
            }
        }
Example #3
0
        public void Render(Camera camera)
        {
            if (Surface.Resolution.X != depthBuffer.Description.Width || Surface.Resolution.Y != depthBuffer.Description.Height)
            {
                OnResize();
            }
            var context = Surface.Context;

            Shapes.MeshCache.FlushPendingUploads(context);

            context.Rasterizer.SetViewport(0, 0, Surface.Resolution.X, Surface.Resolution.Y, 0.0f, 1.0f);

            //Note reversed depth.
            context.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth, 0, 0);
            context.ClearRenderTargetView(rtv, new SharpDX.Mathematics.Interop.RawColor4());
            context.OutputMerger.SetRenderTargets(dsv, rtv);
            context.Rasterizer.State = rasterizerState;
            context.OutputMerger.SetDepthStencilState(opaqueDepthState);

            //All ray traced shapes use analytic coverage writes to get antialiasing.
            context.OutputMerger.SetBlendState(a2cBlendState);
            SphereRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.spheres.Span), 0, Shapes.spheres.Count);
            CapsuleRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.capsules.Span), 0, Shapes.capsules.Count);
            CylinderRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.cylinders.Span), 0, Shapes.cylinders.Count);

            //Non-raytraced shapes just use regular opaque rendering.
            context.OutputMerger.SetBlendState(opaqueBlendState);
            BoxRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.boxes.Span), 0, Shapes.boxes.Count);
            TriangleRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.triangles.Span), 0, Shapes.triangles.Count);
            MeshRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.meshes.Span), 0, Shapes.meshes.Count);
            LineRenderer.Render(context, camera, Surface.Resolution, SpanConverter.AsSpan(Lines.lines.Span), 0, Lines.lines.Count);

            Background.Render(context, camera);

            //Resolve MSAA rendering down to a single sample buffer for screenspace work.
            //Note that we're not bothering to properly handle tonemapping during the resolve. That's going to hurt quality a little, but the demos don't make use of very wide ranges.
            //(If for some reason you end up expanding the demos to make use of wider HDR, you can make this a custom resolve pretty easily.)
            context.ResolveSubresource(colorBuffer, 0, resolvedColorBuffer, 0, Format.R16G16B16A16_Float);
            context.OutputMerger.SetRenderTargets(resolvedRTV);

            //Glyph and screenspace line drawing rely on the same premultiplied alpha blending transparency. We'll handle their state out here.
            context.OutputMerger.SetBlendState(uiBlendState);
            context.OutputMerger.SetDepthStencilState(uiDepthState);
            ImageRenderer.PreparePipeline(context);
            ImageBatcher.Flush(context, Surface.Resolution, ImageRenderer);
            UILineBatcher.Flush(context, Surface.Resolution, UILineRenderer);
            GlyphRenderer.PreparePipeline(context);
            TextBatcher.Flush(context, Surface.Resolution, GlyphRenderer);

            //Note that, for now, the compress to swap handles its own depth state since it's the only post processing stage.
            context.OutputMerger.SetBlendState(opaqueBlendState);
            context.Rasterizer.State = rasterizerState;
            CompressToSwap.Render(context, resolvedSRV, Surface.RTV);
        }
Example #4
0
        public void Render(Camera camera)
        {
            if (Surface.Resolution.X != width || Surface.Resolution.Y != height)
            {
                OnResize();
            }
            Shapes.MeshCache.FlushPendingUploads();

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer);
            //Note reversed depth.
            GL.ClearDepth(0.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Enable(EnableCap.CullFace);
            GL.Enable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Greater);

            //All ray traced shapes use analytic coverage writes to get antialiasing.
            GL.Enable(EnableCap.SampleAlphaToCoverage);
            SphereRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.spheres.Span), 0, Shapes.spheres.Count);
            CapsuleRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.capsules.Span), 0, Shapes.capsules.Count);
            CylinderRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.cylinders.Span), 0, Shapes.cylinders.Count);

            //Non-raytraced shapes just use regular opaque rendering.
            GL.Disable(EnableCap.SampleAlphaToCoverage);
            BoxRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.boxes.Span), 0, Shapes.boxes.Count);
            TriangleRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.triangles.Span), 0, Shapes.triangles.Count);
            MeshRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Shapes.meshes.Span), 0, Shapes.meshes.Count);
            LineRenderer.Render(camera, Surface.Resolution, SpanConverter.AsSpan(Lines.lines.Span), 0, Lines.lines.Count);

            Background.Render(camera);
            GL.Disable(EnableCap.CullFace);
            GL.Disable(EnableCap.DepthTest);

            //Resolve MSAA rendering down to a single sample buffer for screenspace work.
            //Note that we're not bothering to properly handle tonemapping during the resolve. That's going to hurt quality a little, but the demos don't make use of very wide ranges.
            //(If for some reason you end up expanding the demos to make use of wider HDR, you can make this a custom resolve pretty easily.)
            GL.BlitNamedFramebuffer(framebuffer, resolvedFramebuffer, 0, 0, width, height, 0, 0, width, height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, resolvedFramebuffer);

            //Glyph and screenspace line drawing rely on the same premultiplied alpha blending transparency. We'll handle their state out here.
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
            GL.BlendEquation(BlendEquationMode.FuncAdd);
            ImageRenderer.PreparePipeline();
            ImageBatcher.Flush(Surface.Resolution, ImageRenderer);
            UILineBatcher.Flush(Surface.Resolution, UILineRenderer);
            GlyphRenderer.PreparePipeline();
            TextBatcher.Flush(Surface.Resolution, GlyphRenderer);
            GL.Disable(EnableCap.Blend);

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            CompressToSwap.Render(resolvedColorBuffer);
        }
Example #5
0
        public void Render(Camera camera)
        {
            if (Surface.Resolution.X != depthBuffer.Description.Width || Surface.Resolution.Y != depthBuffer.Description.Height)
            {
                OnResize();
            }
            var context = Surface.Context;

            context.Rasterizer.SetViewport(0, 0, Surface.Resolution.X, Surface.Resolution.Y, 0.0f, 1.0f);

            //Note reversed depth.
            context.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth, 0, 0);
            //The background render is going to fill out the entire color buffer, but having a clear can be useful- e.g. clearing out MSAA history.
            //We don't use MSAA right now, but the cost of doing this clear is negligible and it avoids a surprise later.
            context.ClearRenderTargetView(rtv, new SharpDX.Mathematics.Interop.RawColor4());
            context.OutputMerger.SetRenderTargets(dsv, rtv);
            context.Rasterizer.State = rasterizerState;
            context.OutputMerger.SetBlendState(opaqueBlendState);
            context.OutputMerger.SetDepthStencilState(opaqueDepthState);

            SphereRenderer.Render(context, camera, Surface.Resolution, Shapes.spheres.Span.Memory, 0, Shapes.spheres.Count);
            CapsuleRenderer.Render(context, camera, Surface.Resolution, Shapes.capsules.Span.Memory, 0, Shapes.capsules.Count);
            BoxRenderer.Render(context, camera, Surface.Resolution, Shapes.boxes.Span.Memory, 0, Shapes.boxes.Count);
            LineRenderer.Render(context, camera, Surface.Resolution, Lines.lines.Span.Memory, 0, Lines.lines.Count);

            Background.Render(context, camera);

            //Glyph and screenspace line drawing rely on the same premultiplied alpha blending transparency. We'll handle their state out here.
            context.OutputMerger.SetBlendState(uiBlendState);
            context.OutputMerger.SetDepthStencilState(uiDepthState);
            UILineBatcher.Flush(context, Surface.Resolution, UILineRenderer);
            GlyphRenderer.PreparePipeline(context);
            TextBatcher.Flush(context, Surface.Resolution, GlyphRenderer);

            //Note that, for now, the compress to swap handles its own depth state since it's the only post processing stage.
            context.OutputMerger.SetBlendState(opaqueBlendState);
            context.Rasterizer.State = rasterizerState;
            CompressToSwap.Render(context, srv, Surface.RTV);
        }
Example #6
0
        public Renderer(RenderSurface surface)
        {
            looper  = new ParallelLooper();
            Surface = surface;
            using (var stream = GetType().Assembly.GetManifestResourceStream("DemoRenderer.DemoRenderer.shaderarchive"))
            {
                ShaderCache = ShaderCache.Load(stream);
            }
            pool             = new BufferPool();
            Shapes           = new ShapesExtractor(Surface.Device, looper, pool);
            SphereRenderer   = new RayTracedRenderer <SphereInstance>(surface.Device, ShaderCache, @"ShapeDrawing\RenderSpheres.hlsl");
            CapsuleRenderer  = new RayTracedRenderer <CapsuleInstance>(surface.Device, ShaderCache, @"ShapeDrawing\RenderCapsules.hlsl");
            BoxRenderer      = new BoxRenderer(surface.Device, ShaderCache);
            TriangleRenderer = new TriangleRenderer(surface.Device, ShaderCache);
            MeshRenderer     = new MeshRenderer(surface.Device, Shapes.MeshCache, ShaderCache);
            Lines            = new LineExtractor(pool, looper);
            LineRenderer     = new LineRenderer(surface.Device, ShaderCache);
            Background       = new BackgroundRenderer(surface.Device, ShaderCache);
            CompressToSwap   = new CompressToSwap(surface.Device, ShaderCache);

            GlyphRenderer  = new GlyphRenderer(surface.Device, surface.Context, ShaderCache);
            TextBatcher    = new TextBatcher();
            UILineRenderer = new UILineRenderer(surface.Device, ShaderCache);
            UILineBatcher  = new UILineBatcher();

            OnResize();
            var rasterizerStateDescription = RasterizerStateDescription.Default();

            rasterizerStateDescription.IsFrontCounterClockwise = true;
            rasterizerStateDescription.CullMode = CullMode.Back;
            rasterizerState           = new RasterizerState(Surface.Device, rasterizerStateDescription);
            rasterizerState.DebugName = "Default Rasterizer State";

            var opaqueDepthStencilDescription = new DepthStencilStateDescription
            {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                //Note depth reversal.
                DepthComparison  = Comparison.Greater,
                IsStencilEnabled = false
            };

            opaqueDepthState           = new DepthStencilState(Surface.Device, opaqueDepthStencilDescription);
            opaqueDepthState.DebugName = "Opaque Depth State";

            var opaqueBlendStateDescription = BlendStateDescription.Default();

            opaqueBlendState           = new BlendState(Surface.Device, opaqueBlendStateDescription);
            opaqueBlendState.DebugName = "Opaque Blend State";

            var a2cBlendStateDescription = BlendStateDescription.Default();

            a2cBlendStateDescription.AlphaToCoverageEnable = true;
            a2cBlendState           = new BlendState(Surface.Device, a2cBlendStateDescription);
            a2cBlendState.DebugName = "A2C Blend State";

            var uiDepthStateDescription = new DepthStencilStateDescription
            {
                IsDepthEnabled = false,
                DepthWriteMask = DepthWriteMask.Zero,
                //Note depth reversal.
                DepthComparison  = Comparison.Greater,
                IsStencilEnabled = false
            };

            uiDepthState           = new DepthStencilState(Surface.Device, uiDepthStateDescription);
            uiDepthState.DebugName = "UI Depth State";

            //The UI will use premultiplied alpha.
            var uiBlendStateDescription = BlendStateDescription.Default();

            uiBlendStateDescription.RenderTarget[0].IsBlendEnabled        = true;
            uiBlendStateDescription.RenderTarget[0].SourceBlend           = BlendOption.One;
            uiBlendStateDescription.RenderTarget[0].SourceAlphaBlend      = BlendOption.One;
            uiBlendStateDescription.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
            uiBlendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.InverseSourceAlpha;
            uiBlendStateDescription.RenderTarget[0].BlendOperation        = BlendOperation.Add;
            uiBlendStateDescription.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
            uiBlendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            uiBlendState           = new BlendState(Surface.Device, uiBlendStateDescription);
            uiBlendState.DebugName = "UI Blend State";
        }
Example #7
0
        public void Draw(TextBuilder characters, UILineBatcher lines, TextBatcher text)
        {
            //Collect information to define data window ranges.
            int minX = int.MaxValue;
            int maxX = int.MinValue;
            var minY = double.MaxValue;
            var maxY = double.MinValue;

            for (int i = 0; i < graphSeries.Count; ++i)
            {
                var data = graphSeries[i].Data;
                if (minX > data.Start)
                {
                    minX = data.Start;
                }
                if (maxX < data.End)
                {
                    maxX = data.End;
                }
                for (int j = data.Start; j < data.End; ++j)
                {
                    var value = data[j];
                    if (minY > value)
                    {
                        minY = value;
                    }
                    if (maxY < value)
                    {
                        maxY = value;
                    }
                }
            }
            //If no data series contain values, then just use a default size.
            if (minY == float.MinValue)
            {
                minY = 0;
                maxY = 1;
            }
            //You could make use of this earlier to avoid comparisons but it doesn't really matter!
            if (description.ForceVerticalAxisMinimumToZero)
            {
                minY = 0;
                if (maxY < 0)
                {
                    maxY = 1;
                }
            }

            //Calculate the data span that takes into account rounding. We want intervals to be evenly spaced, but also to match nicely rounded numbers.
            //That means the span must be equal to some rounded number multiplied by the number of intervals.
            var yDataSpan         = maxY - minY;
            var yIntervalCount    = description.TargetVerticalTickCount + 1;
            var rawIntervalLength = yDataSpan / yIntervalCount;
            var roundingOffset    = 0.5 * Math.Pow(0.1, description.VerticalIntervalLabelRounding);

            yDataSpan = Math.Round(rawIntervalLength * description.VerticalIntervalValueScale + roundingOffset, description.VerticalIntervalLabelRounding) *
                        (yIntervalCount / description.VerticalIntervalValueScale);

            //Draw the graph body axes.
            var lowerLeft  = description.BodyMinimum + new Vector2(0, description.BodySpan.Y);
            var upperRight = description.BodyMinimum + new Vector2(description.BodySpan.X, 0);
            var lowerRight = description.BodyMinimum + description.BodySpan;

            lines.Draw(description.BodyMinimum, lowerLeft, description.AxisLineRadius, description.BodyLineColor);
            lines.Draw(lowerLeft, lowerRight, description.AxisLineRadius, description.BodyLineColor);

            //Draw axis labels.
            characters.Clear().Append(description.HorizontalAxisLabel);
            var baseAxisLabelDistance       = description.IntervalTickLength + description.IntervalTextHeight * description.LineSpacingMultiplier;
            var verticalAxisLabelDistance   = baseAxisLabelDistance + 2 * description.VerticalTickTextPadding;
            var horizontalAxisLabelDistance = baseAxisLabelDistance + 2 * description.HorizontalTickTextPadding + description.AxisLabelHeight * description.LineSpacingMultiplier;

            text.Write(characters,
                       lowerLeft +
                       new Vector2((description.BodySpan.X - GlyphBatch.MeasureLength(characters, description.Font, description.AxisLabelHeight)) * 0.5f, horizontalAxisLabelDistance),
                       description.AxisLabelHeight, description.TextColor, description.Font);
            characters.Clear().Append(description.VerticalAxisLabel);
            text.Write(characters,
                       description.BodyMinimum +
                       new Vector2(-verticalAxisLabelDistance, (description.BodySpan.Y + GlyphBatch.MeasureLength(characters, description.Font, description.AxisLabelHeight)) * 0.5f),
                       description.AxisLabelHeight, new Vector2(0, -1), description.TextColor, description.Font);

            //Position tickmarks, tick labels, and background lines along the axes.
            {
                var   xDataIntervalSize = (maxX - minX) / (description.TargetHorizontalTickCount + 1f);
                var   previousTickValue = int.MinValue;
                float valueToPixels     = description.BodySpan.X / (maxX - minX);
                for (int i = 0; i < description.TargetHorizontalTickCount + 2; ++i)
                {
                    //Round pen offset such that the data tick lands on an integer.
                    var valueAtTick = i * xDataIntervalSize;
                    var tickValue   = (int)Math.Round(valueAtTick);
                    if (tickValue == previousTickValue)
                    {
                        //Don't bother creating redundant ticks.
                        continue;
                    }
                    previousTickValue = tickValue;

                    var penPosition   = lowerLeft + new Vector2(tickValue * valueToPixels, 0);
                    var tickEnd       = penPosition + new Vector2(0, description.IntervalTickLength);
                    var backgroundEnd = penPosition - new Vector2(0, description.BodySpan.Y);
                    lines.Draw(penPosition, tickEnd, description.IntervalTickRadius, description.BodyLineColor);
                    lines.Draw(penPosition, backgroundEnd, description.BackgroundLineRadius, description.BodyLineColor);
                    characters.Clear().Append(tickValue);
                    text.Write(characters, tickEnd +
                               new Vector2(GlyphBatch.MeasureLength(characters, description.Font, description.IntervalTextHeight) * -0.5f,
                                           description.HorizontalTickTextPadding + description.IntervalTextHeight * description.LineSpacingMultiplier),
                               description.IntervalTextHeight, description.TextColor, description.Font);
                }
            }
            {
                var yDataIntervalSize = yDataSpan / (description.TargetVerticalTickCount + 1f);
                var previousTickValue = double.MinValue;
                //Note the inclusion of the scale. Rounding occurs post-scale; moving back to pixels requires undoing the scale.
                var valueToPixels = description.BodySpan.Y / (yDataSpan * description.VerticalIntervalValueScale);
                for (int i = 0; i < description.TargetVerticalTickCount + 2; ++i)
                {
                    var tickValue = Math.Round((minY + yDataIntervalSize * i) * description.VerticalIntervalValueScale, description.VerticalIntervalLabelRounding);
                    if (tickValue == previousTickValue)
                    {
                        //Don't bother creating redundant ticks.
                        continue;
                    }
                    previousTickValue = tickValue;

                    var penPosition = lowerLeft - new Vector2(0, (float)(tickValue * valueToPixels));

                    var tickEnd       = penPosition - new Vector2(description.IntervalTickLength, 0);
                    var backgroundEnd = penPosition + new Vector2(description.BodySpan.X, 0);
                    lines.Draw(penPosition, tickEnd, description.IntervalTickRadius, description.BodyLineColor);
                    lines.Draw(penPosition, backgroundEnd, description.BackgroundLineRadius, description.BodyLineColor);
                    characters.Clear().Append(tickValue, description.VerticalIntervalLabelRounding);
                    text.Write(characters,
                               tickEnd + new Vector2(-description.VerticalTickTextPadding, 0.5f * GlyphBatch.MeasureLength(characters, description.Font, description.IntervalTextHeight)),
                               description.IntervalTextHeight, new Vector2(0, -1), description.TextColor, description.Font);
                }
            }

            //Draw the line graphs on top of the body.
            {
                var dataToPixelsScale = new Vector2(description.BodySpan.X / (maxX - minX), (float)(description.BodySpan.Y / yDataSpan));
                Vector2 DataToScreenspace(int x, double y)
                {
                    var graphCoordinates  = new Vector2(x - minX, (float)(y - minY)) * dataToPixelsScale;
                    var screenCoordinates = graphCoordinates;

                    screenCoordinates.Y = description.BodySpan.Y - screenCoordinates.Y;
                    screenCoordinates  += description.BodyMinimum;
                    return(screenCoordinates);
                }

                for (int i = 0; i < graphSeries.Count; ++i)
                {
                    var series = graphSeries[i];
                    var data   = series.Data;
                    var count  = data.End - data.Start;
                    if (count > 0)
                    {
                        var previousScreenPosition = DataToScreenspace(data.Start, data[data.Start]);
                        if (count > 1)
                        {
                            for (int j = data.Start + 1; j < data.End; ++j)
                            {
                                var currentScreenPosition = DataToScreenspace(j, data[j]);
                                lines.Draw(previousScreenPosition, currentScreenPosition, series.LineRadius, series.LineColor);
                                previousScreenPosition = currentScreenPosition;
                            }
                        }
                        else
                        {
                            //Only one datapoint. Draw a zero length line just to draw a dot. (The shader can handle it without producing nans.)
                            lines.Draw(previousScreenPosition, previousScreenPosition, series.LineRadius, series.LineColor);
                        }
                    }
                }
            }

            //Draw the legend entry last. Alpha blending will put it on top in case the legend is positioned on top of the body.
            {
                var penPosition       = description.LegendMinimum;
                var legendLineSpacing = description.LegendNameHeight * 1.5f;
                penPosition.Y += legendLineSpacing;

                for (int i = 0; i < graphSeries.Count; ++i)
                {
                    var series    = graphSeries[i];
                    var lineStart = new Vector2(penPosition.X, penPosition.Y);
                    var lineEnd   = lineStart + new Vector2(description.LegendLineLength, -0.7f * description.LegendNameHeight);

                    lines.Draw(lineStart, lineEnd, series.LineRadius, series.LineColor);
                    var textStart = new Vector2(lineEnd.X + series.LineRadius + description.LegendNameHeight * 0.2f, penPosition.Y);
                    characters.Clear().Append(series.Name);
                    text.Write(characters, textStart, description.LegendNameHeight, description.TextColor, description.Font);
                    penPosition.Y += legendLineSpacing;
                }
            }
        }
Example #8
0
        public Renderer(RenderSurface surface)
        {
            looper  = new ParallelLooper();
            Surface = surface;
            using (var stream = new MemoryStream(Resources.DemoRendererShaders))
            {
                ShaderCache = ShaderCache.Load(stream);
            }
            Shapes         = new ShapesExtractor(looper);
            SphereRenderer = new SphereRenderer(surface.Device, ShaderCache);
            Lines          = new LineExtractor(looper);
            LineRenderer   = new LineRenderer(surface.Device, ShaderCache);
            Background     = new BackgroundRenderer(surface.Device, ShaderCache);
            CompressToSwap = new CompressToSwap(surface.Device, ShaderCache);

            GlyphRenderer  = new GlyphRenderer(surface.Device, surface.Context, ShaderCache);
            TextBatcher    = new TextBatcher();
            UILineRenderer = new UILineRenderer(surface.Device, ShaderCache);
            UILineBatcher  = new UILineBatcher();

            OnResize();
            var rasterizerStateDescription = RasterizerStateDescription.Default();

            rasterizerStateDescription.IsFrontCounterClockwise = true;
            rasterizerStateDescription.CullMode = CullMode.None;
            rasterizerState           = new RasterizerState(Surface.Device, rasterizerStateDescription);
            rasterizerState.DebugName = "Default Rasterizer State";

            var opaqueDepthStencilDescription = new DepthStencilStateDescription
            {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                //Note depth reversal.
                DepthComparison  = Comparison.Greater,
                IsStencilEnabled = false
            };

            opaqueDepthState           = new DepthStencilState(Surface.Device, opaqueDepthStencilDescription);
            opaqueDepthState.DebugName = "Opaque Depth State";

            var opaqueBlendStateDescription = BlendStateDescription.Default();

            opaqueBlendState           = new BlendState(Surface.Device, opaqueBlendStateDescription);
            opaqueBlendState.DebugName = "Opaque Blend State";

            var uiDepthStateDescription = new DepthStencilStateDescription
            {
                IsDepthEnabled = false,
                DepthWriteMask = DepthWriteMask.Zero,
                //Note depth reversal.
                DepthComparison  = Comparison.Greater,
                IsStencilEnabled = false
            };

            uiDepthState           = new DepthStencilState(Surface.Device, uiDepthStateDescription);
            uiDepthState.DebugName = "UI Depth State";

            //The UI will use premultiplied alpha.
            var uiBlendStateDescription = BlendStateDescription.Default();

            uiBlendStateDescription.RenderTarget[0].IsBlendEnabled        = true;
            uiBlendStateDescription.RenderTarget[0].SourceBlend           = BlendOption.One;
            uiBlendStateDescription.RenderTarget[0].SourceAlphaBlend      = BlendOption.One;
            uiBlendStateDescription.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
            uiBlendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.InverseSourceAlpha;
            uiBlendStateDescription.RenderTarget[0].BlendOperation        = BlendOperation.Add;
            uiBlendStateDescription.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
            uiBlendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            uiBlendState           = new BlendState(Surface.Device, uiBlendStateDescription);
            uiBlendState.DebugName = "UI Blend State";
        }