Somebody fetch Stainless

I don't think I'm really the right person to do this as I have no practical experience of graphics programming but here are the things I feel (barely) qualified to talk about -
I implemented a (so far) simple renderer for meshes:
https://gitlab.com/vrresto/il2ge-experimental/-/blob/cfdb3147c62785551cf5132504d5479d21e3e9fa/include/il2ge/renderer.h#L51
The interface is designed with the possibility in mind of the renderer running in an own thread.
I'd be happy for some review.
I think the most important thing to establish in the first place is the threading model that you want to have. I presume it is something like:
- Main thread - All of the Java engine code that submits things to be rendered to il2_core and therefore il2ge
- Renderer thread - il2ge doing actual OpenGL calls on the GLContext
I think both interfaces proposed have some blocking in the semantic sense - in the blocking impl the main thread is blocked waiting for createMesh(). In the non-blocking impl it's blocked polling getCreatedMeshes until the mesh is created I think? Although it can do other stuff in between polling right?
In this threading model, if there is frequently a dependency on something in the rendering thread finishing before the main thread can continue then I guess it either doesn't make sense to use a separate thread or there is some alteration that needs to be made to the communication model between the threads. Ideally the main thread wants to be doing "fire and forget" things.
In that case it might be worth considering whether or not you actually get any advantages from the non-blocking interface. I think running the game through the
Concurrency Visualizer in VS2019 might be a good way to check thread utilization on a given scene while running a track maybe? I suppose the criteria is how much time is spent blocking on synchronous createMesh vs busy-waiting in getCreateMeshes.
I guess another angle to consider is that it might be possible to use wglShareLists and run mesh creation and loading as another completely separate thread so that the renderer thread doesn't have to stop to do it, although it looks like there are caveats to doing that, e.g. see the comment at the end of
this blog post.
The actual rendering happens here:
https://gitlab.com/vrresto/il2ge-experimental/-/blob/cfdb3147c62785551cf5132504d5479d21e3e9fa/common/renderer.cpp#L122
Again, I'd be happy for some review whether it's a sound design performance wise - at least for non-transparent objects. I don't know yet how to handle transparency.
Edit: What I haven't looked into so far are hierarchical meshes and whether it would make sense to merge all submeshes into one vertex array.
One question is, whether it is possible to add/remove submeshes at run time. I think it's at least possible to toggle their visibility.
Merging submeshes - definitely possible to toggle visibility and remove submeshes as there's an int[] hideSubTrees(String) method on ActorHMesh, and also void destroyChildFiltered(Class). I don't know enough to say whether it's an important optimization to make in the long run but I probably wouldn't worry about it in a prototype implementation.
Handling transparency - I haven't read about any good way to do it other than rendering things in the right order (furthest away to closest). I'm not sure how il2ge and il2_core interact but as the game already supports transparency I can only assume it does the rendering calls for transparent objects in the right order already? Although I haven't really tried viewing things through multiple transparent objects to see how they behave when they're layered on top of each other. There are implementations of order-independent transparency but it looks really tricky. The simplest explanation of doing this in a simple way that I have found is
here. In fact basically that whole website is a goldmine for everything from the simplest to the most advanced OpenGL techniques with full source code. The approach described there (using a map indexed by the distance from the viewer to store transparent objects) seems like a good approach and not too far from your existing approach of having separate lists.