0

很好地尝试设计一个着色器类,现在只是尝试获得处理制服的基本轮廓。我的一些设计目标是避免将字符串传递给函数,因为这很容易出错并且没有类型检查。只有一个地方会出错,如果你在定义制服的时候打错了制服的名字。

但是,代码膨胀的可能性很大,可能会将 Name 从 Parameter 的模板参数中移出,并将其存储为成员变量,该成员变量将在默认构造函数中分配。

template<typename ParamType>
class Shader
{
public:
    template<typename Type, const char* (*Name)()>
    class Parameter
    {
        static const char* name;
        static GLuint location;
        static GLuint program;

        template<typename> friend class Shader;
    };

    template<typename Type, const char* (*Name)()>
    void SetParameter(const Parameter<Type,Name>&, const Type& value )
    {
        // static_assert(!std::is_same<Type,Type>::value, "Unsupported type, needs specialization.");
        typedef Parameter<Type,Name> Param;

        if(program != -1 && Param::program != program)
        {
            // set Param::location
            Param::program = program;
        }

        std::cout << Param::name << std::endl;
    }

private:

    GLuint program;

};

template<typename ParamType>
template<typename Type, const char* (*Name)()>
const char* Shader<ParamType>::Parameter<Type, Name>::name = Name();

template<typename ParamType>
template<typename Type, const char* (*Name)()>
GLuint Shader<ParamType>::Parameter<Type, Name>::program = -1;

#include "shaderparameters.inl"

着色器参数.inl:

#define MY_PARAMETER(shader, type, name) \
    private: static const char* ShaderParameterStr##shader##type##name##() { return #name ; }  \
    public:  typedef Shader< shader >::Parameter< type, &ShaderParameterStr##shader##type##name > name;

struct ShaderParam
{
    struct Generic
    {
        MY_PARAMETER( Generic, Vec4, position )
        MY_PARAMETER( Generic, Mat4, projection )
    };

};
#undef MY_PARAMETER

用法:

Shader<ShaderParam::Generic> s;

s.SetParameter(ShaderParam::Generic::projection(), Mat4());
s.SetParameter(ShaderParam::Generic::position(), Vec4());

您对此实施有何看法?您对改进或完全不同的系统有什么建议吗?我知道我见过人们使用哈希映射等,但仍然存在连续使用字符串文字来设置制服等的问题(也不太喜欢使用宏来定义字符串的想法)。

4

0 回答 0