OpenGL - 绑定到默认纹理的做法?
OpenGL - Practice of binding to default texture?
我注意到有些人选择将默认纹理绑定到他们在每个渲染循环中使用的每个纹理单元。这是常见/最佳实践吗?
伪示例:
Tick() {
glUseProgram(someProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, imgTexture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, imgTexture2);
.
.
.
//Is the following really necessary: ???
glUseProgram(0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
}
如果这里不需要,那么是否应该在释放资源之前进行此类调用?
这对于删除对象不是必需的。删除对象时,它会自动从每个绑定点取消绑定。这仅适用于发出glDelete*
命令的上下文;共享对该对象的访问权限的其他上下文不会取消绑定该对象。如果对象附加到另一个对象(例如附加到帧缓冲区的纹理),则也不会取消附加。
自己清理也不是一个坏主意,主要是为了避免错误。如果着色器尝试访问绑定了某些内容的纹理单元,它可能会"工作",从而隐藏错误。然而,如果它试图访问一个没有任何绑定的单元,它更有可能明显失败。
当然,这主要用于调试,因此您可以#ifdef
此类代码以在发布版本中删除它。
但是,上述假设您基本上是在完成纹理渲染后解除绑定纹理。我之所以提出这一点,是因为您显示的从每个纹理单元取消绑定的代码不正确。为什么?
因为每个纹理单元都有多个绑定点,每种类型的纹理对应一个绑定点。因此,如果将纹理绑定到GL_TEXTURE_CUBE_MAP
,调用glBindTexture(GL_TEXTURE2D, 0)
不会对绑定到立方体映射目标的纹理执行任何操作。
因此,如果要编写从每个纹理单元取消绑定纹理的代码,则必须使用存在的每个纹理目标调用glBindTexture
:
void UnbindFromTextureUnit(int unit)
{
static const GLenum allTargets[] = {/*Every texture target that exists*/};
glActiveTexture(GL_TEXTURE0 + unit);
for(auto target : allTargets)
glBindTexture(target, 0);
}
或者,您可以使用 GL 4.4 中的多重绑定glBindTextures
。或者直接状态访问 4.5glBindTextureUnit()
.
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 如何使用默认参数等选择模板专业化
- 具有默认模板参数的多态类的模板推导失败
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 初始化具有非默认构造函数的std::数组项的更好方法
- 何时提供默认参数作为模板参数
- 是默认情况下分配给char数组常量的值
- SFML纹理像播放器
- 具有默认值的引用获取函数
- OpenGL大的3D纹理(>2GB)非常慢
- 具有默认模板类型的默认构造函数的类型推导
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 当给定默认值时,为什么此模板参数推导失败
- 修改 VS Code 中的默认C++代码段
- 着色器纹理值与创建纹理时写入的值不同
- 声明默认的模板化函数
- OpenGL - 绑定到默认纹理的做法?
- 是否可以将纹理作为渲染目标附加到默认的FrameBuffer