opengl - glBindTexture 是不是覆盖活动纹理单元的内容

Posted

技术标签:

【中文标题】opengl - glBindTexture 是不是覆盖活动纹理单元的内容【英文标题】:opengl - does glBindTexture overwrite contents of the active texture unitopengl - glBindTexture 是否覆盖活动纹理单元的内容 【发布时间】:2020-06-14 11:16:06 【问题描述】:

我正在寻找glActiveTexture(...)glBindTexture(...) 之间的关系,我找到了awesome answer here,最重要的答案(作者/用户 Alfonse)为我们提供了两个函数如何运行的伪代码,我最了解其中。但是,在其中,他在这样的电话中提到:

glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_2D, object);
glTexImage2D(GL_TEXTURE_2D, ...);  

但通常将纹理绑定到上下文只是为了上传一些数据或修改它。此时绑定到哪个纹理单元并不重要,因此无需设置当前纹理单元。 glTexImage2D 不关心当前活动纹理是 0、1、40 还是其他。

所以我的问题是: 当生成两个纹理时,我们会这样做:

 glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

 glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    


//some more code
//inside the render loop
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);

glDrawElements(...); glSwapBuffers();
//end of render loop

注意,在渲染循环之前的代码中,我使用了两个纹理glBindTexture(...),而没有调用glActiveTexture(...)。由于默认的活动纹理单元是:GL_TEXTURE0,这是否意味着为texture1 设置的参数被texture2覆盖

【问题讨论】:

【参考方案1】:

不,纹理参数(由glTexParameter 设置)是为特定纹理(当前绑定到活动纹理单元的纹理)设置的,而不是为纹理单元(不是GL_TEXTUREi 之一)设置的.


请注意,您对glTextureParameteri 的使用不正确。而不是GL_TEXTURE_2D,它需要一个纹理句柄,由glGenTextures1 返回。您将它与glTexParameteri 混淆了,它确实可以用GL_TEXTURE_2D 调用。

1 正如@derhass 所指出的,glGenTextures(与glCreateTextures 不同)仅保留句柄。仅当您将其传递给glBindTexture 时才会创建具有此句柄的纹理。使用glTexParameter没关系,但如果你想使用glTextureParameteri和其他直接对纹理句柄进行操作的函数,它可能很重要。

【讨论】:

“而不是GL_TEXTURE_2D,它需要一个纹理句柄,由glGenTextures返回”。这是 GL 直接状态访问更微妙的奇怪之处之一,因为 glGen*() 函数实际上只保留名称而不创建任何内容,khronos 必须添加 glCreate*()。因此,准确地说,该语句将是“它需要一个纹理句柄,由glCreateTextures 返回或由glGenTextures 保留,然后是glBindTexture 以实际创建它”。 @juztcode 通过阅读文档。请注意,glBindTexture 永远不会影响当前绑定的纹理对象,它只是建立该绑定。 @juztcode "relationship betn texture units and glbindTexture() 和 glActiveTexture" 简而言之:对于大多数类型的 GL 对象,只能绑定一个对象(或“活动” ) 一次。例如。如果您使用glBindBuffer(GL_ARRAY_BUFFER, x); 绑定顶点缓冲区,则先前绑定的顶点缓冲区将自动解除绑定。但是对于纹理,有不止一个“绑定点”(它们被称为“纹理单元”,并命名为GL_TEXTUREi (i >= 0))。您可以同时绑定多个 2D 纹理 (GL_TEXTURE_2D),只要它们绑定到不同的单元即可。 [1/2] [2/2] glActiveTexture 选择活动纹理单元(默认为GL_TEXTURE0)。随后的glBindTexture 调用将内容绑定到该单元。 (一个单元只能同时绑定一个GL_TEXTURE_2D。) @derhass 很难说所有功能,但是是的,我认为它们中的大多数都在纹理本身而不是纹理单元上工作。顺便说一句,您不需要为我发布单独的 cmets。您可以 ping @derhass,我会收到通知,因为 cmets 在我的回答中。

以上是关于opengl - glBindTexture 是不是覆盖活动纹理单元的内容的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL glBindTexture() 崩溃

OpenGL,禁用纹理单元、glActiveTexture 和 glBindTexture

C++学习(二七四)undefined reference to `glBindTexture‘

osg学习(六十五)图片到纹理

当CSDN携手Markdown

我爱Markdown