BDev13

 

I'm building a 3D game and currently have everything working, but I'm in the process of optimizing my framerate.  The world in the game is many times larger than the screen/window. 

How would I go about determining the world coordinates that are visible on the screen  

Even though the objects outside of the viewport are clipped, the draw code still has to translate (and rotate) the meshes in the objects (many of which will be clipped).  It would be much more efficient if I could just not process meshes that will be outside of the screen. 

Thanks!

 



Re: XNA Framework How Do I Determine The Currently Visible Area?

Darkside

The best and most used practice for efficient management of the viewport contents is to use a tree structure of some kind to manage the arena, in which the camera bound to the tree only returns th area in view to update.

Best example of this can be found on codeplex using a Quadtree structure (the developer also has an octree space example as well)

You can also check out references on Wikipedia and gpwiki.org

Hope this helps

Darkside






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

Thanks. I took a quick look and it looks like what I need.



Re: XNA Framework How Do I Determine The Currently Visible Area?

Darkside

Thanks, if it is the answer please mark it as such to help others!

Darkside






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

Darkside,

That was the solution, but I just verified that it was a few minutes ago (Had a chance to put the ideas to code).

My framerate is several times greater than it was before. For anyone reading this with similar issues, here are the changes I made:

1. In my game.Draw() method, I now calculate the view and projection matrices once per frame instead of once per mesh (the Microsoft examples do it once per mesh). The projection matrix really only needs to be updated when the aspect ratio changes and I may move it later. This change increased my framerate by a factor of two.

//*** Update view and projection matrices
Matrix viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget,
Vector3.Up);

Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
aspectRatio, 1.0f, 10000.0f);

2. In my game.Draw() method, I calculate the view frustum:

//*** Calculate view frustum
BoundingFrustum viewFrustum = new BoundingFrustum(this.viewMatrix * this.projectionMatrix);

3. In my game.Draw() method, for each model I need to draw, I first check to see if it is contained in the view frustum. I currently have two simplifications in place that others may need to expand on for their project:

(a) I don't consider each mesh in the model invdividually to determine if it is inside the view frustum. I construct a bounding sphere that is big enough to contain the entire object which will cause a bit more drawing than would be required if I clipped at the mesh level.

(b) I have not utilized a quadtree (or other structure) to more efficiently partition the model/mesh space. I traverse and consider my models linearly which gives me an algorithmic complexity of O(n). In my application, I don't have a huge number of objects so I'm getting away with this for now. I may need a quadtree later.

Even with these simplifications this change increased my framerate by another factor of 2 or 3.

//*** Draw floors
foreach (Floor floor in this.floorList)
{
BoundingSphere bs = new BoundingSphere(floor.getLocation(), Floor.getFloorWidth()/2.0f);

if (!viewFrustum.Contains(bs).Equals(ContainmentType.Disjoint))
{
floor.Draw(viewMatrix, projectionMatrix);
}
}





Re: XNA Framework How Do I Determine The Currently Visible Area?

thedo

You can probably increase your performance more by creating your bounding sphere once for each "Floor" and simply updating its position if needbe. This will not only save you time allocating memory, but also allow the GC to be less active, by giving it less data to clean up.

Neil






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

Neil,

Thanks.

You're absolutely right.  I can probably do the same for several other types of objects that don't move during the course of a given level (walls, power ups, etc).

Just by making these few changes, my framerate has increased so much that I found that I have to slow down my character's prescribed speed to make it easer to control...

 





Re: XNA Framework How Do I Determine The Currently Visible Area?

thedo

If your having to alter the characters speed because youve increased then framerate then you might want to re-analyse your code.

For example, if you put your move logic in the Update call (in Game or a game component), then (using the default behaviour of XNA) the call will be made 60 times per second regardless of your framerate. For example in my game the main character has a default speed of 1 in whatever direction they are travelling, and this is added only in the update. If i did this in the draw call I would either have a game which ran fine on my system, but too fast/slow on someone elses machine, or have to write code which determined what fraction to use to determine the speed based on how much time passed since the last frame. Putting this code in Update eliminates the need for either of those and keeps your game neater too ;)

N






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

N,

Thanks for the suggestions.

I already had the call to check for user input and to move the player character in Update(). I was already updating the player position based on time (an if statement that checked the current time vs the last time moved and compared the difference to a threshhold value). So, I already had code in place to move the player a certain distance per time unit which should keep the speed constant regardless of computer speed.

The problem that I guess I was having was the the frames rendered between the player moves were taking longer than the alloted frame time (1/60th of a second) which was causing the frames to "slide right" in time and thereby increase the delay between the frames where the player moved (I'm assuming that XNA doesn't skip frames when it's not keeping up), which had the net effect of the player moving slower (on a per second or per time unit basis). Once the frame took less time and the program was keeping up, the player movement reverted to "correct functionality" which ended up being too fast.





Re: XNA Framework How Do I Determine The Currently Visible Area?

Darkside

Yes, thats a usual problem when overcompensating for speed issues, glad to have helped. using a frustrum to pre-cull the view port is certainly an impressive idea, i'll have to keep that one in mind for the future.

Probably a combination of the two would be very usefull, i.e. use a tree for the static elements (walls, power-ups etc.) and a frustrum for the active models, trees get complicated and bad for dynamic moving content and are best suited for things that do not move due the probelms of moving content with in the tree.

There is a lot of content on gamedev.net on this and some links to articles about th problems.

Hope everthing goes well for you and we get to see your game!!, make sure you let the forum know when you got it rady to show and share!!

Darkside






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

Darkside,


Thanks again for the assistance. 

I'm pretty much finished with the game. The game is a 3D version of a game I coded as a kid back in the early 80's for the Atari computers (Ah, the days of Basic and Assembly Language (via USR(1536)) on 8 bit processors).

 I have a few more levels to design but they won't take very long (I built a quick and dirty level editor using Excel and Visual Basic For Applications to generate level files read by the game).  I offered to let my wife design one of the levels and she's dragging her feet (My kids designed one each).

I have the game running on both Windows and XBox 360.  Once the final levels are finished, I'll just need to figure out where to put the source for the game so everyone can access it... 

 

 





Re: XNA Framework How Do I Determine The Currently Visible Area?

Darkside

If your looking for somewhere to upload your game, Derek who runs threesixbox , happily hosts published games for XNA.

Get it uploaded and post a sticky to the forums!

have fun
Darkside






Re: XNA Framework How Do I Determine The Currently Visible Area?

BDev13

Darkside,

I posted the project to the site you recommended. The game/project is named Snake.

http://www.threesixbox.com/project/ id=f580fc1536

Let me know what you think.  I'll also post a link to the game in the sticky thread at the top...





Re: XNA Framework How Do I Determine The Currently Visible Area?

Darkside

Just checked it out, fantastic work and from such a simple game model.

Put a comment on the threesixbox site about it!.

Only recommendations I've got at this moment is that it could do with some flutter or annimation in the background or enemies to avoid.

Also include options for altering the difficuly or speed (Give it an EXtreme mode for the nutters, fly at 100 mph!)

Great job

Darkside