public override void Draw(GameTime gameTime, Frame frame) { using (var rtb = BatchGroup.ForRenderTarget(frame, -1, Rt)) { var ir = new ImperativeRenderer(rtb, Materials); ir.Clear(color: Color.Transparent); ir.SetViewport(new Rectangle(128, 128, 256, 256), true); ir.FillRectangle(new Rectangle(0, 0, 512, 512), Color.Black, customMaterial: Vpos); } { var ir = new ImperativeRenderer(frame, Materials) { AutoIncrementLayer = true }; ir.SetViewport(null, true); ir.Clear(color: Color.SteelBlue); const float scale = 0.65f; var pos = new Vector2(Graphics.PreferredBackBufferWidth, Graphics.PreferredBackBufferHeight) / 2f; ir.Draw( Texture, pos, origin: Vector2.One * 0.5f, scale: Vector2.One * scale, blendState: BlendState.Opaque, samplerState: SamplerState.LinearClamp ); ir.DrawString( Font, "Hello, World!", Vector2.Zero, blendState: BlendState.AlphaBlend, material: Materials.ScreenSpaceShadowedBitmap ); var sg = ir.MakeSubgroup(); sg.AutoIncrementLayer = true; sg.SetViewport(new Rectangle(128, 128, 512, 512), true); sg.FillRectangle(new Rectangle(0, 0, 1024, 1024), Color.Black, customMaterial: Vpos); sg.SetViewport(null, true); ir.Draw( Rt, new Vector2(1920 - 512, 0) ); } }
private void DrawHud(Frame frame) { Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea; Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y); Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f, titleSafeArea.Y + titleSafeArea.Height / 2.0f); // Draw time remaining. Uses modulo division to cause blinking when the // player is running out of time. string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00"); Color timeColor; if (level.TimeRemaining > WarningTime || level.ReachedExit || (int)level.TimeRemaining.TotalSeconds % 2 == 0) { timeColor = Color.Yellow; } else { timeColor = Color.Red; } var renderer = new ImperativeRenderer(frame, materials, 100, blendState: BlendState.AlphaBlend); renderer.DrawString(hudFont, timeString, hudLocation, timeColor, sortKey: 1); renderer.DrawString(hudFont, timeString, hudLocation + Vector2.One, Color.Black, sortKey: 0); var timeHeight = hudFont.MeasureString(timeString).Y; hudLocation.Y = (float)Math.Floor(hudLocation.Y + (timeHeight * 1.2f)); var scoreText = "SCORE: " + level.Score; renderer.DrawString(hudFont, scoreText, hudLocation, Color.Yellow, sortKey: 1); renderer.DrawString(hudFont, scoreText, hudLocation + Vector2.One, Color.Black, sortKey: 0); // Determine the status overlay message to show. Texture2D status = null; if (level.TimeRemaining == TimeSpan.Zero) { if (level.ReachedExit) { status = winOverlay; } else { status = loseOverlay; } } else if (!level.Player.IsAlive) { status = diedOverlay; } if (status != null) { // Draw status message. Vector2 statusSize = new Vector2(status.Width, status.Height); renderer.Draw(status, center - statusSize / 2); } }
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); }