Jump to content
  • Advertisement
Sign in to follow this  
Daniel E

efficient mesh management?

This topic is 3313 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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>

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;


}



Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Alright, my performace confirms this.. it's very bad right now :)


i will try to implement your code now.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!