[3.0.0] Proper way to reload/rebuild meshes at runtime? Topic is solved

Problems building or running the engine, queries about how to use features etc.
User avatar
haloman30
Kobold
Posts: 28
Joined: Mon Aug 29, 2022 2:53 pm
x 2

[3.0.0] Proper way to reload/rebuild meshes at runtime?

Post by haloman30 »

Ogre Version: 3.0.0
Operating System: Windows 7 x64
Render System: Direct3D 11

I've been running into an issue for a while now - thought I'd fixed it a couple times before, but I just can't seem to work it out or find any obvious info on forums or otherwise.

What is the 'proper' way to reload/rebuild meshes at runtime? I'm building a game engine and all meshes are stored in custom data formats, with the engine creating meshes/submeshes and VAOs manually. When loading for the first time, this appears to work fine - but when unloading or reloading, I end up getting exceptions during render where the VAOs are still being referenced after having been deleted.

Reloading in this case, for reference, involves retrieving the existing mesh if one exists, then destroying any submeshes, then loading again the same as if it were a new mesh. Additionally, mesh loading/unloading is setup to only ever happen before rendering, so it seems to me like it should all be cleaned up and ready to go by the time the frame is rendered. The one other potential clue I have is that these are meshes that are already in use and attached to scene nodes, but I would think this would still work given that existing meshes are reused if they already exist and have their submeshes recreated - but maybe I'm wrong on that part.

I assume there's some simple step of some sort that I'm just missing - would appreciate any pointers!

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5446
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1348

Re: [3.0.0] Proper way to reload/rebuild meshes at runtime?

Post by dark_sylinc »

Reloading in this case, for reference, involves retrieving the existing mesh if one exists, then destroying any submeshes, then loading again the same as if it were a new mesh. Additionally, mesh loading/unloading is setup to only ever happen before rendering, so it seems to me like it should all be cleaned up and ready to go by the time the frame is rendered. The one other potential clue I have is that these are meshes that are already in use and attached to scene nodes, but I would think this would still work given that existing meshes are reused if they already exist and have their submeshes recreated - but maybe I'm wrong on that part.

You're missing a crucial step: First destroy any Item/Entity that is still using those meshes.
Meshes are smart ptrs, and won't be fully destroyed until the last reference is destroyed. If you've still got live Item references those Meshes, you just destroyed their internal Vaos while the Item and Mesh are still in use.

A simple way to detect these issues is to build OgreNext and your project with ASAN. OgreNext can be built with CMake flag OGRE_ADDRESS_SANITIZER_ASAN which automatically sets it.

ASAN will tell you when memory corruption first happens, and when was the original block allocated and when it was freed.

Update: Rereading again, it looks like you're not destroying the Mesh, but rather reusing it and destroying its submeshes. The problem with that is that Ogre::SubItem caches the SubMesh ptr in SubEntity::mSubMesh.
Even if you manage to update the mSubMesh ptr, you still have to consider is that if something fundamental changed (the vertex declaration changed, the number of bones per vertex assigned changed, the index buffer is now 32 bit instead of 16, etc), the Renderable::mHlmsHash and Renderable::mHlmsCasterHash become stale. You can use _setNullDatablock() and immediately follow it with a call to setDatablock( originalDatablock ) to recalculate them.