Step 5: Debug rendering |
To output text in an XNA game, we need a sprite font. Let's add one:
Modify MyGraphicsScreen.cs and add a DebugRenderer:
using System; using DigitalRune.Graphics; using DigitalRune.Graphics.Rendering; // NEW using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; // NEW namespace MyGame { public class MyGraphicsScreen : GraphicsScreen { public DebugRenderer DebugRenderer { get; private set; } // NEW public MyGraphicsScreen(IGraphicsService graphicsService) : base(graphicsService) { var spriteFont = graphicsService.Content.Load<SpriteFont>("SpriteFont1"); // NEW DebugRenderer = new DebugRenderer(graphicsService, spriteFont); // NEW } protected override void OnUpdate(TimeSpan deltaTime) { } protected override void OnRender(RenderContext context) { var graphicsDevice = GraphicsService.GraphicsDevice; graphicsDevice.Clear(Color.CornflowerBlue); DebugRenderer.Render(context); // NEW } } }
Draw some debug text in MyGameComponent.cs:
… public class MyGameComponent : Microsoft.Xna.Framework.GameComponent { … public MyGameComponent(Game game) : base(game) { _inputService = ServiceLocator.Current.GetInstance<IInputService>(); _graphicsService = ServiceLocator.Current.GetInstance<IGraphicsService>(); _myGraphicsScreen = new MyGraphicsScreen(_graphicsService); _graphicsService.Screens.Add(_myGraphicsScreen); _myGraphicsScreen.DebugRenderer.DrawText("MyGame"); // NEW } …
Now, the game looks like this:
Next, we use the DebugRenderer to render a few arrows at the world origin. Add the following lines in MyGameComponent.cs:
… using DigitalRune.Geometry; // NEW … namespace MyGame { public class MyGameComponent : Microsoft.Xna.Framework.GameComponent { … public MyGameComponent(Game game) : base(game) { … _myGraphicsScreen.DebugRenderer.DrawText("MyGame"); _myGraphicsScreen.DebugRenderer.DrawAxes(Pose.Identity, 1, false); // NEW } …
If you try to run the project, you will get an exception. The DebugRenderer lets you know that it cannot render 3D graphics without a camera. The camera is necessary to define the viewpoint of the player.
Let's add a camera in MyGraphicsScreen.cs:
using System; using DigitalRune.Geometry; using DigitalRune.Graphics; using DigitalRune.Graphics.Rendering; using DigitalRune.Graphics.SceneGraph; // NEW using DigitalRune.Mathematics; // NEW using DigitalRune.Mathematics.Algebra; // NEW using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace MyGame { public class MyGraphicsScreen : GraphicsScreen { public DebugRenderer DebugRenderer { get; set; } public CameraNode CameraNode { get; set; } // NEW public MyGraphicsScreen(IGraphicsService graphicsService) : base(graphicsService) { var spriteFont = graphicsService.Content.Load<SpriteFont>("SpriteFont1"); DebugRenderer = new DebugRenderer(graphicsService, spriteFont); var projection = new PerspectiveProjection(); // NEW projection.SetFieldOfView( // NEW ConstantsF.PiOver4, // NEW graphicsService.GraphicsDevice.Viewport.AspectRatio, // NEW 0.1f, // NEW 100); // NEW var camera = new Camera(projection); // NEW CameraNode = new CameraNode(camera); // NEW CameraNode.PoseWorld = new Pose(new Vector3F(0, 1, 3)); // NEW } … protected override void OnRender(RenderContext context) { var graphicsDevice = GraphicsService.GraphicsDevice; graphicsDevice.Clear(Color.CornflowerBlue); context.CameraNode = CameraNode; // NEW DebugRenderer.Render(context); context.CameraNode = null; // NEW } } }
The camera is positioned at (0, 1, 5). Per default it looks forward (which is the -z direction in XNA and DigitalRune). To let the renderer know which camera it should use, we have to set this information in the RenderContext in MyGraphicsScreen.OnRender.
Our current game: