efficient mesh management?

Started by
14 comments, last by Ariste 14 years, 9 months ago
Hi, So i have my Mesh Objects of (semi-pseudo code):

class MeshObject {

    LPD3DXMESH mesh;

}

MeshObject meshes[10];


and my function to load a mesh to it

void loadMesh() {

        LPD3DXMESH mesh;
	LoadMeshFromFile(&mesh, "test.x");

        for(int i=0; i<10; i++)
	     meshes->mesh = mesh;


}


So i wonder if adding the same mesh to each object will increase the meshes in memory? Should i use LPD3DXMESH *mesh; in my object class instead? Also will directx load the same file each time? I mean my function is telling it to, but does it really do it?
Advertisement
LPD3DXMESH is already a pointer LP is the give away. So you're already store it as a pointer. So assinging it to each mesh object as you did is only making a reference to the mesh. It is only loaded and stored 1 time. Since you called Load 1 time, and are only copying references, not the mesh data.

This means though, that if you call meshes[0]->mesh->doSomething(), that it will effect all the other meshes, since they are the same mesh.
that looks very good and useful

i have thought about keeping my meshes in a vector before

but what do i have to include to make it work?

my compiler stops at the first line.

i have already included <vector>

I'm sorry, i thought my original post was off track so i removed the code, here it is again, you'll need

#include <vector>
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>


I wrote this very quickly, so it's untested, may not compile, and may be entirely useless/flawed.

std::map<std::string, boost::shared_ptr<Mesh> > meshes;std::vector<boost::shared_ptr<Mesh> > meshInstances;boost::shared_ptr<Mesh> LoadMesh(const std::string &path){  std::map<std::string, boost::shared_ptr<Mesh> >::iterator it;  it = meshes.find(path);  if (it == meshes.end()  {    //mesh not loaded yet    it = meshes.insert(std::pair<std::string, boost::shared_ptr<Mesh> >(path, boost::shared_ptr<Mesh>(new Mesh())));    D3dXLoadMesh(it->second.get());  }  return it->second;}void PopualteMeshInstances(){  for (int i = 0; i < 10; ++i)  {    meshInstances.push_back(LoadMesh("yo.mesh"));  }}


You'll probably want your mesh instance to look more like this:
struct MeshInstance{  Matrix ModelTransform;  boost::shared_ptr<MeshObject> Mesh;};std::vector<MeshInstance> meshInstances;

That way you can store a model transform with each instance.
Quote:Original post by bzroom
LPD3DXMESH is already a pointer LP is the give away. So you're already store it as a pointer. So assinging it to each mesh object as you did is only making a reference to the mesh. It is only loaded and stored 1 time. Since you called Load 1 time, and are only copying references, not the mesh data.

This means though, that if you call meshes[0]->mesh->doSomething(), that it will effect all the other meshes, since they are the same mesh.



I'm sorry, my example wasn't considering that i'm actually calling the function multiple times and pass a file name to it.

In that case, will my MeshObject array actually hold pointers to one mesh and not 10 meshes (if the file name doesnt change)?


it would actually look like this

int i=0;for(i=0; i<10; i++)    loadMesh("test.x");i=0;void loadMesh(char* filename) {        LPD3DXMESH mesh;	LoadMeshFromFile(&mesh, filename);	meshes[i++]->mesh = mesh;}
Each time you call: LoadMeshFromFile, it will load the mesh, regardless of wether it has been already loaded or not.

Yes that will load 10 duplicate copies of the mesh, and you should use a system as described in my previous post to only load each mesh once.
Alright, my performace confirms this.. it's very bad right now :)


i will try to implement your code now.
Ok this works absolutely gorgeous, except that i had to remove all the "boost" usage.

(i'm working on a school project and can't use non standard libraries).

Will the performance at run time decrease without using boost when i get the meshes from the list for rendering?
No, boost is just a way to intelligently handle the life of the objects pointed to by pointers. while it will work, copying the pointers around as you are, it is VERY unsafe.

Imagine you added a destructor to the MeshObject which told directx to free the mesh that it was pointing to. If all 10 MeshObjects are pointing to the same mesh, and one of them gets destroyed, telling d3d to free the mesh, then they all lose their mesh.

Worse still, they all still think the mesh is still there, since they have a pointer to it. But truthfully it's been deleted out from under them. This is called a dangling reference. and you're very very close to a whole party of them :)

You can implement your own reference counted object that the MeshObjects can share, so that when the destructor is called, it only frees the mesh after there are no more references to it. But why go through all that trouble when boost::shared_ptr is there for you?

There may be some std variant, or you may be able to convince your teacher to let you use shared_ptr, since it's pretty much standard at this point.
Ok thanks for shedding light on "boost".

This library doesn't come with windows or? i tried to include it but the compiler says he can't find it.


So here's my implementation so far:

I was a little lazy and use one list to save each mesh one time and just give my mesh objects pointers to the meshes in the list.

LPD3DXMESH* mesh;void ObjectManager::addObject(char *file, MeshObject* object)  std::map<std::string, LPD3DXMESH>::iterator it;  it = MeshList.find(file);	if (it == MeshList.end())	{		mesh = new LPD3DXMESH;		LoadMeshFromFile(mesh, file);		MeshList.insert(std::pair<std::string, LPD3DXMESH>(file, (*mesh)));		object->mesh = treemesh;	}	else	{		object->mesh = &(it->second);	}	scene->AttachChild(object);}


In the rendering i go through my object graph and the objects seem to store only one adress for each mesh (right now i'm using two meshes and only two addresses are shown in my render loop).

Is this implementation suitable or does it miss some benefits of your code? The performance increased by about 100 fps with this new implementation btw. The objects render correctly too.

This topic is closed to new replies.

Advertisement