title: Rendering Engine Design - Abstracting away API specific code for Resources
body: <p>I have a very big design stumbling block in my rendering code. Basically what this is, is not requiring API specific code (such as OpenGL code or DirectX). Now I've thought of numerous ways on how to solve the problem, however I'm <em>not sure</em> which one to use, or how I should improve upon these ideas.</p>
  
  <p>To give a brief example, I will use a Texture as an example. A texture is an object which represents a texture in GPU memory, implementation wise it may be resembled in any particular way, i.e. whether implementation uses a <code>GLuint</code> or <code>LPDIRECT3DTEXTURE9</code> to resemble the texture.</p>
  
  <p>Now here are the ways I've thought of to actually implement this. I'm quite unsure if there is a better way, or which way is better than another.</p>
  
  <hr>
  
  <h2>Method 1: Inheritance</h2>
  
  <p>I could use inheritance, it seems the most obvious choice for this matter. However, this method <em>requires</em> virtual functions, and would require a TextureFactory class in order to create Texture objects. Which would require calls to <code>new</code> for each <code>Texture</code> object (e.g. <code>renderer-&gt;getTextureFactory()-&gt;create()</code>).</p>
  
  <p>Here's how I'm thinking of using inheritance in this case:</p>
  
  <pre><code>class Texture
  {
  public:
  
      virtual ~Texture() {}
  
      // Override-able Methods:
      virtual bool load(const Image&amp;, const urect2&amp; subRect);
      virtual bool reload(const Image&amp;, const urect2&amp; subRect);
      virtual Image getImage() const;
  
      // ... other texture-related methods, such as wrappers for
      // load/reload in order to load/reload the whole image
  
      unsigned int getWidth() const;
      unsigned int getHeight() const;
      unsigned int getDepth() const;
  
      bool is1D() const;
      bool is2D() const;
      bool is3D() const;
  
  protected:
  
      void setWidth(unsigned int);
      void setHeight(unsigned int);
      void setDepth(unsigned int);
  
  private:
      unsigned int _width, _height, _depth;
  };
  </code></pre>
  
  <p>and then in order for OpenGL (or any other API specific) textures to be created, a sub-class would have to be made, such as <code>OglTexture</code>.</p>
  
  <h2>Method 2: Use a 'TextureLoader' or some other class</h2>
  
  <p>This method is as simple as it sounds, I use another class to handle loading of textures. This may or may not use virtual functions, depending on the circumstance (or whether I feel it is necessary).</p>
  
  <p>e.g. A polymorphic texture loader</p>
  
  <pre><code> class TextureLoader
   {
   public:
  
        virtual ~TextureLoader() {}
  
  
        virtual bool load(Texture* texture, const Image&amp;, const urect2&amp; subRect);
        virtual bool reload(Texture* texture, const Image&amp;, const urect2&amp; subRect);
        virtual Image getImage(Texture* texture) const;
   };
  </code></pre>
  
  <p>If I were to use this, a <code>Texture</code> object would only be a POD type. <em>However</em>, in order for this to work, a handle object/ID would have to be present within the <code>Texture</code> class.</p>
  
  <p>For example, <a href="http://ideone.com/fGeejl" rel="noreferrer">this is how I would more than likely implement it</a>. Although, I may be able to generalise the whole ID thing, using a base class. Such as a <code>Resource</code> base class in which case holds an ID for a graphics resource.</p>
  
  <h2>Method 3: The Pimpl Idiom</h2>
  
  <p>I could use the pimpl idiom, which implements how to load/reload/etc. textures. This would more than likely require an abstract factory class for creation of textures. I am unsure how this is better than using inheritance. This pimpl idiom could be used in conjunction with Method 2, i.e. Texture objects would have a reference (pointer) to their loader.</p>
  
  <h2>Method 4: Using concepts/compile-time polymorphism</h2>
  
  <p>I could on the other hand, use compile-time polymorphism and basically use what I presented in the inheritance method, except without declaring virtual functions. This would work, but if I wanted to dynamically switch from OpenGL rendering to DirectX rendering, this would not be the best solution. I would simply put OpenGL/D3D specific code within the Texture class, where there would be multiple texture classes with some-what the same interface (load/reload/getImage/etc.), wrapped inside some namespace (resembling which API it uses, e.g. <code>ogl</code>, <code>d3d</code>, etc.).</p>
  
  <h2>Method 5: Using integers</h2>
  
  <p>I could just use integers to store handles to texture objects, this seems fairly simple, but may produce some-what "messy" code.</p>
  
  <hr>
  
  <p>This problem is also present for other GPU resources such as Geometry, Shaders, and ShaderPrograms.</p>
  
  <p>I've also thought of just making the Renderer class handle the creation, loading, and etc. of graphical resources. However this would violate <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" rel="noreferrer">SPR</a>. e.g. </p>
  
  <pre><code>Texture* texture = renderer-&gt;createTexture(Image("something.png"));
  Image image = renderer-&gt;getImage(texture);
  </code></pre>
  
  <p>Can someone please guide me, I think I'm thinking too heavily about this. I've tried observing <em>various</em> rendering engines, such as Irrlicht, Ogre3D, and others I have found online. Ogre and Irrlicht use inheritance, however I am unsure that this is the best route to take. As some others just use void*, integers, or just put API specific (mainly OpenGL) code within their classes (e.g. GLuint directly within the Texture class). I really cannot decide which design would be the most appropriate for me.</p>
  
  <p>The platforms I am going to target are:</p>
  
  <ul>
  <li>Windows/Linux/Mac</li>
  <li>iOS</li>
  <li>Possibly Android</li>
  </ul>
  
  <p>I have considered to just use OpenGL specific code, as OpenGL works for all of those platforms. However, I feel that if I do that I will have to change my code quite a lot if I wish to port to other platforms that cannot use OpenGL, such as the PS3. Any advice on my situation will be greatly appreciated.</p>