【问题标题】:Opengl error 1282 (invalid operation) when using texture()使用纹理()时出现 Opengl 错误 1282(无效操作)
【发布时间】:2023-12-29 00:35:01
【问题描述】:

我有以下片段着色器:

#version 330 core

layout (location = 0) out vec4 color;

uniform vec4 colour;
uniform vec2 light_pos;

in DATA
{
    vec4 position;
    vec2 texCoord;
    float tid;
    vec4 color;
} fs_in;

uniform sampler2D textures[32];

void main()
{
    float intensity = 1.0 / length(fs_in.position.xy - light_pos);

    vec4 texColor = fs_in.color;
    if (fs_in.tid > 0.0)
    {
        int tid = int(fs_in.tid + 0.5);
        texColor = texture(textures[tid], fs_in.texCoord);
    }

    color = texColor * intensity;
}

如果我运行我的程序,我会收到 opengl 错误 1282,这是无效操作。如果我不使用纹理(),所以我写了 texCoord = vec4(...) 它工作得很好。我总是将 tid (纹理 ID)作为 0 (无纹理)传递,因此该部分甚至不应该运行。我已经将纹理统一设置为某个占位符,但据我所知,这甚至不重要。那么什么会导致无效操作呢?

【问题讨论】:

    标签: opengl glsl fragment-shader


    【解决方案1】:

    我知道这个解决方案已经晚了,但如果它对任何人有帮助的话..

    根据 Cherno 的视频,这应该可行。然而,他在纹理索引的 gl_VertexAttribPointer 中使用属性“fs_in.tid”作为“GL_BYTE”,由于某种原因,关于投射 1.0f 总是被转换为 0.0f,因此不起作用。 将 GL_BYTE 更改为 GL_FLOAT 为我解决了这个问题。

    关于“opengl 错误 1282”,这是我遇到的一个非常常见的错误。我曾经忘记在设置任何制服之前调用 glUseProgram(ShaderID)。因此,即使当时没有使用/设置制服也会导致错误,即“1282”。这可能是解决方案之一,这为我解决了。

    【讨论】:

      【解决方案2】:

      您的着色器编译很可能已失败。确保在尝试编译着色器后始终检查编译状态,使用:

      GLint val = GL_FALSE;
      glGetShaderiv(shaderId, GL_COMPILE_STATUS, &val);
      if (val != GL_TRUE)
      {
          // compilation failed
      }
      

      在您的情况下,着色器是非法的,因为您试图访问具有变量索引的采样器数组:

      texColor = texture(textures[tid], fs_in.texCoord);
      

      GLSL 3.30 不支持此功能。来自规范(强调添加):

      在着色器中聚合到数组中的采样器(使用方括号 [])只能使用整数 constant 表达式进行索引(请参阅第 4.3.3 节“常量表达式”)。

      此限制在以后的 OpenGL 版本中有所放宽。例如,来自 GLSL 4.50 规范:

      当在着色器中聚合成数组时,采样器只能使用动态统一的积分表达式进行索引,否则结果是不确定的。

      此更改是在 GLSL 4.00 中引入的。但这仍然不足以满足您的情况,因为您正在尝试使用 in 变量作为索引,这不是动态统一的。

      如果您的纹理大小都相同,您可能需要考虑使用数组纹理。这将允许您根据动态计算的索引对数组纹理中的某一层进行采样。

      【讨论】:

      • 我检查了编译状态,没有失败。但我会调查一下。
      • 这家伙也在做同样的事情,并且以某种方式工作:youtube.com/watch?v=1x4hrdS97cI这有什么不同?
      • 今晚回家后会查看视频。您是否也检查了链接状态?
      • 哦...我没有检查。我会做的。如果视频对您来说太长,上传者有一个带有来源的 Github 帐户。
      • 这很有趣。今天我买了一个带有 OpenGL 4.4 的现代视频卡(旧的只支持 1.3),代码运行起来绝对没有问题!那么如何确保它也适用于 3.3 版左右的其他卡呢?
      最近更新 更多