简体   繁体   English

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

[英]GL_TEXTUREn+1 activated and bound instead of GL_TEXTUREn on Apple Silicon M1 (possible bug)

Let's first acknowledge that OpenGL is deprecated by Apple, that the last supported version is 4.1 and that that's a shame but hey, we've got to move forward somehow and Vulkan is the way:trollface: Now that that's out of our systems, let's have a look at this weird bug I found.让我们首先承认 OpenGL 已被 Apple 弃用,最后支持的版本是 4.1,这很遗憾,但是嘿,我们必须以某种方式向前迈进,Vulkan 就是这样:trollface:现在这已经超出了我们的系统,让我们看看我发现的这个奇怪的错误。 And let me be clear that I am running this on an Apple Silicon M1, late 2020 MacBook Pro with macOS 11.6.让我明确一点,我在 Apple Silicon M1、2020 年末配备 macOS 11.6 的 MacBook Pro 上运行它。 Let's proceed.让我们继续。

I've been following LearnOpenGL and I have published my WiP right here to track my progress.我一直在关注LearnOpenGL ,并在此处发布了我的 WiP 以跟踪我的进度。 All good until I got to textures.一切都很好,直到我得到纹理。 Using one texture was easy enough so I went straight into using more than one, and that's when I got into trouble.使用一种纹理很容易,所以我直接使用了不止一种纹理,这就是我遇到麻烦的时候。 As I understand it, the workflow is more or less据我了解,工作流程或多或少

  • load pixel data in a byte array called textureData , plus extra info在名为textureData的字节数组中加载像素数据,以及额外的信息
  • glGenTextures(1, &textureID)
  • glBindTexture(GL_TEXTURE_2D, textureID)
  • set parameters at will随意设置参数
  • glTexImage2D(GL_TEXTURE_2D, ... , textureData)
  • glGenerateMipmap(GL_TEXTURE_2D) (although this may be optional) glGenerateMipmap(GL_TEXTURE_2D) (虽然这可能是可选的)

which is what I do around here , and then这就是我在这里做的,然后

and then, in the drawing loop, I should have the following:然后,在绘图循环中,我应该有以下内容:

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

I then prepare my fancy fragment shader as follows:然后我准备我的花哨的片段着色器如下:

#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);
    }
}

and I should have a quad on screen with a texture made up by textureSampler on its left half, and otherTextureSampler on its right half.我应该在屏幕上有一个四边形,它的左半边是由textureSampler组成的纹理,右半边是otherTextureSampler Instead, I have otherTextureSampler on the left half, black on the other half, and a log message that says相反,我在左半边有otherTextureSampler ,在另一半有黑色,还有一条日志消息说

UNSUPPORTED (log once): POSSIBLE ISSUE: unit 1 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable不支持(记录一次):可能的问题:单元 1 GLD_TEXTURE_INDEX_2D 可卸载并绑定到采样器类型(浮点数)-使用零纹理,因为纹理不可加载

I've been on this bug's trail for two days now and there just isn't very much on the Internet.我已经在这个错误的踪迹上两天了,互联网上没有太多。 Some reports point to a possible bug in Apple's GLSL compiler, some others point to the need for binding an extra texture for no apparent reason.一些报告指出 Apple 的 GLSL 编译器中可能存在错误,另一些则指出需要绑定额外的纹理,但没有明显的原因。 These three are the most relevant pieces of information I managed to find:这三个是我设法找到的最相关的信息:

However, none of these helped me very much.但是,这些都没有对我有太大帮助。 Until I did something without thinking.直到我不假思索地做了一件事。 The eagle-eyed among you will have noticed that the drawing code in my git repo is slightly different.眼尖的人会注意到,我的 git repo 中的绘图代码略有不同。 It says right here that I am in fact using GL_TEXTURE1 and GL_TEXTURE2 .在这里说我实际上正在使用GL_TEXTURE1GL_TEXTURE2

It was my understanding that 0 and 1 were the two texture units that I was activating and binding, so why does using texture units 1 and 2 yield the expected result?我的理解是01是我激活和绑定的两个纹理单元,那么为什么使用纹理单元12会产生预期的结果呢?

I tried to add calls to glActiveTexture(GL_TEXTURE0) and 1 right after generating the textures and before binding them, but with zero success.我尝试在生成纹理之后和绑定它们之前添加对glActiveTexture(GL_TEXTURE0)1的调用,但成功率为零。 I also tried using a sampler array like this person suggests and going in with a bunch of if s and integer indices, but of course I was still getting the wrong result.我还尝试使用这个人建议的采样器数组,并使用一堆if s 和 integer 索引,但当然我仍然得到错误的结果。

I spent a few hours trying every possible combination and the only practical "solution" is to use "+1" texture units, as in GL_TEXTUREn with n >= 1 .我花了几个小时尝试所有可能的组合,唯一实用的“解决方案”是使用“+1”纹理单元,如GL_TEXTUREnn >= 1

Question: with all the caveat expressed in the very first paragraph, who is doing something wrong here?问题:在第一段中表达了所有警告,谁在这里做错了什么? Is it noob me who's trying to learn decades old technology on modern hardware, or is it genuinely a bug in Apple's implementation of OpenGL or the GLSL compiler, and so there's zero chance of having it fixed and I should just get on with my "special hardware manufacturer's" crutches?是我试图在现代硬件上学习几十年前的技术,还是真的是 Apple 实现 OpenGL 或 GLSL 编译器中的一个错误,所以修复它的可能性为零,我应该继续我的“特别硬件制造商的“拐杖”?

Instead of passing a texture handle to glUniform1i(glGetUniformLocation(ID, "textureSampler"), ...) , you need to pass a texture slot index.无需将纹理句柄传递给glUniform1i(glGetUniformLocation(ID, "textureSampler"), ...) ,您需要传递纹理槽索引。

Eg if you did glActiveTexture(GL_TEXTUREn) before binding the texture, pass n .例如,如果您在绑定纹理之前执行了glActiveTexture(GL_TEXTUREn) ,则传递n

I know this has been answered for this particular case, although I've been having the same error message even after setting correctly the glsl uniform texture binding (" unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) ").我知道这已经针对这种特殊情况得到了回答,尽管即使在正确设置 glsl 统一纹理绑定之后我也遇到了相同的错误消息(“ unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) ”)。

I'm also on a Mac M1, using OpenGL 2.1 I had a wrong parameter set for the texture sampler ( GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR , but no mipmap was bound) and setting a "good" one solved the issue.我也在 Mac M1 上,使用 OpenGL 2.1 我为纹理采样器设置了错误的参数( GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ,但没有绑定 mipmap)并设置一个“好”的参数解决了这个问题。

Rationale for other devs having the same error message: also check that texture sampler parameters are correct.其他具有相同错误消息的开发人员的理由:还要检查纹理采样器参数是否正确。

Cheers干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM