Mak*_*gan 3 c++ opengl textures
为了使用纹理单元,我们通常将它或多或少地绑定到当前进程:
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
GLint loc = glGetUniformLocation(program, "uniform");
//error check
glUniform1i(loc,0);
Run Code Online (Sandbox Code Playgroud)
你如何"释放"纹理单元.换句话说,如何从当前程序中的纹理单元绑定点分离纹理?
你如何"释放"纹理单元.换句话说,如何从当前程序中的纹理单元绑定点分离纹理?
您不能"释放"纹理单元,但可以将默认纹理对象绑定到纹理单元.
请参阅OpenGL 4.6 API兼容性配置文件规范; 8.1纹理对象; 第178页:
GL中的纹理由命名对象表示.纹理对象的名称空间是无符号整数,GL保留零以表示默认纹理对象.
...
通过调用实现绑定
Run Code Online (Sandbox Code Playgroud)void BindTexture( enum target, uint texture );将目标设置为所需的纹理目标,并将纹理设置为未使用的名称.
这意味着
GLuint defaultTextureObjectID = 0;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, defaultTextureObjectID);
Run Code Online (Sandbox Code Playgroud)
将默认纹理对象绑定到纹理单元0.
从OpenGL 4.5开始就可以使用它 glBindTextureUnit
命令
Run Code Online (Sandbox Code Playgroud)void BindTextureUnit( uint unit, uint texture );将现有纹理对象绑定到编号
unit的纹理单元.texture必须为零或现有纹理对象的名称.如果texture是现有纹理对象的名称,则该对象将绑定到创建对象时指定的相应纹理单元中的目标.
所以你也可以使用以下内容:
glBindTextureUnit( 0, 0 ); // texture unit 0, default texture object (0)
Run Code Online (Sandbox Code Playgroud)
从严格意义上来说……你不能。您可以绑定纹理对象 0,但这被认为是有效的纹理对象(尽管它的行为明显很奇怪)。您可以使用非 DSA 函数来填充数据并(大部分)像常规纹理一样使用它。
现在,是的,大多数现代 OpenGL 用户从不使用纹理对象 0。他们将其保留为默认状态,并将绑定它视为不使用纹理单元。事实上,传递 0 会glBindTextureUnit导致该纹理单元的所有纹理目标都绑定 0(而使用常规对象仅将该对象的目标绑定到该单元,而单元内的其他目标不受干扰)。
话虽如此,请允许我对此给出一个不寻常的观点:您不必从上下文中解除纹理的绑定。
如果程序不使用纹理单元,则某些东西绑定到该单元的事实是无关紧要的。绑定到纹理单元的纹理不会阻止您使用其他纹理单元;只有程序使用的那些(与正确的纹理类型匹配)才真正重要。删除纹理将导致它们自动从上下文中解除绑定(但仅限于当前上下文;如果您有多个上下文,它们仍然会绑定在那里)。
所以它并没有真正起到解除纹理绑定的作用。事实上,它可以有一定的优势。
如果您不小心使用了 0 绑定(概念上未绑定)的纹理单元,则可能会收到 OpenGL 错误。但你可能不会。如果不这样做,则会得到包含白色像素的纹理。这对于您的代码来说可能是明显错误的,也可能不是明显错误。
相比之下,如果你不小心使用了绑定了旧数据的纹理单元,你要么会得到一个 OpenGL 错误,要么你肯定会得到一些明显错误的东西。
因此,如果您将纹理留在那里,如果您不小心没有绑定某些东西,则更有可能出现问题。
| 归档时间: |
|
| 查看次数: |
165 次 |
| 最近记录: |