返回带有uint数组成员的结构时出现OpenGL错误1282

bfhwhh0e  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(282)

当我尝试使用一个函数运行片段着色器时,我收到OpenGL错误1282,该函数返回带有从函数参数和整数文字初始化的uint数组的结构。
当我用下面的片段着色器运行我的程序时,一切都正常,结果我得到的是白色


# version 460

uniform uint param;
out vec4 color;

struct A {
    uint content[2];
};

A createA1(const uint data) { return A( uint[2](data, data) ); }
A createA2(const uint data) { return A( uint[2](data, 0   ) ); }
A createA3(const uint data) { return A( uint[2](data, 0u  ) ); }
A createA4(const uint data) { return A( uint[2](0   , 0   ) ); }

void main() {
    const uint o = param;

    const A a0 = A( uint[2](o, 0) );
    const A a1 = createA1(o);
    //const A a2 = createA2(o);
    const A a3 = createA3(o);
    const A a4 = createA4(o);

    color = vec4(1);
}

但是当我用a2取消注解该行时,我得到OpenGL错误1282。
我在代码上尝试了glslangValidator,它没有输出任何错误。对我来说同样奇怪的是,同样使用相同的零字面值的 a4 没有产生任何错误。而且似乎 o 是从uniform初始化的,因为如果我用某个字面值替换uniform,错误就会消失。
如果它实际上是一个错误(在我看来),而不是一些glsl的特点,我测试的着色器中的程序是运行在Windows与Nvidia显卡。
UPD:所以我没有足够地澄清这个问题:着色器编译时没有错误,但程序没有链接,我得到1282。我调用了glCreateProgram,对于片段和顶点着色器,我调用了glCreateShaderglShaderSourceglCompileShaderglGetShaderivGL_COMPILE_STATUS,打印了 param 值(对于两个着色器,结果都是1),然后是glAttachShaderglLinkProgram,中间没有其他调用。当我检查GL_LINK_STATUS时,结果是0。
当我打印程序对象的信息日志时,它说

Fragment info
-------------
0(11) : error C7011: implicit cast from "int" to "uint"

这是意料之中的,因为 a3 是问题的解决方案。但我不明白两件事:
1.为什么 a0 有效而 a2 无效,因为它们中存在相同的隐式转换,以及为什么如果我为 o 赋某个整数常量而不是统一值,错误就会消失。
1.为什么编译后着色器状态为1,而程序对象表示着色器中存在错误。
为了完整起见,以下是整个程序:


# include <GLEW/glew.h>

# include <GLFW/glfw3.h>

# include<iostream>

void check_(int line) {
    GLenum error;
    while ((error = glGetError()) != GL_NO_ERROR) { 
        std::cout << "Error on line " << line << ": " << error << std::endl;
    }
}

# define check() check_(__LINE__)

int main() {
    if (!glfwInit()) return -1;
    GLFWwindow *window = glfwCreateWindow(50, 50, "", NULL, NULL);
    if (!window) return (glfwTerminate(), -1);
    glfwMakeContextCurrent(window);
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        std::cout << "GLEW error: %s\n" << glewGetErrorString(err) << '\n';     
        glfwTerminate();
        return -1;
    }

    GLuint prog = glCreateProgram();

    GLuint shader_vert = glCreateShader(GL_VERTEX_SHADER);
    GLuint shader_frag = glCreateShader(GL_FRAGMENT_SHADER);

    char const *source_vert = R"(#version 460
        void main() {
            const vec2 verts[] = {vec2(-1),vec2(1, -1),vec2(-1, 1),vec2(1)};
            gl_Position = vec4( verts[gl_VertexID], 0, 1 );
        }
    )";
    char const *source_frag = R"(#version 460

        uniform uint param;
        out vec4 color;

        struct A {
            uint content[2];
        };

        A createA1(const uint data) { return A( uint[2](data, data) ); }
        A createA2(const uint data) { return A( uint[2](data, 0   ) ); }
        A createA3(const uint data) { return A( uint[2](data, 0u  ) ); }
        A createA4(const uint data) { return A( uint[2](0   , 0   ) ); }

        void main() {
            const uint o = param;

            const A a0 = A( uint[2](o, 0) );
            const A a1 = createA1(o);
            const A a2 = createA2(o);
            const A a3 = createA3(o);
            const A a4 = createA4(o);

            color = vec4(1);
        }
    )";

    glShaderSource(shader_vert, 1, &source_vert, nullptr); 
    glCompileShader(shader_vert);
    glShaderSource(shader_frag, 1, &source_frag, nullptr); 
    glCompileShader(shader_frag);

    GLint result_vert;
    glGetShaderiv(shader_vert, GL_COMPILE_STATUS, &result_vert);
    std::cout << "result_vert: " << result_vert << '\n';
    GLint result_frag;
    glGetShaderiv(shader_frag, GL_COMPILE_STATUS, &result_frag);
    std::cout << "result_frag: " << result_frag << '\n';
    //check(); //additional checks were ommited after the problem was found

    glAttachShader(prog, shader_vert);
    glAttachShader(prog, shader_frag);

    glLinkProgram(prog);
    GLint progStatus;
    glGetProgramiv(prog, GL_LINK_STATUS, &progStatus);
    std::cout << "Program status: " << progStatus << '\n';
    {
        int length;
        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &length);
        GLchar *msg = new GLchar[length + 1];
        msg[0] = '\0';
        glGetProgramInfoLog(prog, length, &length, msg);
        std::cout << "Program error:\n" << msg;
        delete[] msg;
    }

    glValidateProgram(prog);
    GLint progValidate;
    glGetProgramiv(prog, GL_VALIDATE_STATUS, &progValidate);
    std::cout << "Program valid: " << progValidate << '\n';
    //check();

    glUseProgram(prog);
    check();

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    return 0;
}
3ks5zfa0

3ks5zfa01#

1282是OpenGL的所有无效操作错误,它什么也不说。
启用调试层并检查着色器编译的结果和(因为它可能失败)生成的信息日志,以查看实际问题。
如果它实际上是一个错误(在我看来)
不,你不是这个世界上唯一一个在编译着色器时发现错误的人。检查你的错误返回,启用调试层并修复你的代码。

相关问题