[英]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
据我了解,工作流程或多或少
textureData
, plus extra infotextureData
的字节数组中加载像素数据,以及额外的信息glGenTextures(1, &textureID)
glBindTexture(GL_TEXTURE_2D, textureID)
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这就是我在这里做的,然后
glUniform1i(glGetUniformLocation(ID, "textureSampler"), textureID)
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_TEXTURE1
和GL_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?我的理解是
0
和1
是我激活和绑定的两个纹理单元,那么为什么使用纹理单元1
和2
会产生预期的结果呢?
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_TEXTUREn
和n >= 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.