Debug view, cameras and textures (not strictly physics related, but...)

Topics: Developer Forum, User Forum
Jul 2, 2010 at 12:13 PM
Edited Jul 5, 2010 at 6:25 AM

Hi, I know this is not an issue strictly related to the physics engine, but I'll ask anyway because I know that here there are brilliant minds always willing to help :PBy the way, I'm using FP3.0.

This has been discussed before, but I still haven't found what I'm looking for (U2's music in the background)... wel I still haven't found what I needed.

I'm trying to use RogueCommander' fantastic camera class along with the debug view. Of course my first attempt was a failure. I did the following (tw and th are the screen width and the screen height):

 

 

// RogueCommander's 2D camera
camera = new Camera2D(new Vector2(tw, th),
    new Vector2(0, 0),
    null,
    null,
    null,
    1f,
    null,
    null,
    null,
    null,
    null);

Matrix camera2DProjection = Matrix.CreateOrthographicOffCenter(0,
 	tw,
 	0,
 	th,
 	0,
 	1);
Matrix cameraMatrix = camera.CameraMatrix;

// This is the farseer's debug view
debugView.RenderDebugData(ref camera2DProjection, ref cameraMatrix); 
screenManager.SpriteBatch.Begin(SpriteBlendMode.AlphaBlend,
	SpriteSortMode.Immediate,
	SaveStateMode.None,
	camera.CameraMatrix);

// Draw stuff in their body's position
screenManager.SpriteBatch.End();

 

 

But everything in the debug view was upside down... and tiny. The upside down part was logical, as the Y coordinates in the world are inverse than in the screen, so I changed my camera2DProjection matrix to:

 

camera2DProjection = Matrix.CreateOrthographicOffCenter(0,
	tw,
	th,
	0,
	0,
	1);

 

Changing the lower Y value reversed everything, but still it was too tiny. So I went to see the code in the sample code for zooming and then, based on it, changed my camera2DProjection to:

 

float ratio = tw / (float)th;

Vector2 extents = new Vector2(ratio * 10f, 10f);

Vector2 screenCenter = new Vector2(tw, th) / 2;

Vector2 lower = screenCenter - extents;
Vector2 upper = screenCenter + extents;

camera2DProjection = Matrix.CreateOrthographicOffCenter(lower.X,
	upper.X,
	lower.Y,
	upper.Y,
	-1,
	1);

Aaannd, yay! It worked, now the debug view was at a decent size, and when moving my camera to track the main character it followed it great. The problem now is when I want to apply textures to each body. See, The world scale is not the same of the camera scale (I'm just drawing things bigger), so the textures don't follow the objects at the same ratio when the camera moves (and the textures don't match the objects positions). So now I have to figure how to arrange this. I don't want to scale the objects to bigger ones, because I read somewhere that I should keep the units small, so I don't want to have a main character 50ft tall moving around just for avoiding zooming the camera or the projection. So... how do you people draw your stuff in Farseer 3.0? Any ideas? Can anyone help me?

 

Jul 3, 2010 at 6:20 AM
Oh my, this is what I chose to work on this weekend. It was also driving me nuts (the camera matrices, especially with the new DebugView from FP3). Where is RobertDodd's camera class? I can only find RogueCommanderIX's. I'd love to help, but I'm further behind than you in understanding the camera.
Developer
Jul 3, 2010 at 9:11 PM

Hey guys,

Check out this post from Shawn - http://blogs.msdn.com/b/shawnhar/archive/2010/04/05/spritebatch-and-custom-shaders-in-xna-game-studio-4-0.aspx

If you want to use SpriteBatch with a custom camera you'll need to upgrade to 4.0.

Or write your own code to render quads how you see fit.

Jul 3, 2010 at 10:13 PM
Edited Jul 4, 2010 at 3:40 AM
Thanks mattbettcher. I just looked at Xna 4 a couple nights ago and decided not to update since I have no idea when you can start deploying to xbox (3.1 games aren't even supported to release until the end of this month, so who knows how long it will be until 4), and it appears it is for Windows 7 phones and that xbox is an afterthought so far. I didn't find mention of Windows either. I'm not sure I want to move to xna 4 just yet. P.S. I'm still developing mainly on XP.
Jul 4, 2010 at 10:54 AM

I'm sure you mean RogueCommander's camera class, not mine! :D

Developer
Jul 4, 2010 at 6:31 PM

Jerky,

I can send you a copy of my work in progress QuadRenderer if you like. It's very much like SpriteBatch, except it accepts projection and view matrices. Right now it is missing texture mapping and a few features such as flipping and custom effect support. I know texture mapping is a huge thing to be missing, it's ready to be added in, I just haven't gotten to it yet. But you could at least see how to write a QuadRenderer. Let me know and if your interested I'll post it up.

Matt

 

Jul 4, 2010 at 6:39 PM

@jerky Sorry, I meant RogueCommander's camera class as RobertDodd said :P 

@matt The problem I have is I use also Mercury Particle Engine and a class for dynamic 2D shadows that uses spritebatch for rendering them, so I don't know if they would work with a custom quad renderer (sorry, I quite ignorant about graphics programming). Any idea if they could "get along"? Plus, I'd love to see your class too :)

Developer
Jul 4, 2010 at 11:11 PM

Here you go Pnikosis http://www.mediafire.com/?sharekey=f7bed25ee7c5f54d9bf8d6369220dcab44dcc3020fd787e264328c9cace34742

I couldn't tell if they would "play well together", but I'm betting they would.

Please remember it isn't finished yet. I'll probably post a new discussion once it's done with a demo showing how to use it.

Jul 5, 2010 at 6:24 AM
Thanks Matt! I'll check your code to see how it works while waiting the thread when it's finished :)
Jul 5, 2010 at 11:32 AM
Hi Matt, me again, I think the IMaterial interface is missing :$
Jul 6, 2010 at 6:33 AM
Edited Jul 6, 2010 at 6:34 AM

Thanks Matt. I noticed that too Pnikosis. I think he knew that, and just wanted to show us what a quad renderer looks like.

I have been reading about graphics programming (and with Matrices specifically) and noticed a few things. The old PhysicsSimulatorview used spritebatch, while the new DebugViewXNA uses your effect.Begin (which is shader based, and therefore needs a quad renderer). Does that sound correct? If so, is there a benefit to this new approach versus the older SimulatorView which used spritebatch? I am seeing a whole new layer of complication due to this change. Is there any reason why I couldn't rewrite the DebugViewXNA to use spritebatch instead? Keep in mind that I also am fairly noobish when it comes to graphics programming. I have learned a lot this weekend, but still have a ways to go.

I was able to get the DebugViewXNA to view very similarly to my Camera class, but they don't quite match because it doesn't want to accept my tranformation matrix the same way my draw method does. I believe it is possible with the right math, but that is going to take me a while to get the hang of it.

Jul 6, 2010 at 4:32 PM

I feel pretty dumb for even commenting on this because some of the stuff you guys talk about is way beyond what I know but I currently have the DebugViewXNA working with RogueCommander's camera class. It takes into account zoom, simulator scale, and positioning. I could pass on what I did if you want. I have a video on youtube of it. I didn't optimize it at all though so it looks pretty crappy. Forgot as well to change FPS of recording which messes with it but you'll get the jist of it. Here it is: http://www.youtube.com/watch?v=rcS_IIeQTFk

Developer
Jul 6, 2010 at 10:19 PM

Sonic - post up that code I helped you with so everybody can see basically how it's done.

Pnikosis & Jerky you shouldn't need IMaterial. You can just change that to Texture2D. I made an interface because I wanted to render many different types of materials such as Video and Diffuse with Normal mapping.

Jerky - everything is shader based in XNA. SpriteBatch just hides all the gory details of rendering Quads. My class is very similar to SpriteBatch so if you study the code closely you can hopefully get a good idea of how it works.

Some recommendations I can give you guys for graphics programming are -

  • Learn what Matrix's do, not all the complicated math that's needed to use them, you can learn that later.
  • Learn about VertexBuffers, IndexBuffers, and how to create, set, use, etc. this is the key to  mastering your graphics card.
  • Learn how shaders work, not how to program them, you can learn that after you know the flow of data from your code through the graphics card and to the display.
  • When trying to learn something new, create a new project and figure out how to do it in a very simple demo. This will boost your productivity because you won't have to  question any of the code in your game/engine while figuring out how something works. Once you know how something works plugging in the code to your game/engine will be simple, hopefully ;)
  • Learn good programming techniques. Interfaces, Lambda Events, Linq, Properties, Fields, Code organization etc.
  • Stay positive and never give up! I am completely self-taught. Never had more then a typing class (until recently I started college to make my knowledge legit)

Please don't take anything I've listed as a personal attack or anything. I love getting to see your guys code and love to help out.

Jul 7, 2010 at 5:11 AM
Edited Jul 7, 2010 at 5:14 AM

Thanks again Matt. I've come a long way in the past 4 days. I got my *almost* working as good as sonic4305, but not quite. It all has to do with calculating the Matrices properly and understanding what they do, like you said. Your advice is very good, and we appreciate your input. I had a suspicion that SpriteBatch was shader-based, but found the documentation lacking for someone who knew nothing of graphics programming going into this, especially regarding Matrices. That being said, with the proper search terms in google, the knowledge is out there, I just hadn't found it yet, and my brain wasn't ready to learn it yet.

sonic4305, I would love to see your implementation. I have my own Camera class, but I may throw it out and put in RogueCommanderIX's.

Jul 7, 2010 at 4:29 PM
Edited Jul 7, 2010 at 4:30 PM

I'll put up everything that Matt gave me and then just point out what each value is for.

 

This would be in your LoadContent method.

 

            DebugViewXNA.LoadContent(graphicsDevice, content);

            debugView = new DebugViewXNA(Farseer.World);
            debugView.AppendFlags(DebugViewFlags.Shape | DebugViewFlags.CenterOfMass | DebugViewFlags.AABB);

 

 

This is the actual drawing.

 

            debugView.DrawDebugData();
            Matrix view = Matrix.CreateTranslation(camera.Position.X / -100f, camera.Position.Y / -100f, 0);
            Matrix projection = Matrix.CreateOrthographicOffCenter(-screenSize.X / 2f, screenSize.X / 2f, screenSize.Y / 2f, -screenSize.Y / 2f, 0, 1);
            debugView.RenderDebugData(ref projection, ref view);

 

 

Matt got these two things for me. The random -100f in the view Matrix is my unit conversion from pixels to meters. Also screen size is the backbuffer width and heights. This will work fine if you keep your zoom at 1 at all times but I added one little change to get that into account. The camera is your Camera2D object that you are using.

 

            debugView.DrawDebugData();
            Matrix view = Matrix.CreateTranslation(camera.Position.X / -100f, camera.Position.Y / -100f, 0);
            Vector2 size = new Vector2(screenSize.X, screenSize.Y) / 2f / camera.Zoom;
            Matrix projection = Matrix.CreateOrthographicOffCenter(-size.X, size.X, size.Y, -size.Y, 0, 1);
            debugView.RenderDebugData(ref projection, ref view);

 

All I did was move everything to a Vector2 called size. It divides it by whatever the camera zoom currently is. That's all I had to really edit. Thanks again Matt for helping me out in the first place to get the view working and hopefully this will help out anyone else :)

 

 

 

 

Jul 12, 2010 at 7:01 AM
Edited Jul 12, 2010 at 7:02 AM
Thanks a lot Matt... also Sonic and Jerky... I'll try to learn a little more on graphics programming, but I reached a point that I hardly have time for going deeper in some topics, maybe I should consider to stop addign features and finishing my project :P
Jul 12, 2010 at 7:55 AM
No worries Pnikosis. Time is always the beast we fight. I was able to get this working for me, although it didn't look exactly like sonic's code. The code I had already written was closer to the end product than what sonic put here. That being said, this was an extremely helpful discussion. I'm sure we'd be willing to help you iron this out if we saw some of your draw code. It all ends up coming down to your scale and so forth.
Oct 8, 2011 at 2:57 PM

Man... thanks a lot for Sonic, Matt and Jerky.... I have beating my head with this inversion issue for hours ..... and I am not using the camera...maybe I will soon... but thanks a lot for putting this code up... saved me sleepless nights.. cheers.