Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

3d engine design issues

Started by Dragon_Strike Feb 28, 2009 at 4:59 AM 0 replies 950+ views
Original Post
Dragon_Strike
Dragon_Strike
ive implemented my 3d engine in a somewhat MVC fashion to make it easier to thread... basicly ive got a "scene/model" subsystem and a "renderer/view" subsystem... the "scene" loads all meshes, textures and materials and then sends the one that should be rendered to the "renderer" in the form of a "displaylist".. this basicly means that the renderer has to see if there are "hardware" instances of all these objects and if not create them and then render... my problem is how i map these "hardware" instances to the ones in the "scene" subsystem... this is how i ma doing it now... very ugly its not actual code just demostrating the problem... scene::Mesh


namespace scene
{
   class Mesh
   {
      const VertexData& VertexData();
      const IndexData& IndexData();

      void* HardwareInstance();
      void HardwareInstance(void* instance);
   }
}



renderer is sent a list of "Geometry" objects that consist of a Mesh, Material and Transform... it then checks if all these objects has a hardware instance, if not creates it and then renders them..

namespace renderer
{
/*........*/

void Render()
{
   DisplayList dpList;
   if(!scene->DisplayList(dpList))
      return;

   BOOST_FOREACH(GeometryPtr& geo, dpList.Geometries())
   {
      if(geo->Mesh()->HardwareInstance() == NULL)
         // create and set hardware instance
      if(geo->Texture()->HardwareInstance() == NULL)
         // create and set hardware instance
   }
   // DO RENDERING
   boost::polymorphic_downcast<d3d10:Mesh*>(geo->Mesh()->HardwareInstance())->Render();
}

/*........*/
}




using void* pointers like this and then doing unsafe static_casts like this is just horrible... im unsure how to solve this? i could assign every object a unique id... and then put them in a splaytree or something... but im unsure about how good that is performance wise... and how would i create the unique ids? i give all the objects string names when they are created but comparing strings isnt all that fast... EDIT: another problem i have is that since i have already created the hardware instance of the "scene" object... the "scene object" is actually no longer needed and is just wasting memory... and for example just emptying the "VertexData" and "IndexData" of the mesh object would make the object lie since it then no longer is a mesh but just a holder of a hardware instance
haegarr
haegarr
I had a similar problem. Similarly to the views in MVC, I allow different kinds of graphics renderers to even co-exist. Different renderers may need different "hardware instances".

My solution is this: Meshes (and other kinds of objects) are managed as resources. Resources of a specific kind are collected in a specific resource library. Such a library is able to provide an ID for the stored resource. That ID is in fact a small integer number. The ID can be allocated and freed, and the allocation is implemented so that the smallest available ID is returned. Allocating the next ID is relatively fast since it is done by looking up the bits of an integer number array. So 32 IDs can be checked for an available ID at once, and binary search can be used inside. However, allocation is done relatively seldom, since resources are not unloaded often.

Now, a renderer (as an example) "knows" that it requires hardware instance for each mesh. When the renderer is asked for rendering a mesh, it fetches the mesh's ID and checks whether its internal array is big enough so that the ID can be used as index into the array. If not, then the array is expanded accordingly. At this point the ID will ever fit as index into the array. So the renderer fetches the pointer that is stored at that index in the array. It may be nil, what means that there is no hardware instance stored. In such a case a new instance is created and stored into the array.

With such arrays every "view" can store whatever it requires. It uses indirect association (the ID) and hence doesn't write access the resource (i.e. mesh in this case) directly.

Every resource library allows clients to be registered as listeners. Changes that are notified are (besides others) removal of the resource from the library. So a renderer can register an own listener with the library. In the handler specific to the resource removal event, the renderer checks whether the mesh has an associated hardware instance in the array and deletes it if so. The ID gets freed by the library as the last step of removal, of course.

Others will suggest you to use maps. I use indices and arrays since it seems me the most efficient way, but maps are suitable as well.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.