public override void Draw(Squared.Render.Frame frame)
        {
            const float LightmapScale = 1f;

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, Width,
                Height, 0,
                0, 1
                );

            ClearBatch.AddNew(frame, 0, Game.ScreenMaterials.Clear, clearColor: Color.Black);

            Renderer.RenderLighting(frame, frame, 1);

            using (var bg = BatchGroup.New(frame, 2)) {
                var dc = new BitmapDrawCall(TestImage, new Vector2(0, 550), 0.55f);

                using (var bb = BitmapBatch.New(bg, 0, Renderer.Materials.ScreenSpaceBitmap))
                    bb.Add(ref dc);

                dc.Position.X += 600;
                dc.Textures    = new TextureSet(dc.Texture, RampTexture);

                using (var bb2 = BitmapBatch.New(bg, 1, Renderer.IlluminantMaterials.ScreenSpaceRampBitmap, samplerState2: SamplerState.LinearClamp))
                    bb2.Add(ref dc);
            }

            if (ShowOutlines)
            {
                Renderer.RenderOutlines(frame, 2, true);
            }
        }
        public override void Draw(GameTime gameTime, Frame frame)
        {
            ClearBatch.AddNew(frame, -1, materials.Clear, clearColor: Color.CornflowerBlue);

            level.Draw(gameTime, frame, materials);

            DrawHud(frame);
        }
示例#3
0
        public override void Draw(GameTime gameTime, Frame frame)
        {
            ClearBatch.AddNew(frame, 0, Materials.Clear, clearColor: Color.Black);

            ParallelDrawer.UserData.Now   = (float)Time.Seconds;
            ParallelDrawer.UserData.Frame = frame;

            ParallelDrawer.Invoke();
        }
示例#4
0
        public override void Draw(GameTime gameTime, Frame frame)
        {
            // HACK: We never set the blend state explicitly anywhere (unlike what SpriteBatch did),
            //  but it's sufficient to just set it once per frame here.
            // Normally you would do this in batch setup, but this is fine.
            graphics.GraphicsDevice.BlendState = BlendState.AlphaBlend;

            ClearBatch.AddNew(frame, -1, materials.Clear, clearColor: Color.CornflowerBlue);

            level.Draw(gameTime, frame, materials);

            DrawHud(frame);
        }
示例#5
0
        /// <summary>
        /// Adds a clear batch. Note that this will *always* advance the layer unless you specify a layer index explicitly.
        /// </summary>
        public void Clear(
            int?layer   = null,
            Color?color = null,
            float?z     = null,
            int?stencil = null
            )
        {
            int _layer = layer.GetValueOrDefault(Layer);

            ClearBatch.AddNew(Container, _layer, Materials.Clear, color, z, stencil);

            if (!layer.HasValue)
            {
                Layer += 1;
            }
        }
        public override void Draw(GameTime gameTime, Frame frame)
        {
            ClearBatch.AddNew(frame, -1, Materials.Clear, clearColor: ClearColor);

            const int width  = 1280;
            const int height = 720;

            var options = new ParallelOptions {
//                MaxDegreeOfParallelism = 1
            };
            int layer   = 0;

            Parallel.For(
                0, height, options,
                // One batch per worker thread
                () =>
                BitmapBatch.New(
                    frame,
                    // Suppress batch combining
                    Interlocked.Increment(ref layer),
                    Materials.ScreenSpaceBitmap
                    ),
                (y, loopState, bb) => {
                var drawCall = new BitmapDrawCall(WhitePixel, new Vector2(0, y));
                float fx     = 0;
                var range    = bb.ReserveSpace(width);
                var array    = range.Array;
                var offset   = range.Offset;

                for (int x = 0; x < width; x++, fx++)
                {
                    drawCall.Texture       = ((x % 2) == 0) ? WhitePixel : GrayPixel;
                    drawCall.Position.X    = fx;
                    drawCall.MultiplyColor = new Color(255, x % 255, y % 255);

                    array[offset + x] = drawCall;
                }

                return(bb);
            },
                (bb) =>
                bb.Dispose()
                );
        }
示例#7
0
        public override void Draw(Squared.Render.Frame frame)
        {
            const float LightmapScale = 1f;

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, Width,
                Height, 0,
                0, 1
                );

            CreateRenderTargets();

            var args = new float[] {
                MagnitudeScale, MiddleGray, AppliedAverageLuminance, MaximumLuminance
            };

            using (var bg = BatchGroup.ForRenderTarget(
                       frame, -1, Lightmap,
                       (dm, _) =>
                       Renderer.IlluminantMaterials.SetGammaCompressionParameters(args[0], args[1], args[2], args[3])
                       )) {
                ClearBatch.AddNew(bg, 0, LightmapMaterials.Clear, clearColor: Color.Black, clearZ: 0, clearStencil: 0);

                Renderer.RenderLighting(frame, bg, 1, intensityScale: 1 / MagnitudeScale);
            };

            ClearBatch.AddNew(frame, 0, Game.ScreenMaterials.Clear, clearColor: Color.Black);

            using (var bb = BitmapBatch.New(
                       frame, 1,
                       Game.ScreenMaterials.Get(Renderer.IlluminantMaterials.ScreenSpaceGammaCompressedBitmap, blendState: BlendState.Opaque)
                       ))
                bb.Add(new BitmapDrawCall(Lightmap, Vector2.Zero));

            if (ShowOutlines)
            {
                Renderer.RenderOutlines(frame, 2, true);
            }
        }
        public override void Draw(Squared.Render.Frame frame)
        {
            const float LightmapScale = 1f;

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, Width,
                Height, 0,
                0, 1
                );

            ClearBatch.AddNew(frame, 0, Game.ScreenMaterials.Clear, clearColor: Color.Black);

            Renderer.RenderLighting(frame, frame, 1);

            if (ShowOutlines)
            {
                Renderer.RenderOutlines(frame, 2, true);
            }

            using (var gb = GeometryBatch.New(frame, 3, Game.ScreenMaterials.Get(Game.ScreenMaterials.ScreenSpaceGeometry, blendState: BlendState.Opaque)))
                for (var i = 0; i < Receivers.Length; i++)
                {
                    var r = Receivers[i];
                    if (!r.ReceivedLight.HasValue)
                    {
                        continue;
                    }

                    var size   = new Vector2(8, 8);
                    var bounds = new Bounds(r.Position - size, r.Position + size);
                    var color  = new Color(r.ReceivedLight.Value.X, r.ReceivedLight.Value.Y, r.ReceivedLight.Value.Z, 1.0f) * r.ReceivedLight.Value.W;

                    // Console.WriteLine("Receiver {0} at {1}: {2}", i, r.Position, r.ReceivedLight);

                    gb.AddFilledQuad(bounds, color);
                }
        }
        /// <summary>
        /// Renders all light sources into the target batch container on the specified layer.
        /// </summary>
        /// <param name="frame">Necessary for bookkeeping.</param>
        /// <param name="container">The batch container to render lighting into.</param>
        /// <param name="layer">The layer to render lighting into.</param>
        /// <param name="intensityScale">A factor to scale the intensity of all light sources. You can use this to rescale the intensity of light values for HDR.</param>
        public void RenderLighting(Frame frame, IBatchContainer container, int layer, float intensityScale = 1.0f)
        {
            // FIXME
            var pointLightVertexCount = Environment.LightSources.Count * 4;
            var pointLightIndexCount  = Environment.LightSources.Count * 6;

            if (PointLightVertices.Length < pointLightVertexCount)
            {
                PointLightVertices = new PointLightVertex[1 << (int)Math.Ceiling(Math.Log(pointLightVertexCount, 2))];
            }

            if ((PointLightIndices == null) || (PointLightIndices.Length < pointLightIndexCount))
            {
                PointLightIndices = new short[pointLightIndexCount];

                int i = 0, j = 0;
                while (i < pointLightIndexCount)
                {
                    PointLightIndices[i++] = (short)(j + 0);
                    PointLightIndices[i++] = (short)(j + 1);
                    PointLightIndices[i++] = (short)(j + 3);
                    PointLightIndices[i++] = (short)(j + 1);
                    PointLightIndices[i++] = (short)(j + 2);
                    PointLightIndices[i++] = (short)(j + 3);

                    j += 4;
                }
            }

            var         needStencilClear = true;
            int         vertexOffset = 0, indexOffset = 0;
            LightSource batchFirstLightSource = null;
            BatchGroup  currentLightGroup     = null;

            int layerIndex = 0;

            using (var sortedLights = BufferPool <LightSource> .Allocate(Environment.LightSources.Count))
                using (var resultGroup = BatchGroup.New(container, layer, before: StoreScissorRect, after: RestoreScissorRect)) {
                    if (Render.Tracing.RenderTrace.EnableTracing)
                    {
                        Render.Tracing.RenderTrace.Marker(resultGroup, -9999, "Frame {0:0000} : LightingRenderer {1:X4} : Begin", frame.Index, this.GetHashCode());
                    }

                    int i          = 0;
                    var lightCount = Environment.LightSources.Count;

                    foreach (var lightSource in Environment.LightSources)
                    {
                        sortedLights.Data[i++] = lightSource;
                    }

                    Array.Sort(sortedLights.Data, 0, lightCount, LightSourceComparerInstance);

                    int lightGroupIndex = 1;

                    for (i = 0; i < lightCount; i++)
                    {
                        var lightSource = sortedLights.Data[i];

                        if (lightSource.Opacity <= 0)
                        {
                            continue;
                        }

                        if (batchFirstLightSource != null)
                        {
                            var needFlush =
                                (needStencilClear) ||
                                (batchFirstLightSource.ClipRegion.HasValue != lightSource.ClipRegion.HasValue) ||
                                (batchFirstLightSource.NeutralColor != lightSource.NeutralColor) ||
                                (batchFirstLightSource.Mode != lightSource.Mode) ||
                                (batchFirstLightSource.RampMode != lightSource.RampMode) ||
                                (batchFirstLightSource.RampTexture != lightSource.RampTexture) ||
                                (batchFirstLightSource.RampTextureFilter != lightSource.RampTextureFilter);

                            if (needFlush)
                            {
                                if (Render.Tracing.RenderTrace.EnableTracing)
                                {
                                    Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Point Light Flush ({2} point(s))", frame.Index, this.GetHashCode(), PointLightBatchBuffer.Count);
                                }
                                FlushPointLightBatch(ref currentLightGroup, ref batchFirstLightSource, ref layerIndex);
                                indexOffset = 0;
                            }
                        }

                        if (batchFirstLightSource == null)
                        {
                            batchFirstLightSource = lightSource;
                        }
                        if (currentLightGroup == null)
                        {
                            currentLightGroup = BatchGroup.New(resultGroup, lightGroupIndex++, before: RestoreScissorRect);
                        }

                        var lightBounds = new Bounds(lightSource.Position - new Vector2(lightSource.RampEnd), lightSource.Position + new Vector2(lightSource.RampEnd));

                        Bounds clippedLightBounds;
                        if (lightSource.ClipRegion.HasValue)
                        {
                            var clipBounds = lightSource.ClipRegion.Value;
                            if (!lightBounds.Intersection(ref lightBounds, ref clipBounds, out clippedLightBounds))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            clippedLightBounds = lightBounds;
                        }

                        if (needStencilClear)
                        {
                            if (Render.Tracing.RenderTrace.EnableTracing)
                            {
                                Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Stencil Clear", frame.Index, this.GetHashCode());
                            }
                            ClearBatch.AddNew(currentLightGroup, layerIndex++, IlluminantMaterials.ClearStencil, clearStencil: StencilFalse);
                            needStencilClear = false;
                        }

                        NativeBatch stencilBatch = null;
                        SpatialCollection <LightObstructionBase> .Sector currentSector;
                        using (var e = Environment.Obstructions.GetSectorsFromBounds(lightBounds))
                            while (e.GetNext(out currentSector))
                            {
                                var cachedSector = GetCachedSector(frame, currentSector.Index);
                                if (cachedSector.VertexCount <= 0)
                                {
                                    continue;
                                }

                                if (stencilBatch == null)
                                {
                                    if (Render.Tracing.RenderTrace.EnableTracing)
                                    {
                                        Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Begin Stencil Shadow Batch", frame.Index, this.GetHashCode());
                                    }

                                    stencilBatch = NativeBatch.New(currentLightGroup, layerIndex++, IlluminantMaterials.Shadow, ShadowBatchSetup, lightSource);
                                    stencilBatch.Dispose();
                                    needStencilClear = true;

                                    if (Render.Tracing.RenderTrace.EnableTracing)
                                    {
                                        Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : End Stencil Shadow Batch", frame.Index, this.GetHashCode());
                                    }
                                }

                                stencilBatch.Add(new NativeDrawCall(
                                                     PrimitiveType.TriangleList, cachedSector.ObstructionVertexBuffer, 0, cachedSector.ObstructionIndexBuffer, 0, 0, cachedSector.VertexCount, 0, cachedSector.PrimitiveCount
                                                     ));
                            }

                        PointLightVertex vertex;

                        vertex.LightCenter = lightSource.Position;
                        vertex.Color       = lightSource.Color;
                        vertex.Color.W    *= (lightSource.Opacity * intensityScale);
                        vertex.Ramp        = new Vector2(lightSource.RampStart, lightSource.RampEnd);

                        vertex.Position = clippedLightBounds.TopLeft;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.TopRight;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.BottomRight;
                        PointLightVertices[vertexOffset++] = vertex;

                        vertex.Position = clippedLightBounds.BottomLeft;
                        PointLightVertices[vertexOffset++] = vertex;

                        var newRecord = new PointLightRecord {
                            VertexOffset = vertexOffset - 4,
                            IndexOffset  = indexOffset,
                            VertexCount  = 4,
                            IndexCount   = 6
                        };

                        if (PointLightBatchBuffer.Count > 0)
                        {
                            var oldRecord = PointLightBatchBuffer[PointLightBatchBuffer.Count - 1];

                            if (
                                (newRecord.VertexOffset == oldRecord.VertexOffset + oldRecord.VertexCount) &&
                                (newRecord.IndexOffset == oldRecord.IndexOffset + oldRecord.IndexCount)
                                )
                            {
                                oldRecord.VertexCount += newRecord.VertexCount;
                                oldRecord.IndexCount  += newRecord.IndexCount;
                                PointLightBatchBuffer[PointLightBatchBuffer.Count - 1] = oldRecord;
                            }
                            else
                            {
                                PointLightBatchBuffer.Add(newRecord);
                            }
                        }
                        else
                        {
                            PointLightBatchBuffer.Add(newRecord);
                        }

                        indexOffset += 6;
                    }

                    if (PointLightBatchBuffer.Count > 0)
                    {
                        if (Render.Tracing.RenderTrace.EnableTracing)
                        {
                            Render.Tracing.RenderTrace.Marker(currentLightGroup, layerIndex++, "Frame {0:0000} : LightingRenderer {1:X4} : Point Light Flush ({2} point(s))", frame.Index, this.GetHashCode(), PointLightBatchBuffer.Count);
                        }

                        FlushPointLightBatch(ref currentLightGroup, ref batchFirstLightSource, ref layerIndex);
                    }

                    if (Render.Tracing.RenderTrace.EnableTracing)
                    {
                        Render.Tracing.RenderTrace.Marker(resultGroup, 9999, "Frame {0:0000} : LightingRenderer {1:X4} : End", frame.Index, this.GetHashCode());
                    }
                }
        }
示例#10
0
        public override void Draw(GameTime gameTime, Frame frame)
        {
            ClearBatch.AddNew(frame, 4, Materials.Clear, clearColor: new Color(16, 32, 48));

            var alphaGeometry = Materials.Get(Materials.ScreenSpaceGeometry, blendState: BlendState.AlphaBlend);

            using (var gb = GeometryBatch.New(frame, 5, alphaGeometry)) {
                gb.AddGradientFilledQuad(
                    Vector2.Zero, new Vector2(Graphics.PreferredBackBufferWidth, Graphics.PreferredBackBufferHeight),
                    Color.DarkSlateGray, Color.DarkSlateGray,
                    Color.SlateBlue, Color.SlateBlue
                    );
            }

            using (var gb = GeometryBatch.New(frame, 6, alphaGeometry)) {
                var alphaBlack  = new Color(0, 0, 0, 192);
                var alphaBlack2 = new Color(0, 0, 0, 64);

                gb.AddQuadBorder(
                    Playfield.Bounds.TopLeft + new Vector2(32 + 24, 0),
                    Playfield.Bounds.BottomRight + new Vector2(-32 - 24, 0),
                    alphaBlack2, alphaBlack, 24
                    );
            }

            // Render the contents of the trail buffer to the screen using additive blending
            using (var bb = BitmapBatch.New(frame, 7, Materials.Trail)) {
                bb.Add(new BitmapDrawCall(
                           TrailBuffer, Vector2.Zero, (float)TrailScale
                           ));
            }

            // Render the paddles and ball to both the framebuffer and the trail buffer (note the different layer values)
            using (var gb = GeometryBatch.New(frame, 8, alphaGeometry))
                using (var gb2 = GeometryBatch.New(frame, 9, alphaGeometry))
                    using (var trailBatch = GeometryBatch.New(frame, 2, alphaGeometry)) {
                        foreach (var paddle in Paddles)
                        {
                            gb.AddFilledQuad(
                                paddle.Bounds.TopLeft, paddle.Bounds.BottomRight, Color.White
                                );
                            gb2.AddQuadBorder(
                                paddle.Bounds.TopLeft, paddle.Bounds.BottomRight, Color.Black, Color.Black, 2.25f
                                );

                            trailBatch.AddFilledQuad(
                                paddle.Bounds.TopLeft, paddle.Bounds.BottomRight, Color.White
                                );
                        }

                        gb.AddFilledRing(Ball.Position, 0.0f, Ball.Radius, Color.White, Color.White);
                        gb2.AddFilledRing(Ball.Position, Ball.Radius, Ball.Radius + 2.0f, Color.Black, Color.Black);

                        trailBatch.AddFilledRing(Ball.Position, 0.0f, Ball.Radius, Color.White, Color.White);
                    }

            // Render the score values using a stringbatch (unfortunately this uses spritebatch to render spritefonts :( )
            {
                var ir = new ImperativeRenderer(frame, Materials, 10, blendState: BlendState.AlphaBlend);
                ir.DrawString(
                    Font, String.Format("Player 1: {0:00}", Scores[0]),
                    new Vector2(16, 16)
                    );

                var player2Text = String.Format("Player 2: {0:00}", Scores[1]);
                ir.DrawString(
                    Font, player2Text,
                    new Vector2(Graphics.PreferredBackBufferWidth - 16 - Font.MeasureString(player2Text).X, 16)
                    );
            }

            // The first stage of our frame involves selecting the trail buffer as our render target (note that it's layer 0)
            SetRenderTargetBatch.AddNew(frame, 0, TrailBuffer);

            if (FirstFrame)
            {
                // If it's the first time we've rendered, we erase the trail buffer since it could contain anything
                ClearBatch.AddNew(frame, 1, Materials.Clear, clearColor: Color.Black);
                FirstFrame = false;
            }
            else
            {
                // Otherwise, we fade out the contents of the trail buffer
                using (var gb = GeometryBatch.New(frame, 1, Materials.SubtractiveGeometry)) {
                    gb.AddFilledQuad(
                        new Bounds(Vector2.Zero, new Vector2(Graphics.PreferredBackBufferWidth, Graphics.PreferredBackBufferHeight)),
                        new Color(12, 12, 12, 0)
                        );
                }
            }

            // After the trail buffer has been updated, we turn it off and begin rendering to the framebuffer. Note layer 3.
            SetRenderTargetBatch.AddNew(frame, 3, null);
        }
示例#11
0
        public override void Draw(Squared.Render.Frame frame)
        {
            CreateRenderTargets();

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, BackgroundLightmap.Width,
                BackgroundLightmap.Height, 0,
                0, 1
                );

            using (var backgroundGroup = BatchGroup.ForRenderTarget(frame, 0, Background)) {
                ClearBatch.AddNew(backgroundGroup, 1, Game.ScreenMaterials.Clear, clearColor: Color.Transparent);

                using (var bb = BitmapBatch.New(backgroundGroup, 2, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    for (var i = 0; i < 1; i++)
                    {
                        var layer = Layers[i];
                        var dc    = new BitmapDrawCall(layer, Vector2.Zero);
                        dc.SortKey = i;
                        bb.Add(dc);
                    }
                }
            }

            using (var foregroundGroup = BatchGroup.ForRenderTarget(frame, 1, Foreground)) {
                ClearBatch.AddNew(foregroundGroup, 1, Game.ScreenMaterials.Clear, clearColor: Color.Transparent);

                using (var bb = BitmapBatch.New(foregroundGroup, 2, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    for (var i = 1; i < Layers.Length; i++)
                    {
                        var layer = Layers[i];
                        var dc    = new BitmapDrawCall(layer, Vector2.Zero);
                        dc.SortKey = i;
                        bb.Add(dc);
                    }
                }
            }

            using (var backgroundLightGroup = BatchGroup.ForRenderTarget(frame, 4, BackgroundLightmap)) {
                ClearBatch.AddNew(backgroundLightGroup, 1, LightmapMaterials.Clear, clearColor: new Color(32, 32, 32, 255), clearZ: 0, clearStencil: 0);
                BackgroundRenderer.RenderLighting(frame, backgroundLightGroup, 2);
            }

            using (var foregroundLightGroup = BatchGroup.ForRenderTarget(frame, 5, ForegroundLightmap)) {
                ClearBatch.AddNew(foregroundLightGroup, 1, LightmapMaterials.Clear, clearColor: new Color(96, 96, 96, 255), clearZ: 0, clearStencil: 0);
                ForegroundRenderer.RenderLighting(frame, foregroundLightGroup, 2);
            }

            SetRenderTargetBatch.AddNew(frame, 49, null);
            ClearBatch.AddNew(frame, 50, Game.ScreenMaterials.Clear, clearColor: Color.Black, clearZ: 0, clearStencil: 0);

            if (ShowLightmap)
            {
                using (var bb = BitmapBatch.New(frame, 55, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    var dc = new BitmapDrawCall(BackgroundLightmap, Vector2.Zero, LightmapScale);
                    bb.Add(dc);
                }

                ParticleRenderer.Draw(frame, 56);
            }
            else
            {
                var dc = new BitmapDrawCall(Background, Vector2.Zero);

                var material = LightmapMaterials.Get(LightmapMaterials.WorldSpaceLightmappedBitmap, blendState: BlendState.AlphaBlend);

                using (var bb = BitmapBatch.New(frame, 55, material)) {
                    dc.Textures = new TextureSet(Background, BackgroundLightmap);
                    dc.SortKey  = 0;

                    bb.Add(dc);
                }

                ParticleRenderer.Draw(frame, 56);

                using (var bb = BitmapBatch.New(frame, 57, material)) {
                    dc.Textures = new TextureSet(Foreground, ForegroundLightmap);
                    dc.SortKey  = 1;

                    bb.Add(dc);
                }
            }

            if (ShowOutlines || (Dragging != null))
            {
                BackgroundRenderer.RenderOutlines(frame, 59, true);
            }
        }
示例#12
0
        public override void Draw(GameTime gameTime, Frame frame)
        {
            if (false)
            {
                var stats = RenderManager.GetMemoryStatistics();
                Console.WriteLine(
                    "managed: {0:0000000}kb    vertex: {1:0000000}kb    index: {2:0000000}kb",
                    (stats.ManagedIndexBytes + stats.ManagedVertexBytes) / 1024.0,
                    stats.UnmanagedVertexBytes / 1024.0,
                    stats.UnmanagedIndexBytes / 1024.0
                    );
            }

            ClearBatch.AddNew(frame, -1, Materials.Clear, clearColor: ClearColor);

            const int width  = 1280;
            const int height = 720;

            var options = new ParallelOptions {
//                MaxDegreeOfParallelism = 1
            };
            int layer   = 0;

            Parallel.For(
                0, height, options,
                // One batch per worker thread
                () =>
                BitmapBatch.New(
                    frame,
                    // Suppress batch combining
                    Interlocked.Increment(ref layer),
                    Materials.ScreenSpaceBitmap
                    ),
                (y, loopState, bb) => {
                var drawCall = new BitmapDrawCall(WhitePixel, new Vector2(0, y));
                float fx     = 0;
                var range    = bb.ReserveSpace(width);
                var array    = range.Array;
                var offset   = range.Offset;

                for (int x = 0; x < width; x++, fx++)
                {
                    drawCall.Texture       = ((x % 2) == 0) ? WhitePixel : GrayPixel;
                    drawCall.Position.X    = fx;
                    drawCall.MultiplyColor = new Color(255, x % 255, y % 255);

                    array[offset + x] = drawCall;
                }

                return(bb);
            },
                (bb) =>
                bb.Dispose()
                );

            var ir = new ImperativeRenderer(
                frame, Materials,
                blendState: BlendState.Opaque,
                depthStencilState: DepthStencilState.None,
                rasterizerState: RasterizerState.CullNone,
                worldSpace: false,
                layer: 9999
                );

            DrawPerformanceStats(ref ir);
        }
示例#13
0
        public override void Draw(Squared.Render.Frame frame)
        {
            CreateRenderTargets();

            LightmapMaterials.ViewportScale    = new Vector2(1f / LightmapScale);
            LightmapMaterials.ProjectionMatrix = Matrix.CreateOrthographicOffCenter(
                0, BackgroundLightmap.Width,
                BackgroundLightmap.Height, 0,
                0, 1
                );

            using (var backgroundGroup = BatchGroup.ForRenderTarget(frame, 0, Background)) {
                ClearBatch.AddNew(backgroundGroup, 1, Game.ScreenMaterials.Clear, clearColor: Color.Transparent);

                using (var bb = BitmapBatch.New(backgroundGroup, 2, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    for (var i = 0; i < 1; i++)
                    {
                        var layer = Layers[i];
                        var dc    = new BitmapDrawCall(layer, Vector2.Zero);
                        dc.SortKey = i;
                        bb.Add(dc);
                    }
                }
            }

            using (var foregroundGroup = BatchGroup.ForRenderTarget(frame, 1, Foreground)) {
                ClearBatch.AddNew(foregroundGroup, 1, Game.ScreenMaterials.Clear, clearColor: Color.Transparent);

                using (var bb = BitmapBatch.New(foregroundGroup, 2, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    for (var i = 1; i < Layers.Length; i++)
                    {
                        var layer = Layers[i];
                        var dc    = new BitmapDrawCall(layer, Vector2.Zero);
                        dc.SortKey = i;
                        bb.Add(dc);
                    }
                }
            }

            if (ShowBrickSpecular)
            {
                using (var bricksLightGroup = BatchGroup.ForRenderTarget(frame, 2, ForegroundLightmap)) {
                    ClearBatch.AddNew(bricksLightGroup, 1, LightmapMaterials.Clear, clearColor: new Color(0, 0, 0, 255), clearZ: 0, clearStencil: 0);
                    ForegroundRenderer.RenderLighting(frame, bricksLightGroup, 2);
                }
            }

            if (ShowAOShadow)
            {
                using (var aoShadowFirstPassGroup = BatchGroup.ForRenderTarget(frame, 3, AOShadowScratch)) {
                    ClearBatch.AddNew(aoShadowFirstPassGroup, 1, LightmapMaterials.Clear, clearColor: Color.Transparent);

                    using (var bb = BitmapBatch.New(aoShadowFirstPassGroup, 2, Game.ScreenMaterials.ScreenSpaceHorizontalGaussianBlur5Tap)) {
                        bb.Add(new BitmapDrawCall(Foreground, Vector2.Zero, 1f / LightmapScale));
                    }
                }
            }

            using (var backgroundLightGroup = BatchGroup.ForRenderTarget(frame, 4, BackgroundLightmap)) {
                ClearBatch.AddNew(backgroundLightGroup, 1, LightmapMaterials.Clear, clearColor: new Color(40, 40, 40, 255), clearZ: 0, clearStencil: 0);

                BackgroundRenderer.RenderLighting(frame, backgroundLightGroup, 2);

                if (ShowBrickSpecular)
                {
                    using (var foregroundLightBatch = BitmapBatch.New(backgroundLightGroup, 3, MaskedForegroundMaterial)) {
                        var dc = new BitmapDrawCall(
                            ForegroundLightmap, Vector2.Zero
                            );
                        dc.Textures = new TextureSet(dc.Textures.Texture1, BricksLightMask);
                        foregroundLightBatch.Add(dc);
                    }
                }
                else
                {
                    ForegroundRenderer.RenderLighting(frame, backgroundLightGroup, 3);
                }

                if (ShowAOShadow)
                {
                    using (var aoShadowBatch = BitmapBatch.New(backgroundLightGroup, 4, AOShadowMaterial)) {
                        var dc = new BitmapDrawCall(
                            AOShadowScratch, new Vector2(0, 4)
                            );
                        dc.MultiplyColor = Color.Black;
                        dc.AddColor      = Color.White;

                        aoShadowBatch.Add(dc);
                    }
                }
            }

            using (var foregroundLightGroup = BatchGroup.ForRenderTarget(frame, 5, ForegroundLightmap)) {
                ClearBatch.AddNew(foregroundLightGroup, 1, LightmapMaterials.Clear, clearColor: new Color(127, 127, 127, 255), clearZ: 0, clearStencil: 0);
                ForegroundRenderer.RenderLighting(frame, foregroundLightGroup, 2);
            }

            SetRenderTargetBatch.AddNew(frame, 49, null);
            ClearBatch.AddNew(frame, 50, Game.ScreenMaterials.Clear, clearColor: Color.Black, clearZ: 0, clearStencil: 0);

            if (ShowLightmap)
            {
                using (var bb = BitmapBatch.New(frame, 55, Game.ScreenMaterials.WorldSpaceBitmap)) {
                    var dc = new BitmapDrawCall(BackgroundLightmap, Vector2.Zero, LightmapScale);
                    bb.Add(dc);
                }
            }
            else
            {
                var dc = new BitmapDrawCall(Background, Vector2.Zero);

                var material = LightmapMaterials.Get(LightmapMaterials.WorldSpaceLightmappedBitmap, blendState: BlendState.AlphaBlend);

                using (var bb = BitmapBatch.New(frame, 55, material)) {
                    dc.Textures = new TextureSet(Background, BackgroundLightmap);
                    dc.SortKey  = 0;

                    bb.Add(dc);
                }

                ParticleRenderer.Draw(frame, 56);

                using (var bb = BitmapBatch.New(frame, 57, material)) {
                    dc.Textures = new TextureSet(Foreground, ForegroundLightmap);
                    dc.SortKey  = 1;

                    bb.Add(dc);
                }
            }

            if (ShowOutlines || (Dragging != null))
            {
                BackgroundRenderer.RenderOutlines(frame, 59, true);
            }
        }