Hello Guest

[Solved]Sending matrix array to GLSL vertex shader

  • 4 Replies
  • 13926 Views
[Solved]Sending matrix array to GLSL vertex shader
« on: May 04, 2013, 15:53:50 »
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:
Code: [Select]
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:
Code: [Select]
#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:
Code: [Select]
   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:
Code: [Select]
   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.
« Last Edit: May 05, 2013, 13:49:33 by rherma »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Sending matrix array to GLSL vertex shader
« Reply #1 on: May 04, 2013, 20:27:24 »
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.

Re: Sending matrix array to GLSL vertex shader
« Reply #2 on: May 04, 2013, 21:31:28 »
this code:
Code: [Select]
    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:
Code: [Select]
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.
« Last Edit: May 04, 2013, 22:09:41 by rherma »

Re: Sending matrix array to GLSL vertex shader
« Reply #3 on: May 05, 2013, 13:12:51 »
I checked out the documentation for  glUniformMatrix4.
There is one function that seems to do exactly what I am trying to do:
Code: [Select]
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?

Re: Sending matrix array to GLSL vertex shader
« Reply #4 on: May 05, 2013, 13:49:16 »
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.