dynamic mesh "streaming" / general multithreading
dynamic mesh "streaming" / general multithreading
hi folks.
i am planning to create a prototype application rendering a rather big world consisting of thousands of meshes (maybe i will use & enhance my GTA world loader for this). for this, some kind of streaming of mesh and texture data is definitely needed. i think keeping all this data in memory is out of question, so i am looking for ideas how to realise this using Irrrlicht.
so thinking about this i would create a management class that determines which meshes are to be drawn (or at least which meshes must be present in memory), loads new meshes/textures and unloads unneeded ones.
the problem which i see here: if i load data during two rendering frames, the application will probably suffer a dramatic FPS drop. maybe this could be compensated by only loading one mesh between frames, but i think that is not a solid solution.
the only thing i can think of which would be a good solution here would be threading (having a seperate data management thread), but that leads me to the next questions:
since a few days i see multiple threads in this forum which are related to multithreading, and i read them, but there are several basic questions which do not get answered completely or easily:
- does irrlicht support multithreading at all?
- ... or maybe just for some subareas (the only subarea which i would need to have threadsafe is mesh/texture loading, but i don't think threaded texture loading is possible using APIs like OpenGL)?
- if not supported at all, is it planned?
- if not supported at all, are there any other ideas how to speedup mesh loading in an external thread?
thanks in advance for any clearifications and ideas on the topic.
i am planning to create a prototype application rendering a rather big world consisting of thousands of meshes (maybe i will use & enhance my GTA world loader for this). for this, some kind of streaming of mesh and texture data is definitely needed. i think keeping all this data in memory is out of question, so i am looking for ideas how to realise this using Irrrlicht.
so thinking about this i would create a management class that determines which meshes are to be drawn (or at least which meshes must be present in memory), loads new meshes/textures and unloads unneeded ones.
the problem which i see here: if i load data during two rendering frames, the application will probably suffer a dramatic FPS drop. maybe this could be compensated by only loading one mesh between frames, but i think that is not a solid solution.
the only thing i can think of which would be a good solution here would be threading (having a seperate data management thread), but that leads me to the next questions:
since a few days i see multiple threads in this forum which are related to multithreading, and i read them, but there are several basic questions which do not get answered completely or easily:
- does irrlicht support multithreading at all?
- ... or maybe just for some subareas (the only subarea which i would need to have threadsafe is mesh/texture loading, but i don't think threaded texture loading is possible using APIs like OpenGL)?
- if not supported at all, is it planned?
- if not supported at all, are there any other ideas how to speedup mesh loading in an external thread?
thanks in advance for any clearifications and ideas on the topic.
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Re: dynamic mesh "streaming" / general multithread
Irrlicht is not currently thread safe.loki1985 wrote:- does irrlicht support multithreading at all?
I don't know of anyone in the current dev team who plans to do it, but:loki1985 wrote:- if not supported at all, is it planned?
1) I may be wrong about that.
2) You get into the dev team by providing patches, so knock yourself out.
I should note that any implementation would have to be cross platform, and provably robust. Multithreading tends to introduce subtle bugs, so anyone planning to implement it had better be planning to support it as well.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Re: dynamic mesh "streaming" / general multithread
I guess the most sensible way to do this would be to have a LOD based mesh format with easy access to the levels for loading. You can then queue the disk access so that the lowest levels are handled first. Populate the mesh data with changes, then unlock it to allow drawing / sending to the GPU.
The same applies to textures, some texture format that allows easy access to mipmaps and then to expose the mipmap levels of ITexture. This way you can load the smallest mipmaps first (1x1 pixels) and stream the other ones in as required, ditching the levels as you get further away. Loading textures into video memory will have to be done in the render thread.
Finally, you'll need a node type that deals with the texture and mesh managers, and will draw whatever mesh/texture data is available and materials to fade them in/out.
This is all a lot of work, but that's what it would take to deliver a seamless experience as good as Unreal Engine 3.
To make an even better effect, you could morph the meshes between LOD levels (means your own custom mesh format and tools), and for better performance you could use impostors as your lowest mesh LOD level.
The same applies to textures, some texture format that allows easy access to mipmaps and then to expose the mipmap levels of ITexture. This way you can load the smallest mipmaps first (1x1 pixels) and stream the other ones in as required, ditching the levels as you get further away. Loading textures into video memory will have to be done in the render thread.
Finally, you'll need a node type that deals with the texture and mesh managers, and will draw whatever mesh/texture data is available and materials to fade them in/out.
This is all a lot of work, but that's what it would take to deliver a seamless experience as good as Unreal Engine 3.
To make an even better effect, you could morph the meshes between LOD levels (means your own custom mesh format and tools), and for better performance you could use impostors as your lowest mesh LOD level.
The LOD Mehses will have diffrent topolgy and might have diffrent tcoords as the vertices are different, loading in mipmaps would work if all the lod levels use the same texture coords or just have rpeating etxtures withouht a proper UV layout( lightmaps would have diffrent uv's nad textures for diffrent LOD levels.).
"Irrlicht is obese"
If you want modern rendering techniques learn how to make them or go to the engine next door =p
If you want modern rendering techniques learn how to make them or go to the engine next door =p
Yep, but it still makes sense to load the smallest mipmaps first even if they aren't shared across meshes. You can initially keep every texture in the world in memory as a single pixel, and even if something hasn't loaded it can still be displayed without pausing, even if it looks crap for a second or two. I think this is how Unreal does it anyway, it certainly looked that way in Mass Effect.omaremad wrote:The LOD Mehses will have diffrent topolgy and might have diffrent tcoords as the vertices are different, loading in mipmaps would work if all the lod levels use the same texture coords or just have rpeating etxtures withouht a proper UV layout( lightmaps would have diffrent uv's nad textures for diffrent LOD levels.).
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
It's possible, but you'll want to synchronise access to the Irrlicht scene node.
Consider what would happen if your AI moves a scene node (or otherwise changes the scene graph) while the scene graph is being rendered. It wouldn't necessarily be fatal, but you'd get inconsistent visual results for that frame.
You'll want to synchronise access to the scene graph so that can't happen. Consider "double buffering" the graph, by which I mean having your AI thread operate on a copy of the relevant data, and writing those data into the scene node just before starting the Irrlicht render.
Approximately...
Note that there's very likely an error even in that near-trivial interaction diagram. Threading is a pig to design and debug, and anyone who tells you otherwise has never had to fix someone else's hooky implementation.
Consider what would happen if your AI moves a scene node (or otherwise changes the scene graph) while the scene graph is being rendered. It wouldn't necessarily be fatal, but you'd get inconsistent visual results for that frame.
You'll want to synchronise access to the scene graph so that can't happen. Consider "double buffering" the graph, by which I mean having your AI thread operate on a copy of the relevant data, and writing those data into the scene node just before starting the Irrlicht render.
Approximately...
Code: Select all
[AI thread] [Irrlicht thread]
| |
| Take scene graph mutex
Do AI |
| |
Wait for scene graph mutex |
| |
| Render scene graph
| |
| Render finished, give mutex
| |
Take mutex |
| |
| Wait for mutex
| |
Copy data to scene graph ----------->|
| |
Give mutex |
| |
............ repeat ....................
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
-
- Posts: 1638
- Joined: Mon Apr 30, 2007 3:24 am
- Location: Montreal, CANADA
- Contact:
Could this be done with a "background" loader that load stuff in buffers then copies it to a mesh buffer when it's completed?
The current problem is that when loading (anything) that the CPU is doing that in the foreground (stopping everything that is being worked on (scene redraw, etc.). Doing only this in a background process and putting in a buffer that is NOT used by the rendering engine until it's not complete would make sense.
Anybody with the skills and time?
The current problem is that when loading (anything) that the CPU is doing that in the foreground (stopping everything that is being worked on (scene redraw, etc.). Doing only this in a background process and putting in a buffer that is NOT used by the rendering engine until it's not complete would make sense.
Anybody with the skills and time?
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Of course it could be done.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
just tried to implement a meshstreamer......
works actually. it streams the meshes in a second thread one after each other. I'm using a empty IAnimatedMesh to attach to the IAnimatedSceneNodes. Then i load the real mesh in the other thread and attach the mesh with setMesh.
Only problem is that textures are all white^^
works actually. it streams the meshes in a second thread one after each other. I'm using a empty IAnimatedMesh to attach to the IAnimatedSceneNodes. Then i load the real mesh in the other thread and attach the mesh with setMesh.
Only problem is that textures are all white^^
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
-
- Posts: 1638
- Joined: Mon Apr 30, 2007 3:24 am
- Location: Montreal, CANADA
- Contact:
i think the problem here is that you cannot load textures (means: transfer them to Video RAM) while rendering takes place. so texture upload must be done serial, not parallel (to the rendering, that is)christianclavet wrote: Have you tried loading your texture first? If the textures are in the buffer the mesh shouldnt have white textures.
jepp thats it unfortunatly....the textures should upload themself beforerendering takes places that way u could load them in another thread and then load them to videoram in the mainthread.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Shouldn't be the most intriguing problem though, as this would just mean to factor out the upload call, add a flag to the texture implementations, and upload on first bind.
However, the texture usage is not really separated at all. So it's hard to become aware of its first usage (or you have to put such calls to many places in the drivers...)
However, the texture usage is not really separated at all. So it's hard to become aware of its first usage (or you have to put such calls to many places in the drivers...)