7
votes

I run

glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVertUniformsVect);

and get 1024.

Than in GLSL I do

uniform mediump vec4[1020] instance_mat

and that was ok. But with vec3/vec2/float it fails:

uniform mediump float[1030] instance_mat;          // fails
//uniform mediump vec2[1030] instance_mat;         // and this
//uniform mediump vec3[1030] instance_mat;         // and this

With following error:

cannot locate suitable resource to bind variable "instance_mat". Possibly large array.

The question is: Does GL_MAX_VERTEX_UNIFORM_VECTORS return the number of all kind of arrays, no matter what size they are? I mean, no matter does this float/vec2/vec3/vec4 - all counts as one VERTEX_UNIFORM_VECTOR?


Vertex shader code, as is:

#version 120
uniform mediump float[1200] instance_mat;        //mat4x3
attribute mediump float instaceIdF;             // in range 0..1000 Will be converted to int

attribute mediump vec3 vertex_;
attribute lowp vec4 color;
uniform mediump mat4 matrix;
varying lowp vec4 v_color;

void main(void)
{
    v_color = color;


        int instaceId = int(instaceIdF) * 12;
        mediump mat4 offsetMat = mat4(
                                    vec4(instance_mat[instaceId],   instance_mat[instaceId+1], instance_mat[instaceId+2], 0),
                                    vec4(instance_mat[instaceId+3], instance_mat[instaceId+4], instance_mat[instaceId+5], 0),
                                    vec4(instance_mat[instaceId+6], instance_mat[instaceId+7], instance_mat[instaceId+8], 0),
                                    vec4(instance_mat[instaceId+9], instance_mat[instaceId+10], instance_mat[instaceId+11], 1)
                                 );

        /*mediump mat4 offsetMat = mat4(
                                    vec4(instance_mat[instaceId].xyz, 0),
                                    vec4(instance_mat[instaceId+1].xyz, 0),
                                    vec4(instance_mat[instaceId+2].xyz, 0),
                                    vec4(instance_mat[instaceId+3].xyz, 1)
                                 );*/
        gl_Position = matrix * offsetMat * vec4(vertex_, 1.0);
        //gl_Position = matrix * vec4(vertex, 1.0);


}
2
GL_MAX_VERTEX_UNIFORM_COMPONENTS returns aprox 16000. And I have nVidia, not ATI. So I think its true. :)tower120
Can you show your entire shader? I think there is some confusion here, and the information in the accepted answer is incorrect. GL_MAX_VERTEX_UNIFORM_VECTORS refers to the sum total maximum size of all active uniforms in the vertex shader stage. If you have any other uniforms, the maximum length of an array you can support will be smaller.Andon M. Coleman
Thank you for updating your question. Now, your issue is actually the version of GLSL you are using. There is no such thing as GL_MAX_VERTEX_UNIFORM_VECTORS in GLSL 1.20. All you have is GL_MAX_VERTEX_UNIFORM_COMPONENTS. In GLSL, this constant can be referenced by: gl_MaxVertexUniformComponents and it has a minimum implementation limit of 512. You are consuming 1200 + 16 uniform components in your vertex shader (1200 for the array and 16 for the mat4). Try declaring something along the lines of: uniform mediump float instance_mat [gl_MaxVertexUniformComponents - 16];Andon M. Coleman
You also have your array subscript around the wrong part of the declaration if you are trying to create a uniform array.Andon M. Coleman
"uniform mediump float instance_mat [gl_MaxVertexUniformComponents - 16];" - Same error.tower120

2 Answers

6
votes

According to http://www.opengl.org/wiki/Uniform_%28GLSL%29 (Implementation limits):

Implementation note: OpenGL implementations are allowed to reject shaders for implementation-dependent reasons. So you can have fewer active uniform components by your reckoning and still fail to link due to uniform limits. This is usually on hardware that is innately vector hardware. Pre-GeForce 8xxx hardware, and all ATi hardware does this. In this case, you should assume that each separate uniform takes up 4 components, much like it would in D3D. That means a "uniform float" is 4 components, a mat2x4 is 16 components (each row is 4 components), but a mat4x2 is 8 components.

Which is my case, also. But it not has to be always like that. Of course, for compatible reasons it is always better to count each float/vec2/vec3 uniform value, as max size value (vec4)

2
votes

The OpenGL Docs says it all.

GL_MAX_VERTEX_UNIFORM_VECTORS

data returns one value, the maximum number of 4-vectors that may be held in uniform variable storage for the vertex shader. The value of GL_MAX_VERTEX_UNIFORM_VECTORS is equal to the value of GL_MAX_VERTEX_UNIFORM_COMPONENTS and must be at least 256.

Thereby that means that no matter the type, you can only hold an array of max GL_MAX_VERTEX_UNIFORM_VECTORS in length. Even though that vec4 == 4 floats

The maximum value of course vary by the different hardward implementations and how old/new the individual graphics card may be of OpenGL.