1
$\begingroup$

I'm currently passing an array of bone positions to GLSL for a skeletal animation shader; the positions are passing successfully but producing a GL_INVALID_OPERATION error.

I'm passing the matrices in the following line:

std::vector<glm::mat4x4> bpos;
...
glUniformMatrix4fv(shader.uniform("bpos"), 50, GL_FALSE, &bpos.at(0)[0][0]);

Where the shader.uniform("bpos") position has been assigned earlier as:

this->m_uniforms["bpos"] = glGetUniformLocation(this->m_program, "uniform_bpos");

I'm getting the following output:

GL CALLBACK: ** GL ERROR ** type = 0x824c, severity = 0x9146, message = GL_INVALID_OPERATION in glUniform3(uniform "uniform_bpos"@1 is matrix)

Has anyone here encountered this error or does anyone here see what I'm doing incorrectly?

EDIT:

The vertex shader:

#version 330 core

layout(location = 0) in vec3 vert_ms;
layout(location = 1) in vec3 norm_ms;
layout(location = 2) in ivec4 bone_ids;
layout(location = 3) in vec4 bone_weights;


out vec3 norm_ws;
out vec3 pos_ws;

uniform mat4 uniform_mvp;
uniform mat4 uniform_bpos[50];

void main(){
     mat4 bone = uniform_bpos[bone_ids[0]] * bone_weights[0];
     bone += uniform_bpos[bone_ids[1]] * bone_weights[1];
     bone += uniform_bpos[bone_ids[2]] * bone_weights[2];
     bone += uniform_bpos[bone_ids[3]] * bone_weights[3];

     gl_Position = uniform_mvp * bone * vec4(vert_ms, 1);
     norm_ws = (uniform_mvp * bone * vec4 (norm_ms, 0)).xyz;
     pos_ws = vec3(gl_Position);
}

the function getting the uniform locations:

Shader::Shader(GLuint shader_program)
{
  this->m_program = shader_program;

  this->m_uniforms["mvp"] = glGetUniformLocation(this->m_program, "uniform_mvp");
  this->m_uniforms["bpos"] = glGetUniformLocation(this->m_program, "uniform_bpos");
  this->m_uniforms["eye"] = glGetUniformLocation(this->m_program, "uniform_eye");
}

from this file: https://github.com/EricJIsaac/opengl-engine/blob/feature/pb-materials/src/graphics/shader.cpp

uploading the vertex data:

void SkeletonMeshBuffer::predraw()
{
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
  glEnableVertexAttribArray(2);
  glEnableVertexAttribArray(3);
  glBindBuffer(GL_ARRAY_BUFFER, this->m_vbo);

  // Vertices
  std::size_t stride = sizeof(graphics::data::SkeletonMesh_Vertex);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);

  // Normals
  char* offset = (char*)0 + 3 * sizeof(float);
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, (void*)offset);

  // Bone Ids
  offset = (char*)0 + 6 * sizeof(float);
  glVertexAttribIPointer(2, 4, GL_UNSIGNED_SHORT, stride, (void*)offset);

  // Bone Weights
  offset = (char*)0 + 6 * sizeof(float) + 4 * sizeof(unsigned short);
  glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, stride, (void*)offset);

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_ele);
}

void SkeletonMeshBuffer::draw(std::size_t id)
{
  if(id < 0 || id > this->m_entries.size())
  {
    printf("Invalid skeleton mesh id %lu requested\n", id);
    return;
  }

  char* offset = (char*)0 +
    this->m_entries[id].index_offset * sizeof(unsigned short);

  glDrawElementsBaseVertex(
    GL_TRIANGLES,
    this->m_entries[id].index_count,
    GL_UNSIGNED_SHORT,
    (void*)offset,
    this->m_entries[id].vertex_offset / 3);
}

void SkeletonMeshBuffer::postdraw()
{
    glDisableVertexAttribArray(0);
}

from this file: https://github.com/EricJIsaac/opengl-engine/blob/feature/pb-materials/src/graphics/skeleton_mesh_buffer.cpp

The meshes being loaded: https://github.com/EricJIsaac/opengl-engine/tree/master/data/geometry/skeletonMeshes

$\endgroup$
6
  • $\begingroup$ "the positions are passing successfully but producing a GL_INVALID_OPERATION error." How can something be "successful" while erroring? Also, how are "uniform buffer objects" involved; you don't use glUniform* calls to upload to UBOs. $\endgroup$ May 4, 2020 at 3:01
  • $\begingroup$ To clarify, the animated meshes appear to be animating correctly but an error is being reported. My guess at the moment is that the matrices are accessible in the shader as expected but an error is being reported. My best guess is that I am either observing a bug or undefined behavior that happened to work. So succeeding in the sense that the information seems to be making it to the hardware, but an error is still reported by the instruction that puts them there. $\endgroup$
    – user13304
    May 4, 2020 at 4:45
  • $\begingroup$ My mistake on the uniform-buffer-object tag, I just removed it. $\endgroup$
    – user13304
    May 4, 2020 at 4:56
  • $\begingroup$ Well, if the uniforms are uploaded correctly, are you sure the error is thrown by that exact function call and not some earlier or later code? It's also a bit confusing why the error message talks about glUniform3. $\endgroup$ May 4, 2020 at 12:06
  • $\begingroup$ Please provide more code (shaders, uploading of the data, getting the uniform locations). As @ChristianRau mentioned, this part of the error message glUniform3 looks suspicious. Throw an exception from your callback function if an error occurs. This way you can use your debugger to activate a breakpoint and traverse the call stack to find out which API call actually causes the error. It might be another function and not the one you expected. $\endgroup$
    – wychmaster
    May 4, 2020 at 12:43

1 Answer 1

1
$\begingroup$

The eye position (a vec3) was being bound to the wrong shader, resulting in the glUniform3 error when OpenGL (mesa) checked the validity of the uniforms. The error was due to a typo; I named my simple-mesh and animated-mesh shaders similar things.

glUseProgram(smesh_shader.get());
      smb.predraw();
      glUniform3fv(mesh_shader.uniform("eye"), 1, &eye[0]); // <- Oops
      graphics::ogl::render(scene.getRoot(), smb, mv, smesh_shader);
      smb.postdraw();

Following @Christian Rau's and @wychmaster's suggestions, I was able to debug the issue. I also needed to build a debug version of the mesa library to make sense of the stack-trace in gdb.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.