GLSL中的Cant访问vec4阵列

时间:2019-02-16 16:57:19

标签: opengl graphics glsl

当我尝试在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];

该程序有效。

UPDATE(2):

我解决了这个问题。 原来,我有两个问题,一个是我的组件太多,而由于一个答案提醒我,我解决了这个问题。

另一种是我不能将制服直接放在我认为可以做到的片段着色器中,因此我将颜色放置在顶点着色器中并传递了片段着色器所需的一种颜色。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

uniform mat4 model[100];

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

(来自评论):

  

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

但这并不意味着程序对象成功链接。通常在链接过程中会强制执行此类资源限制。

  

我很确定程序是由openGL成功创建的对象,但是我不确定其他程序。您会发现我是否将片段着色器主函数更改为FragColor = color[0];,它将起作用,所以我想的问题是instanceID

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