Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# XNA low frame rate

Ok, I have 80,000 "Box" Mesh with simple textures I have set a view distance and only draw the ones you can see which leave 600 to 1000 for the DrawModel function belowe The problume is I only get 10 frame per second and my view distance is crappy Also, I have done memory test to all my code and the "mesh.draw()" takes 30 Frame per second off. nothing else take NEAR that much. Any help?

        private void DrawModel(MeshHolder tmpMH)
        {          
            Model tmpDrawModel = (Model)_Meshs[tmpMH.MeshFileName];
            Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];
            tmpDrawModel.CopyAbsoluteBoneTransformsTo(transforms);
            foreach (ModelMesh mesh in tmpDrawModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {

                    effect.LightingEnabled = false;

                    effect.TextureEnabled = true;
                    effect.Texture = (Texture2D)_Textures[tmpMH.GetTexture(Count)]; 



                    effect.View = _MainCam.View;
                    effect.Projection = _projection;
                    effect.World =
                         transforms[mesh.ParentBone.Index] *
                        Matrix.CreateFromYawPitchRoll(tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z) *
                        Matrix.CreateScale(tmpMH.Scale) *
                        Matrix.CreateTranslation(tmpMH.Position);
                }

                    mesh.Draw();               
            }
        }
like image 887
codegreen Avatar asked Jun 02 '11 19:06

codegreen


1 Answers

What is killing your performance - as you say - is ModelMesh.Draw. When you draw models, it works like this:

for each frame
  for each Model
    for each ModelMesh // you call Draw(), which does:
      for each ModelMeshPart
        for each Effect
          for each EffectPass
            Draw some triangles // sends a batch of instructions to the GPU

So the question is: how many times each frame are you sending a batch to the GPU? Because you can only send a few thousand* batches per frame before you saturate the CPU - hitting the "batch limit". (Each batch uses up CPU time in the graphics driver - it also uses some bandwidth and GPU time, but CPU time dominates.)

You may want to read this answer and this answer and this slide deck for additional information.

The solution is to modify your scene (eg: combine some mesh parts, do some culling, add instancing support) to reduce the number of batches you are sending to the GPU.


Also, try to avoid things like this in your Draw and Update loop:

Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];

You should really do your best to avoid memory allocations that happen each frame - as they will eventually cause an expensive garbage collection and potentially a frame-rate hiccup (especially on Xbox). Try to store your buffer somewhere and reuse it.

like image 181
Andrew Russell Avatar answered Sep 28 '22 06:09

Andrew Russell