-2
\$\begingroup\$

This is more a theoretical question,

during runtime, my game runs smooth without any hickups. But as standard game-objects, my game contains collectibles such as coins (which are rotating Models).

I can (again, during runtime) load 10 of those coins without getting any hickups. But as soon as I load 50 coins, the runtime freezes for some ticks and continues then.

How could I generally preload a 50-Coin case, so that the game has done all loading during load-time?

This is how I draw a single Coin (and every of those 50 get drawn like this)

public override void Draw(RenderContext renderContext)
{
    var transforms = new Matrix[_model.Bones.Count];
    _model.CopyAbsoluteBoneTransformsTo(transforms);
    foreach (ModelMesh mesh in _model.Meshes)
    {
        foreach (BasicEffect effect in mesh.Effects)
        {   
             effect.View = renderContext.Camera.View;
             effect.Projection = renderContext.Camera.Projection;
             effect.World = transforms[mesh.ParentBone.Index] * WorldMatrix;
        }
        mesh.Draw();
     }
     base.Draw(renderContext);
 }

How could I draw one Model in x: 10, x: 20 and x:30 (with the other values like Y,Z or scale untouched) for instance?

\$\endgroup\$
8
  • 6
    \$\begingroup\$ Why are you loading 50 coins? Why are you not loading one coin and reusing that one coin each of the 50 times? \$\endgroup\$ May 3, 2013 at 21:20
  • \$\begingroup\$ How should I do that? I have a row of coins, I need to have 50 coins in different locations \$\endgroup\$
    – IMX
    May 4, 2013 at 13:50
  • 5
    \$\begingroup\$ Read up on matrices and transforms. \$\endgroup\$ May 4, 2013 at 13:52
  • 3
    \$\begingroup\$ @IMX: I see some code, but I don't see why you can't render the same mesh in different places. \$\endgroup\$ May 7, 2013 at 13:50
  • 3
    \$\begingroup\$ riemers.net/eng/Tutorials/XNA/Csharp/Series3/… - start with the section beginning "Imagine you want to draw 2 objects from the same mesh" (this should be a familiar page as you seem to have copy/pasted your code from it). \$\endgroup\$ May 7, 2013 at 13:58

2 Answers 2

4
+50
\$\begingroup\$

Upon creation of a coin, do you load the model/texture from disk every time? This would make loading extremely slow. Creating a coin object without disk IO should generally be very, very fast. If that's not the case, try looking at object pools.

Wikipedia:

A pool in computer science is a set of initialised resources that are kept ready to use, rather than allocated and destroyed on demand. A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished with an object (or resource), it returns it to the pool, rather than destroying it.

Create a coin pool upon loading a level/the game, then use and put coins back as necessary.

Edit: For a more thorough explanation, see this post.

\$\endgroup\$
0
13
\$\begingroup\$

You don't need 50 or 10 or even 2 copies of a model. You don't need to pool them, either (though pooling the objects they represent may be worthwhile).

You need one model, and you need 50 instances of it. For each mesh in your coin model, you draw that mesh at 50 locations. For simple, repeated models, it makes much more sense than drawing each mesh for each model location.

The bounty for more details edit:

The reason you aren't getting sufficiently detailed answers is that the solution to your problem is too extensive for a single answer. Your posted code is the out-of-the-box, tutorial method for drawing a model, and it simply doesn't work for drawing a large number of models. As a matter of expert opinion, the Model class itself isn't good for drawing a lot of models (or anything else).

So you want to draw a lot of models anyway. Fine, but you need to drastically change your code. Here's a shortened list:

  • Load the model differently
  • Handle its meshes individually
  • Manually store individual transforms that represent models
  • Manage those transforms into batches of the correct size for your hardware (the sample below has compiler directives for the differences between the 360 and the PC)
  • Make an extra graphics buffer to hold the transforms
  • Create a shader to handle both buffers
  • Draw your model in a completely different loop

Easy, right? NOPE! It's a complete overhaul; far beyond the scope of your current Draw() method. No one can give all that code in a detailed answer. But luckily for you, no one has to. You just have to download and study the example project below.

End edit. Begin solution to drawing lots of models.

The XNA instancing example puts together the technical details of whole process. The purpose of this example is to demonstrate the terrible loss of performance from drawing one model at a time in XNA. The example can draw thousands of models at 60fps, or choke on only a few. Screenshot:

enter image description here

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .