如何让一个C++;编译器知道函数是`幂等的` 我正在编写一个OpenGL C++包装器。此包装器旨在减少复杂和易出错的使用
例如,我目前希望用户只对如何让一个C++;编译器知道函数是`幂等的` 我正在编写一个OpenGL C++包装器。此包装器旨在减少复杂和易出错的使用,c++,opengl,C++,Opengl,例如,我目前希望用户只对OpenGL上下文稍加注意。为此,我编写了一个类gl\u texture\u 2d。众所周知,OpenGL纹理基本上具有以下操作: 将其u/v参数设置为repeat/mirror,依此类推 将其设置为min/mag过滤器为线性 基于此,我们有: class gl_texture_2d { public: void mirror_u(); // set u parameter as mirror model void mirror_v(); // set v p
OpenGL上下文
稍加注意。为此,我编写了一个类gl\u texture\u 2d
。众所周知,OpenGL纹理
基本上具有以下操作:
repeat
/mirror
,依此类推min
/mag
过滤器
为线性
class gl_texture_2d
{
public:
void mirror_u(); // set u parameter as mirror model
void mirror_v(); // set v parameter as mirror model
void linear_min_filter(); // ...
void linear_mag_filter(); // ...
};
我们知道,只有当OpenGL纹理对象的句柄当前绑定到OpenGL上下文时,我们才能执行这些操作。
假设我们有一个函数,可以这样做:
无效绑定(GLuint htex);//实际上是相关GL函数的别名
好的,我们现在可以将我们的gl\u纹理\u 2d
用法设计为:
gl_texture_2d tex;
bind(tex.handle());
tex.mirror_u();
tex.linear_min_filter();
unbind(tex.handle());
它证实了德国劳埃德船级社的逻辑,但它失去了包装的意义,对吗?作为一名用户,我希望像这样操作:
gl_texture_2d tex;
tex.mirror_u();
tex.linear_min_filter();
为了实现这一目标,我们必须实现以下功能:
void gl_texture_2d::mirror_u()
{
glBindTexture(GL_TEXTURE_2D, handle());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glBindTexture(GL_TEXTURE_2D, 0);
}
始终在内部执行绑定操作可确保该操作有效。但是成本太高了
代码:
tex.mirror_u();
tex.mirror_v();
将扩展为一对无意义的绑定/解除绑定操作
那么,是否有任何机制可以让编译器知道:
bind(b)
紧接着bind(a)
,则可以删除bind(a)
李>
bind(a)
在一个块中出现两次,则最后一次无效您将无法在编译级别执行此操作。相反,如果您真的担心这类错误的时间成本,那么管理者对象可能是一种方法:
class state_manager {
GLuint current_texture;
/*Maybe other stuff?*/
public:
void bind_texture(gl_texture_2d const& tex) {
if(tex.handle() != current_texture) {
current_texture = tex.handle();
glBindTexture(/*...*/, current_texture);
}
}
};
int main() {
state_manager manager;
/*...*/
gl_texture_2d tex;
manager.bind(tex);
manager.bind(tex); //Won't execute the bind twice in a row!
/*Do Stuff with tex bound*/
}
如果您正在使用,并且您绝对必须直接使用自己的API包装OpenGL调用,那么用户可能需要了解整个绑定到编辑的事情。毕竟,如果他们为了渲染目的绑定了一个纹理,然后试图修改一个纹理,这可能会损坏当前绑定
因此,您应该将绑定到编辑的概念直接构建到API中
也就是说,纹理对象(顺便说一句,不应该仅限于2D纹理)实际上不应该具有修改它的功能,因为不绑定OpenGL纹理(或者不绑定DSA,您确实应该学习DSA)就无法修改它。它不应该有mirror\u
等等;这些函数应该是活页夹对象的一部分:
bound_texture bind(some_texture, tex_unit);
bind.mirror_u();
...
bound_纹理的构造函数
将某些_纹理
绑定到tex_单元
。其成员函数将修改该纹理(注意:它们需要调用glActiveTexture
,以确保没有人更改活动纹理单元)
bound_texture
的析构函数应自动解除纹理绑定。但是您应该有一个release
成员函数来手动解除绑定