0

This ought to be XNA's bug.

I have two 3d models, currentModel and nextModel and I would like to apply special effect on these two models, to say morph one to another.

Code:

void DrawModelMorphing(Model currentModel, Model nextModel)
{    
    int targetIndex = 0;
    foreach(var mesh in currentModel.Meshes.Count)
    {
        foreach(var mp in mesh.MeshParts)
        {
            GraphicsDevice.Indices = mp.IndexBuffer;

            VertexBufferBinding[] vertexBufferBindings = new VertexBufferBinding[2];
            vertexBufferBindings[0] = new VertexBufferBinding(mp.VertexBuffer, mp.VertexOffset);
            vertexBufferBindings[1] = new VertexBufferBinding(nextModel.Meshes[targetIndex].MeshParts[0].VertexBuffer, nextModel.Meshes[targetIndex].MeshParts[0].VertexOffset);

            GraphicsDevice.SetVertexBuffers(vertexBufferBindings);


            mEffect.CurrentTechnique.Passes[0].Apply();

            GraphicsDevice.DrawIndexedPrimitives(
            PrimitiveType.TriangleList,
            0,
            0,
            mesh.MeshParts[0].NumVertices,
            mesh.MeshParts[0].StartIndex,
            mesh.MeshParts[0].PrimitiveCount);

            //vertexBufferBindings[0].VertexBuffer.Dispose(); //exception 
            //vertexBufferBindings[1].VertexBuffer.Dispose(); //exception 


        }
    }

    targetIndex++;
    }

}

GraphicsDevice.SetVertexBuffers will cause serious memory leaks, 300MB in 30 minutes, then "Out of Memory"

Here is one similar issue on different function call: OutOfMemory Exception when drawing cube

Something I had tested:

1) Event if I define vertexBufferBindings[] globally, problem remains.

2) If I dispose the the vertex buffer, there will be exception. "A first chance exception of type 'System.ObjectDisposedException' occurred in Microsoft.Xna.Framework.dll"

3) GC and some 3rd party tool like freeMem will not work too.

Can anyone help on this?

I nearly want to give up using XNA in my project.

Thanks.

Edit:

The solution is to cache everything that I needed, eg: VertexBuffer and Textural

Community
  • 1
  • 1
Steven Du
  • 1,681
  • 19
  • 35
  • I tried to fix your code formatting, but it seems you have `targetIndex++;` outside both of your loops. Maybe it's causing this? – user1306322 Jan 06 '13 at 17:29
  • Hardly. IndexOutOf BOund exceptions... you know... they are thrown. But creating new Indexbuffers without disposing them - that creates that. – TomTom Jan 06 '13 at 17:36
  • Have you tried using a "using" statement for both the vertexbuffers? – Deukalion Jan 06 '13 at 21:26
  • Also, why are you just not defining a method that can draw both models with a more modular method? Why draw one model and in that loop draw the other model (nextModel)? Why are you breaking the foreach loop? If you don't want to loop through all the meshes, use a different method altogether. – Deukalion Jan 06 '13 at 21:35
  • @Deukalion Yes, I tried the using to dispose, then I will get "dispose" exception .. – Steven Du Jan 06 '13 at 23:05
  • @user1306322 thanks for fixing format. Now I give the method name in the code. – Steven Du Jan 06 '13 at 23:09
  • @Deukalion I need to draw two together because the "effect" requires two models to work. I will remove the "break".. :) – Steven Du Jan 06 '13 at 23:22
  • Yes, calling a dispose on the VertexBuffer in the model will cause an exception because you will remove the buffer from the model and thus you can only render it once without problems. – Deukalion Jan 07 '13 at 18:23

1 Answers1

1

Do you ever call DISPOSE on those elements you allocate? If not - no, sorry, device memory is unmanaged, the corresponding classes must implement IDisposable and you must clean up.

If you assume the GC helps, exactly this happens.

TomTom
  • 61,059
  • 10
  • 88
  • 148
  • I tired vertexBufferBindings[0].VertexBuffer.Dispose(), but it gives System.ObjectDisposedException' – Steven Du Jan 06 '13 at 23:24
  • Tehen fix it. Sorry, you have your pointer, I am not here to use my crystal ball to look at your exact error message and figure out how the code - which I do not know and do not want to know - is going wrong. Fact is, you are not disposing SOMETHING so it eats non-managed memory. Maybe it is something else in your code that you do not dispose. – TomTom Jan 06 '13 at 23:26
  • Maybe yo just apply a memory profiler and look which objects ar in memory - if some of those have large unmanaged references, there you go. – TomTom Jan 06 '13 at 23:26