c++ - 是否可以在着色器类中使用 "Key"设计模式?

标签 c++ design-patterns opengl shader

首先,我不知道“关键”模式是否被接受为一般模式,但最近其中一些模式已经出现在各处,所以......

我想做什么?

用 C++ 创建着色器操作类。我在这里的问题特别关注设置统一值(“直接”从 C++ 发送到 GLSL 的值)。

问题是什么?

(快速解释,以便不习惯OpenGL的人也可以贡献)- 统一变量通过使用全局 glUniform* 函数设置,将当前绑定(bind)着色器中统一的位置作为第一个参数 (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 类实例,因为可以在一个对象中生成 key 并将其传递给另一个对象,从而导致不必要的行为。

我的问题是 - 在 C++ 中这样的事情可能吗?我是否必须在关键对象中保留指向“父”对象的指针,并每次测试它是否是有效参数,或者是否有任何语言/Boost 功能允许在其周围使用某种语法糖?

我自己推断,关键类应该嵌套在 CShader 中,并且将 CShader 作为 friend 。它还应该将普通构造函数声明为私有(private),并重载复制构造函数,以便复制的对象仍然是有效的键。

最佳答案

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

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

关于c++ - 是否可以在着色器类中使用 "Key"设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10960136/

相关文章:

c++ - 在 700,000 个 vector 元素处突然出现内存峰值

c++ - 使用 openGL 渲染/动画 2d 的最佳方式?

design-patterns - 为什么我们需要设计模式

c - 为什么我的顶点法线会随着相机旋转而旋转?

c++ - 如何正确更新几何图形

OpenGL着色器sampler2D的默认值是多少

c++ - 在 C++ 中创建一个大数组

c++ - Affectiva可以连接Kinect v1吗

.net - Chunky 界面含义

clojure - Clojure中的模式匹配功能?