【问题标题】:Cant access vec4 array in GLSL无法访问 GLSL 中的 vec4 数组
【发布时间】:2019-02-17 06:26:03
【问题描述】:

当我尝试在 OpenGL 4.0 中编译此 GLSL 代码时,我收到错误 1282

顶点着色器:

#version 330 core
layout(location = 0) in vec2 aPos;

uniform mat4 model[100];
uniform mat4 projection;

out int instanceID;

void main()
{
    instanceID = gl_InstanceID;
    gl_Position = projection * model[gl_InstanceID] * vec4(aPos.x, aPos.y, 0.0, 1.0);
}

片段着色器:

#version 330 core

in int instanceID;
out vec4 FragColor;

uniform vec4 color[100];

void main()
{
    FragColor = color[instanceID];
}

代码是常规的 ShaderProgram 创建,因为我在绘制之前收到错误或类似的错误,但以防万一这里是代码:

    unsigned int vertex, fragment;

    vertex = glCreateShader(GL_VERTEX_SHADER);
    std::string vShaderCode = ReadEntireTextFile(vertPath);
    const char* c_vShaderCode = vShaderCode.c_str();
    glShaderSource(vertex, 1, &c_vShaderCode, NULL);
    glCompileShader(vertex);


    std::string fShaderCode = ReadEntireTextFile(fragPath);
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    const char* c_fShaderCode = fShaderCode.c_str();
    glShaderSource(fragment, 1, &c_fShaderCode, NULL);
    glCompileShader(fragment);
    // shader Program
    m_RendererID = glCreateProgram();
    glAttachShader(m_RendererID, vertex);
    glAttachShader(m_RendererID, fragment);

    glLinkProgram(m_RendererID);
    // delete the shaders as they're linked into our program now and no longer necessery
    glDeleteShader(vertex);
    glDeleteShader(fragment);
    glUseProgram(m_RendererID);

我确定错误是由于 instanceID 造成的,因为它在着色器没有它时起作用。但我试图找出问题所在,但没有运气。

更新:

确保着色器已成功编译。结果他们编译成功了。

我能够查明错误发生的位置,它是 glUseProgram 函数。

我认为错误是因为 instanceID 因为当我更改时:

FragColor = color[instanceID];

到

FragColor = color[0];

程序有效。

更新(2):

我解决了这个问题。 原来我有 2 个问题,一个是我有太多组件,我解决了这个问题,这要感谢其中一个提醒我的答案。

另一个是我不能将制服直接放入片段着色器中,我认为你可以这样做。所以我将颜色放入顶点着色器中,并传递了片段着色器所需的一种颜色。

感谢您的帮助!

【问题讨论】:

  • 哪个 gl 调用导致了错误?你能发布那个代码吗?
  • 它是 glUseProgram。
  • 你应该检查编译日志,看看它是否编译正确。拨打glCompileShader()后,您需要拨打glGetShaderInfoLog()。
  • 它不返回任何片段和顶点着色器和 glGetShaderiv(shader, GL_COMPILE_STATUS, &output);两个着色器都返回 true。
  • 根据documentation,如果“程序不是程序对象”、“程序不能成为当前状态的一部分”或“变换反馈模式处于活动状态”。所以它一定是这三件事之一。

标签: opengl graphics glsl


【解决方案1】:
uniform mat4 model[100];

这超出了规范的保证范围。这里的限制是GL_MAX_VERTEX_UNIFORM_COMPONENTS,规范保证至少为 1024。由于mat4 消耗 16 个组件,因此最多为 64 个矩阵。现在您的特定限制可能更高,但您的程序中还有其他制服,例如 color[100]。

(来自 cmets):

它不会为片段和顶点着色器返回任何内容,glGetShaderiv(shader, GL_COMPILE_STATUS, &output); 对两个着色器都返回 true。

但这并不意味着程序对象链接成功。这种资源限制通常在链接期间强制执行。

我很确定 program 是由 openGL 成功创建的对象,但我不太确定其他对象。你看看我是否将片段着色器主函数更改为FragColor = color[0]; 它会起作用,所以我认为问题出在instanceID 上。

这个结论不成立。如果您编写color[0],它会将您的vec4r[100] 数组优化为vec4[1],并且您可能会低于您的特定限制。

【讨论】:

  • 我尝试将矩阵和 vec4 的大小从 100 更改为 10,这应该远低于 1024 个分量,但我仍然得到相同的错误:(
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多