Another one about drawing textures

Topics: Developer Forum, User Forum
Dec 15, 2010 at 7:42 PM

Hi , I´ve been testing the engine for two days now, so sorry about asking about textures again. 

I know Farseer doesn´t handle textures at all, so I am lost here. How can I draw my textures (pngs) using the engine dynamics? Should I draw them in my main Draw(), using the coordinates of objects created in Farseer world?

Thanks a lot.

Coordinator
Dec 15, 2010 at 7:51 PM

Where you call Draw() is up to you.

The easiest thing for you is to create a camera class that scales the world to screen coordinates. Farseer Physis Engine works with meters and screens work in pixels, so you have to scale between the two units. For that you can use the Matrix class as seen in countless camera posts on the internet. (FPE 3.2 will also have an easy to use Camera class in the samples.)

When you draw a texture using the SpriteBatch, you simply supply it with your transformation (scale) Matrix and it automatically takes care of the scaling for you. Then you just need to supply the SpriteBatch with the position and rotation of the body from the physics World. - It is easier than you might think.

Dec 15, 2010 at 10:18 PM

Ok, thanks for your reply...  So this is the right approach, right? I create the body in Farseer with the bounds of my Image to check for collisions and to process the dynamics. ok.

I create a Rectangle fixture to represent the floor in my game, and draw the floor in the exact position of the body, in my Draw function, right? But the Farseer engine will draw the rectangle automatically on the screen. How to avoid the rectangle drawing? Sorry about these annoying questions, but I am still understanding the whole concept.

Developer
Dec 16, 2010 at 3:21 AM

Actually Farseer will never ever draw anything ;)

I assume you are using the debugView? If so then well it is just that, a debugView to quickly visualize what is going on so that you can test your physics setup. Just throw it out of your Draw() method and Farseer won't draw anything. Then you just step the world in your Update() method and draw your own graphics, by reading the positions and rotations from the bodys added to the world.

Dec 16, 2010 at 7:27 PM

Sure! That was what I couldnt understand...  Who was drawing all that stuff.....

Thanks a lot for your replies.

Dec 16, 2010 at 10:06 PM
Edited Dec 16, 2010 at 10:11 PM

....

Ok. I took off base.Draw() from my Draw() method (i assume that´s the way to avoid debugview from drawing, right?), it works. I have only my texture on the screen. Two issues:

1. I tested the program without the World.Step() in my Update(), and it still works . Maybe I am not disabling something from debugview yet?

2. When I left click and drag the mouse anywhere on the game screen without calling base.Draw() I get a long text exception, can´t even read its details. When base.Draw() is on it works fine, I can throw my object by dragging it. I think it´s still something debugview is automatically handling for me, right? 

Sorry, i am still very confused with how things relate to each other in Farseer.

Developer
Dec 17, 2010 at 2:28 PM
Edited Dec 17, 2010 at 2:31 PM

Again I think you are confusing Farseer (the physics engine) with our Demo/Samples framework. I suggest to have a look at the HelloWorld sample. You do not need to incorporate the DebugView nor the DemoBaseXNA classes in your project at all. Just comment out "_debugView.RenderDebugData(ref proj, ref view);" in the HelleWorld sample's Draw() method and you won't see anything anymore ;)

Then try to add your own drawing code there.

I have to guess here, but i think you are using the physicsgamescreen class from DemoBaseXNA? That is not really part of Farseer and the physics engine itself, but rather part of a (more or less complex) framework that uses the engine to showcase its features. base.Draw() however has also nothing to do with the debugView in particular. It just calls the Draw method of the base class which happens to contain the draw code for the debug view... among other things, that you don't just want to cut out.

I'd really encourage you to start with the HelloWorld sample and just use the other samples and the testbed as a reference on how certain physics things are done.

Dec 17, 2010 at 2:47 PM

Ok. I´ll try the Hello World, thanks a lot for your answer.

Dec 18, 2010 at 7:12 PM

Ok, Now I understand the concept of DebugView and what should/should not be in Draw() method. I saw the article about scalling and it says:

float horScaling = (float)device.PresentationParameters.BackBufferWidth / baseScreenSize.X;
float verScaling = (float)device.PresentationParameters.BackBufferHeight / baseScreenSize.Y;
screenScalingFactor = new Vector3(horScaling, verScaling, 1);
Matrix globalTransformation = Matrix.CreateScale(screenScalingFactor);

I used the circle 
_circleFixture = FixtureFactory.CreateCircle(_world, 2, 1, new Vector2(10, 10));
created in the HelloWorld to represent a 64x64 circle Texture I´ve created.
globalTransformation goes in spriteBatch.Begin(), got it. One question now, what values should I put in baseScreenSize?

Developer
Dec 21, 2010 at 10:26 AM
gerotica wrote:

[...] One question now, what values should I put in baseScreenSize?

That is up to you. If you set a "constant" value like 50 your coordinate system will range from 0 to 50 and depending on your resolution 1 unit may cover more or less pixels. So basically your graphics always cover the same portion of your screen. If your resolution is fixed anyway you can calculate your baseScreenSize.

Just take your resolution, divide it by 64 and you get your baseScreenSize.

For a resolution of 1920x1080 you'd get:

baseScreenSize.X: 30

baseScreenSize.Y: 16,875

...for example.