C++ & DirectX - geometry question
I am working on my own 3d engine and have the following question:
I have an abstract object, that handles geometry (vertices and faces). It uses internal storage for this geometry, allows editing and my renderer object has a method RenderGeometry
.
With this design my rendering process includes a geometry caching
step. So, renderer has some map-like container
std::map<Geometry*, CachedGeometry*> map;
and here Geometry
stands for my own geometry storage and CachedGeometry
means a pair of hardware-specific index and vertex buffers, which can then be displayed (in case of DirectX 9 these would be IDirect3D9VertexBuffer*
and IDirect3D9IndexBuffer*
.
And, well, everything looks fine and is extremely convenient. Still, every Geometry*
rendering call has a huge overhead - time to locate that Geometry*
object in my internal storage and only then render the CachedGeometry*
.
In case of simple scenes this overhead was, of course, minimal, but when I attempted to render a landscape with a vast amount of little spatial objects (patches), the profiling showed that about 20% of time spent in rendering was actually used for std::map开发者_Go百科
lookups.
Hash-based containers (boost::unordered_map
, actually) showed even worse performance (why?) and that percentage raised to 35%.
So - to sum everything up - what should I do in this situation? I guess this design is really comfortable and "appropriate", but has abstraction performance penalty.
I think that probably I should try the "nastier" approach and introduce methods like StoreGeometry
in my renderer, which would return object index (int
, for example), so that RenderGeometry
method would look like RenderGeometry(int stored_geometry_index)
.
Although this looks very bad, probably it could help me in reducing the lookups overhead.
What do you think? Maybe some alternative approach? What do modern engines do about geometry precaching?
I am surprised that std::map
is performing so bad. It might be worthwile ask a question (search for existing answers first!) specifically about std::map performance on pointers.
Given that Geometry
and CachedGeometry
are objects that you control, you can do whatever you want to maintain links between them. One way is to make the link 2-way: Both Geometry and CachedGeometry have pointers to each other, and if CachedGeomitry is destroyed, it tells Geometry
to null the reference to it's CachedGeometry
. If your app is single threaded this could be very simple. If not, it is still doable but will require you to think how you handle(or prevent) situations when an object is deleted in mid air.
精彩评论