static gboolean
_set_uniform (GQuark field_id, const GValue * value, gpointer user_data)
{
  GstGLShader *shader = user_data;
  const gchar *field_name = g_quark_to_string (field_id);

  if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_INT)) {
    gst_gl_shader_set_uniform_1i (shader, field_name, g_value_get_int (value));
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FLOAT)) {
    gst_gl_shader_set_uniform_1f (shader, field_name,
        g_value_get_float (value));
#ifdef HAVE_GRAPHENE
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC2)) {
    graphene_vec2_t *vec2 = g_value_get_boxed (value);
    float x = graphene_vec2_get_x (vec2);
    float y = graphene_vec2_get_y (vec2);
    gst_gl_shader_set_uniform_2f (shader, field_name, x, y);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC3)) {
    graphene_vec3_t *vec3 = g_value_get_boxed (value);
    float x = graphene_vec3_get_x (vec3);
    float y = graphene_vec3_get_y (vec3);
    float z = graphene_vec3_get_z (vec3);
    gst_gl_shader_set_uniform_3f (shader, field_name, x, y, z);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC4)) {
    graphene_vec4_t *vec4 = g_value_get_boxed (value);
    float x = graphene_vec4_get_x (vec4);
    float y = graphene_vec4_get_y (vec4);
    float z = graphene_vec4_get_z (vec4);
    float w = graphene_vec4_get_w (vec4);
    gst_gl_shader_set_uniform_4f (shader, field_name, x, y, z, w);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_MATRIX)) {
    graphene_matrix_t *matrix = g_value_get_boxed (value);
    float matrix_f[16];
    graphene_matrix_to_float (matrix, matrix_f);
    gst_gl_shader_set_uniform_matrix_4fv (shader, field_name, 1, FALSE,
        matrix_f);
#endif
  } else {
    /* FIXME: Add support for unsigned ints, non 4x4 matrices, etc */
    GST_FIXME ("Don't know how to set the \'%s\' paramater.  Unknown type",
        field_name);
    return TRUE;
  }

  return TRUE;
}
int
gst_gl_shadervariable_set (GstGLShader * shader,
    struct gst_gl_shadervariable_desc *ret)
{

  switch (ret->type) {
    case _bool:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_1i (shader, ret->name,
            ((int *) ret->value)[0]);
      }
      break;
    case _int:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_1i (shader, ret->name,
            ((int *) ret->value)[0]);
      }
      break;

    case _uint:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_1i (shader, ret->name,
            ((unsigned int *) ret->value)[0]);
      }
      break;

    case _float:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_1fv (shader, ret->name, ret->count,
            (float *) ret->value);
      } else {
        gst_gl_shader_set_uniform_1f (shader, ret->name,
            ((float *) ret->value)[0]);
      }
      break;

    case _vec2:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_2fv (shader, ret->name, ret->count,
            (float *) ret->value);
      } else {
        gst_gl_shader_set_uniform_2f (shader, ret->name,
            ((float *) ret->value)[0], ((float *) ret->value)[1]);
      }
      break;

    case _bvec2:
    case _ivec2:
    case _uvec2:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_2iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_2i (shader, ret->name,
            ((int *) ret->value)[0], ((int *) ret->value)[1]);
      }
      break;

    case _vec3:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_3fv (shader, ret->name, ret->count,
            (float *) ret->value);
      } else {
        gst_gl_shader_set_uniform_3f (shader, ret->name,
            ((float *) ret->value)[0], ((float *) ret->value)[1],
            ((float *) ret->value)[2]);
      }
      break;

    case _bvec3:
    case _ivec3:
    case _uvec3:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_3iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_3i (shader, ret->name,
            ((int *) ret->value)[0], ((int *) ret->value)[1],
            ((int *) ret->value)[2]);
      }
      break;

    case _vec4:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_4fv (shader, ret->name, ret->count,
            (float *) ret->value);
      } else {
        gst_gl_shader_set_uniform_4f (shader, ret->name,
            ((float *) ret->value)[0], ((float *) ret->value)[1],
            ((float *) ret->value)[2], ((float *) ret->value)[3]);
      }
      break;

    case _bvec4:
    case _ivec4:
    case _uvec4:
      if (ret->arraysize) {
        gst_gl_shader_set_uniform_4iv (shader, ret->name, ret->count,
            (int *) ret->value);
      } else {
        gst_gl_shader_set_uniform_4i (shader, ret->name,
            ((int *) ret->value)[0], ((int *) ret->value)[1],
            ((int *) ret->value)[2], ((int *) ret->value)[3]);
      }
      break;

    case _mat2:
    case _mat2x2:
      gst_gl_shader_set_uniform_matrix_2fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat3:
    case _mat3x3:
      gst_gl_shader_set_uniform_matrix_3fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat4:
    case _mat4x4:
      gst_gl_shader_set_uniform_matrix_4fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

#if GST_GL_HAVE_OPENGL
    case _mat2x3:
      gst_gl_shader_set_uniform_matrix_2x3fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat3x2:
      gst_gl_shader_set_uniform_matrix_3x2fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat2x4:
      gst_gl_shader_set_uniform_matrix_2x4fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat4x2:
      gst_gl_shader_set_uniform_matrix_4x2fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat3x4:
      gst_gl_shader_set_uniform_matrix_3x4fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;

    case _mat4x3:
      gst_gl_shader_set_uniform_matrix_4x3fv (shader, ret->name, ret->count, 0,
          (float *) ret->value);
      break;
#endif

    default:
      return -1;
  }
  return 0;
}