Abdullrahman Salim
Abdullrahman Salim

Reputation: 77

Cant access vec4 array in GLSL

When I try to compile this GLSL code in OpenGL 4.0 I get error 1282

Vertex shader:

#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);
}

Fragment shader:

#version 330 core

in int instanceID;
out vec4 FragColor;

uniform vec4 color[100];

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

The code is regular ShaderProgram creation because I get the error before drawing or anything like that but just in case here is the code:

    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);

I know for sure that the error is because of instanceID because it worked when the shader didn't have that. but I tried to find where the problem is exactly with no luck.

UPDATE:

Made sure shaders were compiled successfully. and turns out they are compiled successfully.

I was able to pinpoint where the error occurs and it was the glUseProgram funtion.

I think the error is because of instanceID because when I change:

FragColor = color[instanceID];

to

FragColor = color[0];

the program works.

UPDATE(2):

I solved the problem. Turns out I had 2 problems one being that I had too many components and I fixed that thanks to one of the answers alerting me.

The other was that I can't put uniforms directly in the fragment shader which I thought you could do.So I put the colors in the vertex shader and passed the one color I needed for the fragment shader.

Thanks for the help!

Upvotes: 1

Views: 2212

Answers (1)

derhass
derhass

Reputation: 45332

uniform mat4 model[100];

That is way outside of what is guaranteed by the spec. The limit here is GL_MAX_VERTEX_UNIFORM_COMPONENTS, which the spec guarantees to be at least 1024. Since a mat4 consumes 16 components, that's 64 matrices at most. Now your particular limit might be higher, but you also have the other uniforms in your program, like color[100].

(from comments):

It does not return anything for both fragment and vertex shaders and glGetShaderiv(shader, GL_COMPILE_STATUS, &output); returns true for both shaders.

But that does not imply that the program object linked successfully. Such ressource limits are usually enforced during linking.

I'm pretty sure program is an object created by openGL successfully, I'm not really sure about the others though. you see if i change the fragment shader main function to FragColor = color[0]; it will work so the issue is with instanceID I think.

That conclusion does not follow. If you write color[0], it will optimize your vec4r[100] array to vec4[1], and you might get below your particular limit.

Upvotes: 3

Related Questions