Beispiel #1
0
        internal void AddGeometry(Vertex[] vertices, RenderProgram renderProgram)
        {
            // Find a batch with matching render programs or create a new one if it does not exist
            GeometryBatch batch = FindBatch(renderProgram) ?? CreateBatch(renderProgram);

            batch.AddVertices(vertices);
        }
        public void RenderOutlines(IBatchContainer container, int layer, bool showLights, Color?lineColor = null, Color?lightColor = null)
        {
            using (var group = BatchGroup.New(container, layer)) {
                using (var gb = GeometryBatch.New(group, 0, IlluminantMaterials.DebugOutlines)) {
                    VisualizerLineWriterInstance.Batch = gb;
                    VisualizerLineWriterInstance.Color = lineColor.GetValueOrDefault(Color.White);

                    foreach (var lo in Environment.Obstructions)
                    {
                        lo.GenerateLines(VisualizerLineWriterInstance);
                    }

                    VisualizerLineWriterInstance.Batch = null;
                }

                int i = 0;

                if (showLights)
                {
                    foreach (var lightSource in Environment.LightSources)
                    {
                        var cMax = lightColor.GetValueOrDefault(Color.White);
                        var cMin = cMax * 0.25f;

                        using (var gb = GeometryBatch.New(group, i + 1, IlluminantMaterials.DebugOutlines)) {
                            gb.AddFilledRing(lightSource.Position, 0f, 2f, cMax, cMax);
                            gb.AddFilledRing(lightSource.Position, lightSource.RampStart - 1f, lightSource.RampStart + 1f, cMax, cMax);
                            gb.AddFilledRing(lightSource.Position, lightSource.RampEnd - 1f, lightSource.RampEnd + 1f, cMin, cMin);
                        }

                        i += 1;
                    }
                }
            }
        }
Beispiel #3
0
 private void RemoveBatch(GeometryBatch batch)
 {
     for (int i = Batches.Count - 1; i >= 0; i--)
     {
         if (Batches[i] == batch)
         {
             Batches.RemoveAt(i);
             break;
         }
     }
     SortBatchesByDrawLayer();
 }
Beispiel #4
0
        private void ParallelPrepareOrbs(int partitionIndex, int partitionCount, DrawArgs args)
        {
            Orb           orb;
            int           i     = 0;
            GeometryBatch batch = null;

            using (var e = Orbs.GetParallelEnumerator(partitionIndex, partitionCount))
                while (e.GetNext(out orb))
                {
                    if (batch == null)
                    {
                        batch = GeometryBatch.New(args.Frame, 1, Materials.WorldSpaceGeometry);
                    }

                    // Compute the position of this orb at the current time
                    var position = Orb.Interpolator(
                        Orb.InterpolatorSource, ref orb,
                        0, (args.Now - orb.LastUpdateAt) / orb.Duration
                        );

                    // AddFilledRing is actually pretty computationally intensive compared to drawing a quad
                    //  so on XBox 360 you can get much higher performance by switching from filled rings to quads

                    if (UseQuads)
                    {
                        batch.AddFilledQuad(
                            position - orb.Size, position + orb.Size, orb.Color
                            );
                    }
                    else
                    {
                        batch.AddFilledRing(
                            position, Vector2.Zero, orb.Size, orb.Color, Color.Transparent
                            );
                    }

                    i += 1;
                    if ((i % BatchSize) == 0)
                    {
                        // Once our batch contains enough objects, we 'dispose' it to tell the renderer that it is done being prepared.
                        // This normally looks like 'using (batch)', which is (IMO) easier to understand... still, kind of a nasty hack.
                        batch.Dispose();
                        batch = null;
                    }
                }

            if (batch != null)
            {
                batch.Dispose();
            }
        }
Beispiel #5
0
        internal GeometryBatch CreateBatch(RenderProgram renderProgram)
        {
            GeometryBatch newBatch = new GeometryBatch(renderProgram);

            Batches.Add(newBatch);
            SortBatchesByDrawLayer();

            if (BatchesAreHot)
            {
                newBatch.Begin();
            }

            return(newBatch);
        }
Beispiel #6
0
        public GeometryBatch GetGeometryBatch(int?layer, bool?worldSpace, BlendState blendState)
        {
            if (Materials == null)
            {
                throw new InvalidOperationException("You cannot use the argumentless ImperativeRenderer constructor.");
            }

            var actualLayer       = layer.GetValueOrDefault(Layer);
            var actualWorldSpace  = worldSpace.GetValueOrDefault(WorldSpace);
            var desiredBlendState = blendState ?? BlendState;

            CachedBatch cacheEntry;

            if (!Cache.TryGet <GeometryBatch>(
                    out cacheEntry,
                    CachedBatchType.Geometry,
                    container: Container,
                    layer: actualLayer,
                    worldSpace: actualWorldSpace,
                    rasterizerState: RasterizerState,
                    depthStencilState: DepthStencilState,
                    blendState: desiredBlendState,
                    samplerState: null,
                    customMaterial: null,
                    useZBuffer: UseZBuffer
                    ))
            {
                var material = Materials.GetGeometryMaterial(
                    actualWorldSpace,
                    rasterizerState: RasterizerState,
                    depthStencilState: DepthStencilState,
                    blendState: desiredBlendState
                    );

                cacheEntry.Batch = GeometryBatch.New(Container, actualLayer, material);
                Cache.InsertAtFront(ref cacheEntry, null);
            }

            if (AutoIncrementLayer && !layer.HasValue)
            {
                Layer += 1;
            }

            return((GeometryBatch)cacheEntry.Batch);
        }
        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);
                }
        }
        public unsafe GraphicsCanvas([NotNull] GraphicsDevice device,
                                     [NotNull] RenderTargetView renderTarget,
                                     Vector2f canvasUnits)
        {
            info = new GraphicsCanvasInfo(this);

            // Initialize shaders.
            Initialize();

            this.unitSize     = canvasUnits;
            this.device       = device;
            this.renderTarget = renderTarget;

            this.batch = Geometry.CreateBatch(VertexData.Format, new IndexFormat(true),
                                              MaxVerticesInBatch, MaxIndicesInBatch, CyclicBufferCount);

            // We also immediatelly bind it to device.
            this.batch.BindToDevice(device);

            // We create vertex constants buffer.
            {
                TypelessBuffer vertexConstBuffer = new TypelessBuffer(Usage.Dynamic, BufferUsage.ConstantBuffer,
                                                                      CPUAccess.Write, GraphicsLocality.DeviceOrSystemMemory, 16 * 4 * 2);
                vertexConstBuffer.DisposeOnViewDispose = true;

                ConstantBufferLayoutBuilder vertexBufferLayout = new ConstantBufferLayoutBuilder();
                vertexBufferLayout.AppendElement("PositionTransform", PinFormat.Float4x4);
                vertexBufferLayout.AppendElement("TextureTransform", PinFormat.Float4x4);

                vertexConstants = vertexConstBuffer.CreateConstantBuffer(vertexBufferLayout.CreateLayout());
            }

            // We create pixel constants buffer.
            pixelConstants = new TypelessBuffer(Usage.Dynamic, BufferUsage.ConstantBuffer, CPUAccess.Write,
                                                GraphicsLocality.DeviceOrSystemMemory, ConstantBufferView.MaxSize);
        }
Beispiel #9
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);
        }