Skip to main content
Added example usage
Source Link
akaltar
  • 181
  • 4

Here is some usage to clarify why is a reinterpret_cast necessary(this is not code to be reviewed, just rough example of usage):

// Init
DeferredRenderer->AddObjectType<Asset>(AssetShader.Get(),
   RenderFunctions::Deferred::RenderAsset );

// Somewhere passing a Asset to external C code( lua )
void* genericRenderable = MyAsset;
PassToLua( genericRenderable );

// Lua code calling entity system.
SetComponent( DeferredRenderable, genericRenderable );

// The render system processing entities
static_cast<Renderable*>(genericRenderable)->Render( DeferredRenderer );

// This calls 
void Asset::Render( Renderer* r ) // where r is DeferredRenderer
{
    r->Render( *this );
}

Here is some usage to clarify why is a reinterpret_cast necessary(this is not code to be reviewed, just rough example of usage):

// Init
DeferredRenderer->AddObjectType<Asset>(AssetShader.Get(),
   RenderFunctions::Deferred::RenderAsset );

// Somewhere passing a Asset to external C code( lua )
void* genericRenderable = MyAsset;
PassToLua( genericRenderable );

// Lua code calling entity system.
SetComponent( DeferredRenderable, genericRenderable );

// The render system processing entities
static_cast<Renderable*>(genericRenderable)->Render( DeferredRenderer );

// This calls 
void Asset::Render( Renderer* r ) // where r is DeferredRenderer
{
    r->Render( *this );
}
Tweeted twitter.com/#!/StackCodeReview/status/579035032339247104
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Source Link
akaltar
  • 181
  • 4

Templated renderer class

A class that matches the rendered objects shader and render function(sets shader resources) based on its typeid hash.

#include <unordered_map>

#include <glm/glm.hpp>

#include "gl_func.h"
#include "gl_buffer.h"
#include "shader.h"
#include "log.h"

class Renderer
{
private:

    typedef void (*RenderFunctionPointer)();

    typedef std::unordered_map< size_t, Shader* >::iterator ShaderIterator;
    typedef std::unordered_map< size_t, RenderFunctionPointer >::iterator
        FunctionIterator;

    std::unordered_map< size_t, Shader* > Shaders;
    std::unordered_map< size_t, RenderFunctionPointer > RenderFunctions;

    glm::mat4 ProjectionMatrix;
    glm::mat4 ViewMatrix;

public:

    // Sets the given matrices for all shaders
    void SetProjectionMatrix( glm::mat4 p );
    void SetViewMatrix( glm::mat4 v );

    /*! \brief Tells the renderer how to render object of type T
     *  \param shd Shader to use for rendering.
     *  \param f Pointer to a function that takes a shader and a T& argument. */
    template< typename T >
    void AddObjectType( Shader* shd, void (*f)(Shader*, T& ) )
    {
        size_t type = typeid( T ).hash_code();
        Shaders[type] = shd;
        RenderFunctions[type] = (RenderFunctionPointer)f;
    }

    /*! \brief Renders the given object.
     *  The object type has to be registered before this call.
     *  \param obj Object to Render */
    template< typename T >
    void Render( T& obj )
    {
        size_t type = typeid( T ).hash_code();

        ShaderIterator i = Shaders.find( type );

        if( i == Shaders.end() )
        {
            LOG_WARNING() << "Couldn't find shader for object: " 
                << typeid( T ).name();
            return;
        }
    
        Shader* shd = i->second;
        shd->SetModelMatrix( obj.GetTransform() );
        shd->Bind();

        FunctionIterator f = RenderFunctions.find( type );
        if( f == RenderFunctions.end() )
        {
            LOG_WARNING() << "Couldn't find renderfunction for object: "
                << typeid( T ).name();
            return;
        }

        RenderFunctionPointer rp = f->second;
        reinterpret_cast< void(*)(Shader* shd, T& t) >(rp)( shd, obj );
    }
};