当我尝试使用一个函数运行片段着色器时,我收到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
,对于片段和顶点着色器,我调用了glCreateShader
、glShaderSource
、glCompileShader
、glGetShaderiv
和GL_COMPILE_STATUS
,打印了 param 值(对于两个着色器,结果都是1),然后是glAttachShader
和glLinkProgram
,中间没有其他调用。当我检查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;
}
1条答案
按热度按时间3ks5zfa01#
1282是OpenGL的所有无效操作错误,它什么也不说。
启用调试层并检查着色器编译的结果和(因为它可能失败)生成的信息日志,以查看实际问题。
如果它实际上是一个错误(在我看来)
不,你不是这个世界上唯一一个在编译着色器时发现错误的人。检查你的错误返回,启用调试层并修复你的代码。