可以在着色器类中使用“Key”设计模式吗?

时间:2012-06-09 10:13:37

标签: c++ design-patterns opengl shader

首先,我不知道"键"模式被接受为一般模式,但最近有一些模式出现在SO上,所以......

我想做什么?

在C ++中创建着色器操作类。我的问题特别侧重于设置统一值(从C ++发送到GLSL"直接")的值。

问题是什么?

(快速解释,这样不习惯OpenGL的人也可以贡献) - 使用全局glUniform*函数设置统一变量,将当前绑定着色器(int)中统一的位置作为第一个参数;

所以常见的用法是:

glBindProgram(myProgramNum);
int Location = glGetUniformLocation(myProgramNum, "myUniformParameterName");
float myValue = 42.f; // arbitrary data
glUniform1f (Location, myValue);

我已经创建了一些封装上述内容所需的方法,例如

void SetUniform1f (std::string const& name, float a);
void SetUniformVector3 (std::string const& name, CVector3 const& vec);
void SetUniformMatrix4 (std::string const& name, CMatrix4 const& mat);

然而,我注意到所有这些都使用了glGetUniformLocation(int, const char*)。由于其中一些将实时使用,这将导致不必要的性能开销。

第一个想法

我认为我可以为每个功能创建两个版本 - 一个采用std::string和值,第二个采用int和值,因此可以更快地访问。

然而,它会使它们不比纯OpenGL访问更好,因为用户仍然可以向他们发送恶意参数。

第二个想法

所以,正确的方法是生成某种" Key"来自着色器类的对象,包含给定制服的位置。但是,它需要链接到特定的CShader类实例,因为可以在一个对象中生成密钥并将其传递给另一个对象,从而导致不必要的行为。

我的问题是 - 在C ++中可能是这样吗?我是否必须保持指向" parent"密钥对象中的对象,并且每次测试它是否有效参数,或者是否有任何语言/ Boost功能允许它周围的某种语法糖?

我能够推断自己,关键类应该嵌套在CShader中,并将CShader作为朋友。此外,它应该声明普通的构造函数private,并重载copy-constructor,以便复制的对象仍然是有效的键。

1 个答案:

答案 0 :(得分:2)

您只需要一个整数来设置统一变量。实际上,为什么不在glGetUniformLocation中缓存这些值,而不是调用一堆std::map<std::string, int>?查询map会更快,不是吗?

问题中没有一切都清楚(父指针?,恶意值?),但最后,CShader类的假设用户想要一个设置统一值的快捷方式。实际上,您可以在着色器链接(使用glGetActiveUniform)后查询制服,或者您可以在必要时查询统一和缓存统一位置。