首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当返回带有uint数组成员的结构时,OpenGL错误1282

当返回带有uint数组成员的结构时,OpenGL错误1282
EN

Stack Overflow用户
提问于 2022-04-04 17:09:24
回答 1查看 272关注 0票数 0

当我试图运行带有函数的片段着色器时,我得到了OpenGL错误1282,该函数返回带有从函数参数和整数文本初始化的uint数组的结构。

当我使用下面的片段着色器运行我的程序时,一切正常,我得到的结果是白色屏幕。

代码语言:javascript
运行
复制
#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是从制服初始化的,因为如果我用一些文字值替换制服,错误就消失了。

如果它实际上是一个bug (在我看来),而不是一些glsl的特性,那么我测试着色器的程序是在Windows上使用Nvidia图形卡运行的。

UPD:所以我没有充分澄清这个问题:着色器编译时没有错误,但是程序没有链接,我得到了1282。我调用了glCreateProgram,对于glCreateShaderglShaderSourceglCompileShaderglGetShaderivGL_COMPILE_STATUS的代码段和顶点着色器,打印了param值(对于这两种着色器,结果是1),glAttachShaderglLinkProgram之后使用noE 210中间的其他调用。但是,当我检查GL_LINK_STATUS时,结果是0。

当我打印程序对象的信息日志时,它说

代码语言:javascript
运行
复制
Fragment info
-------------
0(11) : error C7011: implicit cast from "int" to "uint"

这是预料中的,因为a3是问题的解决方案。但我不明白两件事:

为什么

  1. 为什么a0工作并且a2不存在,因为它们都存在相同的隐式强制转换,以及为什么如果我将一些整数常量而不是一致值赋给o.
  2. ,为什么在编译后的着色器状态为1,而程序对象说着色器中有错误时,错误就消失了。

为了完整起见,这里是整个程序:

代码语言:javascript
运行
复制
#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;
}
EN

回答 1

Stack Overflow用户

发布于 2022-04-04 17:16:57

1282是OpenGL的所有无效操作错误,它什么也没有说.

启用调试层并检查着色器编译的结果,以及(因为可能失败)生成的信息日志,以查看实际问题。

如果它实际上是一个bug (在我看来是这样)

不,你不是这个世界上唯一一个在编译着色器时发现错误的人。检查错误返回,启用调试层并修复代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71741125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档