Apple Silicon M1 上的 GL_TEXTUREn+1 被激活并绑定,而不是 GL_TEXTUREn(可能是错误)

Mor*_*eu5 7 c++ opengl textures apple-silicon apple-m1

让我们首先承认 OpenGL 已被 Apple 弃用,最后支持的版本是 4.1,这很遗憾,但是嘿,我们必须以某种方式向前迈进,Vulkan 就是这样:trollface:现在这已经不再是我们的系统了,让我们看看我发现的这个奇怪的错误。让我澄清一下,我正在 Apple Silicon M1、2020 年底、配备 macOS 11.6 的 MacBook Pro 上运行此程序。让我们继续吧。

我一直在关注LearnOpenGL ,并且在这里发布了我的 WiP来跟踪我的进度。一切都很好,直到我开始使用纹理。使用一种纹理很容易,所以我直接使用多种纹理,这就是我遇到麻烦的时候。据我了解,工作流程或多或少是

  • 将像素数据加载到名为 的字节数组中textureData,以及额外的信息
  • glGenTextures(1, &textureID)
  • glBindTexture(GL_TEXTURE_2D, textureID)
  • 随意设置参数
  • glTexImage2D(GL_TEXTURE_2D, ... , textureData)
  • glGenerateMipmap(GL_TEXTURE_2D)(尽管这可能是可选的)

这就是我在这里所做的,然后

  • glUniform1i(glGetUniformLocation(ID, "textureSampler"), textureID)
  • 冲洗并重复其他纹理

然后,在绘图循环中,我应该具有以下内容:

  • glUseProgram(shaderID)
  • glActiveTexture(GL_TEXTURE0)
  • glBindTexture(GL_TEXTURE_2D, textureID)
  • glActiveTexture(GL_TEXTURE1)
  • glBindTexture(GL_TEXTURE_2D, otherTextureID)

然后,我准备我的奇特片段着色器,如下所示:

#version 410 core

out vec4 FragColor;
in vec2 TexCoord;

uniform sampler2D textureSampler;
uniform sampler2D otherTextureSampler;

void main() {
    if (TexCoord.x < 0.5) {
        FragColor = texture(textureSampler, TexCoord);
    } else {
        FragColor = texture(otherTextureSampler, TexCoord);
    }
}
Run Code Online (Sandbox Code Playgroud)

textureSampler我应该在屏幕上有一个四边形,其纹理由其左半部分和otherTextureSampler右半部分组成。相反,我的otherTextureSampler左半部分是黑色的,另一半是黑色的,并且有一条日志消息,上面写着

不支持(记录一次):可能的问题:单元 1 GLD_TEXTURE_INDEX_2D 不可加载并绑定到采样器类型(Float) - 使用零纹理,因为纹理不可加载

我已经追踪这个 bug 两天了,但互联网上并没有太多相关信息。一些报告指出 Apple 的 GLSL 编译器中可能存在错误,另一些报告指出需要绑定额外的纹理,但没有明显的原因。这三个是我设法找到的最相关的信息:

然而,这些都没有对我有太大帮助。直到我不假思索地做了某件事。眼尖的你们一定会注意到我的 git repo 中的绘图代码略有不同。它在这里说我实际上正在使用GL_TEXTURE1GL_TEXTURE2

据我了解,01是我激活和绑定的两个纹理单元,那么为什么使用纹理单元12产生预期的结果呢?

我尝试在生成纹理之后和绑定它们之前添加调用,但成功率为零glActiveTexture(GL_TEXTURE0)我还尝试使用像这个人建议的1采样器数组,并使用一堆s 和整数索引,但当然我仍然得到错误的结果。if

我花了几个小时尝试每种可能的组合,唯一实用的“解决方案”是使用“+1”纹理单元,GL_TEXTUREnn >= 1.

问题:第一段中表达了所有警告,谁在这里做错了什么?到底是我这个菜鸟试图在现代硬件上学习几十年前的技术,还是这确实是苹果 OpenGL 或 GLSL 编译器实现中的一个错误,所以修复它的可能性为零,我应该继续我的“特殊”硬件制造商的“拐杖?”

Hol*_*Cat 6

您需要传递纹理槽索引glUniform1i(glGetUniformLocation(ID, "textureSampler"), ...),而不是向 传递纹理句柄。

例如,如果您glActiveTexture(GL_TEXTUREn)在绑定纹理之前进行了操作,请传递n.