Can't get DebugView working

Topics: User Forum
May 25, 2011 at 6:45 AM
Edited May 27, 2011 at 3:51 PM

Hi all,

 

I'm trying to get DebugViewXNA working for my game, but I can't seem to figure it out. I've done lots of research and googling and experimenting, but XNA and Farseer often change, which makes reading someone's old source difficult. My source is  definitely a 'work in progress', so it's messy right now. Here's what I've figured out so far.

I feel like I'm missing something obvious.. Thanks to anyone who answers!

 

 

    public class BounceGame : Microsoft.Xna.Framework.Game
    {
        public static GraphicsDeviceManager Graphics;
        public static SpriteBatch SpriteBatch;

        public BounceGame()
        {
            Graphics = new GraphicsDeviceManager(this);
            Graphics.PreferredBackBufferWidth = 800;
            Graphics.PreferredBackBufferHeight = 480;
            Window.Title = "Project Bounce";
            Graphics.ApplyChanges();
            Content.RootDirectory = "Content";
        }

        public static World World;
        public ObjectCreator ObjectCreator;
        public DebugViewXNA DebugViewXNA;

        protected override void Initialize()
        {
            r = new Random();
            ObjectCreator = new ObjectCreator(this);
            World = new World(new Vector2(0, 1.25f));
            DebugViewXNA = new DebugViewXNA(World);
            KeyBoardState = new KeyboardState();
            base.Initialize();
        }

        SpriteFont font;
        protected override void LoadContent()
        {
            SpriteBatch = new SpriteBatch(GraphicsDevice);

            DebugViewXNA.LoadContent(GraphicsDevice, Content);
        }

        protected override void Update(GameTime gameTime)
        {
            KeyBoardState = Keyboard.GetState();
            HandleInput(gameTime);
            World.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            

            SpriteBatch.Begin();
            DebugDraw();
            SpriteBatch.End();
            base.Draw(gameTime);
        }

        protected void DebugDraw()
        {
            Matrix transform = Matrix.Identity * Matrix.CreateScale(GraphicsDevice.Viewport.Height / ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height))
                                    * Matrix.CreateScale(1,-1,1)
                                    * Matrix.CreateTranslation(GraphicsDevice.Viewport.Width * .5f, GraphicsDevice.Viewport.Height * .5f, 0f);
            

            Matrix IDMatrix = Matrix.Identity;
            DebugViewXNA.RenderDebugData(ref transform, ref IDMatrix);
        }
    }

 

May 25, 2011 at 8:24 AM

I set up debug drawing some time ago so I can't remember exactly but I have this vague (perhaps wrong) memory of needing to create an orthographic projection matrix using Matrix.Ortho.

I'll post relevant code when I get back home and hae acess to my code, but you might want to look into that anyway :)

May 25, 2011 at 1:48 PM

Hope this helps:

 

Matrix proj = Matrix.CreateOrthographic(BaseGame.Get.BackBufferWidth / Camera.Get.WorldScale.X / 100.0f, BaseGame.Get.BackBufferHeight / Camera.Get.WorldScale.Y / 100.0f, 0, 1000000);
            Vector3 campos = new Vector3();
            campos.X = -Camera.Get.Position.X / 100.0f;
            campos.Y = Camera.Get.Position.Y / -100.0f;
            campos.Z = 0;
            Matrix tran = Matrix.Identity;
            tran.Translation = campos;
            Matrix view = tran;

            _debugView.RenderDebugData(ref proj, ref view);

Sorry I'm no tsure why I do half the things I do (such as the divide by 100.0f) but i know it works fine :)

May 25, 2011 at 2:41 PM
Edited May 25, 2011 at 3:21 PM

Hey thanks for the source code! it is useful, yes . . . except I'm not using a camera. What should I replace into those values?

I've been trying a few things that make sense, like using the center of the screen instead of a camera position.. but I can't seem to get it. working.

Thanks!

May 25, 2011 at 3:11 PM
Edited May 25, 2011 at 5:10 PM

Hi, it's OP again. I think I fixed it :D I turned off framing.Draw(), and I saw that DebugDrawXNA was rendering debug data underneath the background! That's why I couldn't see it. This is great, now I can visualize what's going wrong. Thanks, meds!

Now I just need to figure out why DebugViewXNA is rendering with a reversed Y axis, as you can see in my screenshot.

Here's how I changed it to work without a camera, for anyone reading this thread in the future. Note that this code is still broken like in the above screenshot.

 

Matrix proj = Matrix.CreateOrthographic(Graphics.PreferredBackBufferWidth / 1f / 100.0f, Graphics.PreferredBackBufferHeight / 1f / 100.0f, 0, 1000000);
            Vector3 campos = new Vector3();
            campos.X = (-Graphics.PreferredBackBufferWidth / 2) / 100.0f;
            campos.Y = (Graphics.PreferredBackBufferHeight / 2) / -100.0f;
            campos.Z = 0;
            Matrix tran = Matrix.Identity;
            tran.Translation = campos;
            Matrix view = tran;
            DebugViewXNA.RenderDebugData(ref proj, ref view);

EDIT: I fixed it :). Screenshot. It's simple really . . you just have to make your orthographic matrix with the negative of your buffer height.
Here's what that looks like:
Matrix proj = Matrix.CreateOrthographic(
                Graphics.PreferredBackBufferWidth / 1f / 100.0f,
                -Graphics.PreferredBackBufferHeight / 1f / 100.0f, 0, 1000000);

May 26, 2011 at 4:16 AM
Edited May 26, 2011 at 4:19 AM

What's the point of dividing by 1?

Also, for anyone who's using the camera from the Farseer samples. You can set up the debug view by doing this (3.3.1):

1) Add:

using FarseerPhysics.DebugViews;

2) Create a DebugView property for your screen class.

 

3) In the LoadContent() method, after you create the World object for your screen, create the debug view and set the options you want:

DebugView = new DebugViewXNA(World);
DebugView.AppendFlags(DebugViewFlags.Shape);
DebugView.AppendFlags(DebugViewFlags.DebugPanel);
DebugView.AppendFlags(DebugViewFlags.PerformanceGraph);
DebugView.AppendFlags(DebugViewFlags.Joint);
DebugView.AppendFlags(DebugViewFlags.ContactPoints);
DebugView.AppendFlags(DebugViewFlags.ContactNormals);
DebugView.AppendFlags(DebugViewFlags.Controllers);
DebugView.AppendFlags(DebugViewFlags.CenterOfMass);
DebugView.AppendFlags(DebugViewFlags.AABB);

DebugView.DefaultShapeColor = Color.White;
DebugView.SleepingShapeColor = Color.LightGray;
DebugView.LoadContent(ScreenManager.GraphicsDevice, ScreenManager.Content);
4) In your draw call, find the point when you want the debug stuff to draw (I do this last) and add these lines:

Matrix proj = Camera.SimProjection;
Matrix view = Camera.SimView;
DebugView.RenderDebugData(ref proj, ref view);

That worked for me and I'm pretty sure I pulled it from the examples.

May 27, 2011 at 4:16 PM
Edited May 27, 2011 at 4:19 PM

Good point Drackir, there's no point to divide by one. I was using it as a placeholder so I could better visualize my changes, but it was removed from my actual game.

I created a class that inherits Xna.Framework.GameComponent. It contains everything needed to draw DebugViewXNA data. Well, almost everything: I use my personal InputHelper class to check for a unique keypress when toggling flags.

DebugFarseer.cs

May 31, 2011 at 3:01 PM

In case anyone needs to use this with the addition of their own camera, I used the code above with a camera as follows:

// Assume you have a _camera object with Zoom and Position properties
Matrix projection, view;

// Projection (Scale)
float zoom = _camera.Zoom;
float width = (1f / zoom) * ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Width);
float height = (-1f / zoom) * ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height);
float zNearPlane = 0f;
float zFarPlane = 1000000f;
projection = Matrix.CreateOrthographic(width, height, zNearPlane, zFarPlane);

// View (Translation, Rotation)
float xTranslation = -1 * ConvertUnits.ToSimUnits_camera.Position.X);
float yTranslation = -1 * ConvertUnits.ToSimUnits(_camera.Position.Y);
Vector3 translationVector = new Vector3(xTranslation, yTranslation, 0f);
view = Matrix.Identity;
view.Translation = translationVector;

// Draw the Debug View
_physicsDebugView.RenderDebugData(ref projection, ref view);


 

Jul 12, 2011 at 9:13 PM

@Beringela,

How can I modify that code to make it rotate around the Z-axis? My camera has a 'Rotation' float, but I'm not sure how to modify this code so that it works with that.