[Solved]Sending matrix array to GLSL vertex shader

Started by rherma, May 04, 2013, 15:53:50

Previous topic - Next topic

rherma

Hello.
I am trying to implement skeletal animation using glsl. The skeleton is an array of matrices, I load them into the shader like this:
public void setMatrixArray(String name,boolean transposed, Matrix4f[] matrices){
        int location = uniformMap.get(name);
        FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16*matrices.length);
        for(int i = 0; i<matrices.length; i++)  {
            matrices[i].store(matrixBuffer);
        }
        matrixBuffer.flip();
        GL20.glUniformMatrix4(location,transposed,matrixBuffer);
    }

This does not generate any errors.

My vertex shader looks like this:
#version 330

#define MAX_JOINT_COUNT 33 //The number of joints inside the model
uniform mat4     g_view;
uniform mat4     g_projection;
uniform mat4     g_world;
uniform mat4     g_skeleton[MAX_JOINT_COUNT];

layout(location = 0)in vec3     in_position;
layout(location = 1)in vec3     in_normal;
layout(location = 2)in vec2     in_uv;
layout(location = 3)in vec4     in_indices;
layout(location = 4)in vec4     in_weights;

layout(location = 5)out vec3    out_normal;
layout(location = 6)out vec2    out_uv;

void jointInfluence(in mat4 joint_matrix, in float weight, inout vec3 position)
{
  position += weight * (joint_matrix * vec4(position, 1.0)).xyz;
}
void main()
{
    out_normal = in_normal;
    out_uv     = in_uv;

    jointInfluence(g_skeleton[int(in_indices.x)], in_weights.x, in_position);
    jointInfluence(g_skeleton[int(in_indices.y)], in_weights.y, in_position);
    jointInfluence(g_skeleton[int(in_indices.z)], in_weights.z, in_position);
    jointInfluence(g_skeleton[int(in_indices.w)], in_weights.w, in_position);

    gl_Position = g_projection * g_view * g_world * vec4(in_position,1.0);
}


As soon as I use the g_skeleton array I get the error: "Invalid operation". Note that  the shader is compiling just fine and that the program is running.
I get the error string from GL11.glGetError().

I am obviously doing somthing illeagal with the g_skeleton variable, but I have no idea what that could be?

If i use a fixed index I still get the same error, eg:
   jointInfluence(g_skeleton[0], in_weights.x, in_position);
    jointInfluence(g_skeleton[0], in_weights.y, in_position);
    jointInfluence(g_skeleton[0], in_weights.z, in_position);
    jointInfluence(g_skeleton[0], in_weights.w, in_position);


How ever, if I use another matrix it works just fine, eg:
   jointInfluence(g_world, in_weights.x, in_position);
    jointInfluence(g_world, in_weights.y, in_position);
    jointInfluence(g_world, in_weights.z, in_position);
    jointInfluence(g_world, in_weights.w, in_position);


If some one could point me in the right direction it would be much appreciated.

quew8

You can get the error log with glGetShaderInfoLog. The log is vendor specific but one hopes that it will tell you what the problem is.

rherma

this code:
    jointInfluence(g_skeleton[int(in_indices.x)], in_weights.x, in_position);
    jointInfluence(g_skeleton[int(in_indices.y)], in_weights.y, in_position);
    jointInfluence(g_skeleton[int(in_indices.z)], in_weights.z, in_position);
    jointInfluence(g_skeleton[int(in_indices.w)], in_weights.w, in_position);

    gl_Position = g_projection * g_view * g_world * vec4(in_position,1.0);


Yields:
Quote
Invalid operation (not this is not from the glGetShaderInfoLog)
WARNING: 0:34: warning(#398) l-value required: assign "in_position" (can't modify an input)
WARNING: 0:35: warning(#398) l-value required: assign "in_position" (can't modify an input)
WARNING: 0:36: warning(#398) l-value required: assign "in_position" (can't modify an input)

So I changed it to:
vec3 position = in_position;

    jointInfluence(g_skeleton[int(in_indices.x)], in_weights.x, position);
    jointInfluence(g_skeleton[int(in_indices.y)], in_weights.y, position);
    jointInfluence(g_skeleton[int(in_indices.z)], in_weights.z, position);
    jointInfluence(g_skeleton[int(in_indices.w)], in_weights.w, position);

    gl_Position = g_projection * g_view * g_world * vec4(position,1.0);


Now I don't get warnings from the shader log. How ever, the glGetError still gives me the "Invalid operation".
It feels like the error has to do with my g_skeleton variable, maybe the way I am uploading the matrices?

Anyways, thanks for the tip about glGetShaderInfoLog, very usefull.

rherma

I checked out the documentation for  glUniformMatrix4.
There is one function that seems to do exactly what I am trying to do:
void glUniformMatrix4fv(GLint  location,  GLsizei  count,  GLboolean  transpose,  const GLfloat * value);

How ever, LWJGL has not ported that function.
Is there some usage example how to upload a list of matrices to a unform variable?

rherma

Well this is akward ;)
I set the skeleton variable before i draw each mesh in the model. I bind the shader when i draw a mesh, not before. So my shader is not set when I try to set the skeleton variable, hence the error.

So the sytax for uploading a matrix array is correct.