title: OpenGL Renderer class design: flexible and simple?
body: <p>I'm working on designing a rendering system for OpenGL 3.1 ( limited to just 2D for now ). What I'd like to do is really think about elegant design patterns so that I don't have to worry about some hacked up mess which is a pain to maintain and debug.</p>
  
  <p>At first, I was thinking something along the lines of having a templated base class with functions which accepted different typenames as arguments. The child classes would then inherit from the base class, sending in which types they would be using as template arguments upon derivation.</p>
  
  <p><a href="https://stackoverflow.com/a/3255804/763053">Then I found out this was basically impossible</a>.</p>
  
  <p>So, I'm a bit stuck as how I should design this properly without just hacking things away. The thing is that I'm using my own vertex structures which wrap around <code>glm</code> vector classes, so I can have vertex pairs in a structure and stride them with memory offsets when I call <code>glVertexAttribPointer()</code>.</p>
  
  <p>In other words,</p>
  
  <pre><code>typedef struct colorVertex_d
  {
      glm::vec3 Position;
      glm::vec4 Color;
  }
  colorVertex_t;
  
  typedef struct textureVertex_d
  {
      glm::vec3 Position;
      glm::vec2 UV;
  }
  textureVertex_t;
  </code></pre>
  
  <p>Ideally, what I'd like to do is limit the actual types available for use in this Renderer to be the vertex types which have been defined.</p>
  
  <p>One way of doing this I think was by doing something along the lines of <a href="http://www.parashift.com/c++-faq/template-specialization.html" rel="nofollow noreferrer">this</a>, and then calling a Shutdown method ( kind of like an exception, just not an exception... ) if the type sent to the class isn't valid.</p>
  
  <p>Still, I'm not even sure if this could be considered a good implementation in this context. </p>
  
  <p>What I'm really looking for is a means for which I can support multiple buffer types ( e.g. vertex, index, normal, color, etc. ) which conforms to types like the vertex structures shown above.</p>
  
  <p><strong>Original Source</strong></p>
  
  <pre><code>/**
    * Is an abstract class to inherit from for defining custom buffer handler classes,
    * the type name specified is the type of data stored in the buffer specifically, e.g. textureVertex_t or colorVertex_t
    */
  
  template &lt; typename DataT, typename ContainerT &gt;
  class RenderBuffer
  {
  public:
      enum RenderMethod
      {
          Stream,             // used for writing data into the buffer once per render
          Dynamic,            // values in the buffer are changed from time to time
          Static              // data is set only once, then rendered as many times as it needs to be
      };
  
      enum DrawMode
      {
          Triangle,
          TriangleStrip,
          Line,
          LineStrip
      };
  
      enum BufSetType
      {
          Alloc,
          Update
      };
  
      RenderBuffer( RenderMethod rm, DrawMode dm )
      {
          switch( rm )
          {
          case Stream:    mRenderMethod = GL_STREAM_DRAW;     break;
          case Dynamic:   mRenderMethod = GL_DYNAMIC_DRAW;    break;
          case Static:    mRenderMethod = GL_STATIC_DRAW;     break;
          }
  
          switch( dm )
          {
          case Triangle:      mDrawMode = GL_TRIANGLES;       break;
          case TriangleStrip: mDrawMode = GL_TRIANGLE_STRIP;  break;
          case Line:          mDrawMode = GL_LINES;           break;
          case LineStrip:     mDrawMode = GL_LINE_STRIP;      break;
          }
      }
  
      virtual ~RenderBuffer( void )
      {
      }
  
      virtual void Reserve( size_t sz ) = 0; // Reserve space for whatever container used to store the buffer data.
  
      virtual void Bind( void ) const = 0;
  
      virtual void UnBind( void ) const = 0;
  
      template &lt; typename DataT, ContainerT &gt;
      virtual void SetBufferData( const ShaderProgram&amp; program, const ContainerT&amp; data, BufSetType m )
      {
      }
  
      template &lt; typename DataT, ContainerT &gt;
      virtual void SetBufferData( const ShaderProgram&amp; program, const DataT* data, const size_t len, BufSetType m )
      {
      }
  
      virtual void Render( void ) const = 0;
  
      size_t VertexCount;
  
  protected:
      GLenum mDrawMode, mRenderMethod;
  };
  </code></pre>